คู่มือ GroupDocs Viewer สำหรับ Java: แปลง Word เป็น HTML และแสดงเอกสารพร้อมความคิดเห็น

บทนำ

หากคุณต้องการ แปลง Word เป็น HTML พร้อมเก็บบันทึกของผู้ตรวจสอบ ทุกความคิดเห็น หรือคำอธิบายไว้ คุณมาถูกที่แล้ว นักพัฒนา Java จำนวนมากเจออุปสรรคเมื่อการแปลงเอกสารลบข้อมูลข้อเสนอแนะที่ฝังอยู่ในไฟล์ต้นฉบับ บทเรียนนี้จะสอนคุณใช้ GroupDocs Viewer สำหรับ Java เพื่อ แปลง Word เป็น HTML และแสดงประเภทเอกสารหลากหลาย—Word, Excel, PowerPoint, PDF และอื่น ๆ—โดยไม่สูญเสียข้อมูลความคิดเห็นใด ๆ

คุณจะได้พบว่าทำไม GroupDocs Viewer จึงเป็นตัวเลือกพร้อมใช้งานในการผลิต วิธีตั้งค่าสภาพแวดล้อม โค้ดที่จำเป็นต้องใช้ และเคล็ดลับที่พิสูจน์แล้วว่าจะทำให้ประสิทธิภาพรวดเร็วแม้กับไฟล์ขนาดใหญ่

แสดงเอกสารพร้อมความคิดเห็นด้วย GroupDocs.Viewer สำหรับ Java

แสดงเอกสารพร้อมความคิดเห็นด้วย GroupDocs.Viewer สำหรับ Java

สิ่งที่คุณจะเรียนรู้ในบทเรียนนี้:

  • การตั้งค่าและกำหนดค่าของ GroupDocs Viewer อย่างครบถ้วน
  • ขั้นตอน‑ต่อ​ขั้นตอน แปลง Word เป็น HTML พร้อมคอมเมนต์ที่คงไว้
  • วิธีแก้ปัญหาทั่วไปและข้อควรระวังที่ควรหลีกเลี่ยง
  • รูปแบบการใช้งานจริงและแนวปฏิบัติที่ดีที่สุด
  • เทคนิคการเพิ่มประสิทธิภาพสำหรับการใช้งานในสภาพแวดล้อมการผลิต

คำตอบสั้น

  • Can GroupDocs Viewer convert Word to HTML? ใช่—เปิดใช้งานการเรนเดอร์ HTML และการสนับสนุนคอมเมนต์ด้วยบรรทัดโค้ดเดียว
  • Do comments stay in the HTML output? แน่นอน—setRenderComments(true) จะคงคอมเมนต์และคำอธิบายทั้งหมดไว้
  • What Java version is required? JDK 8 หรือสูงกว่า
  • Is a license needed for production? ใบอนุญาตเต็มจะลบลายน้ำและเปิดใช้งานคุณสมบัติทั้งหมด
  • How to improve rendering speed? เรนเดอร์เฉพาะหน้าที่ต้องการ ใช้ทรัพยากรภายนอก และเพิ่มขนาด heap ของ JVM

“แปลง word เป็น html” พร้อมคอมเมนต์คืออะไร?

“Convert Word to HTML” หมายถึงการแปลงไฟล์ Microsoft Word .docx ให้เป็นเอกสาร HTML ที่พร้อมใช้งานบนเว็บโดยคงรูปแบบต้นฉบับ การจัดสไตล์ และคอมเมนต์ที่ฝังอยู่ กระบวนการนี้ทำให้เบราว์เซอร์แสดงเอกสารได้ตามที่ผู้เขียนตั้งใจ พร้อมกับข้อเสนอแนะจากผู้ตรวจสอบ

ทำไมต้องเลือก GroupDocs Viewer สำหรับ Java?

ก่อนที่เราจะลงลึกในโค้ด มาดูเหตุผลที่ GroupDocs Viewer เป็นไลบรารีที่ต้องใช้สำหรับการเรนเดอร์เอกสารบน Java:

  • 170+ supported formats – ไลบรารีรองรับทุกอย่างตั้งแต่ DOCX ถึงไฟล์ CAD ให้คุณมี dependency เพียงหนึ่งเดียวสำหรับการแปลงทั้งหมด
  • No third‑party Office installation – ทำงานบนทุก OS โดยไม่ต้องติดตั้ง Microsoft Office, LibreOffice หรือ runtime หนักอื่น ๆ
  • Preserves formatting and annotations – คอมเมนต์, หมายเหตุเชิงล่าง, และการติดตามการเปลี่ยนแปลงจะคงอยู่หลังการแปลง
  • Fast, lightweight engine – เอกสารทั่วไป 100 หน้าเรนเดอร์ภายในต่ำกว่า 2 วินาทีบนเซิร์ฟเวอร์ 4‑core มาตรฐาน
  • Robust documentation and active community – มีตัวอย่าง, ฟอรั่ม, และการสนับสนุนที่รวดเร็วเมื่อคุณเจอปัญหา

เมื่อควรใช้วิธีนี้

  • สร้างตัวดูเอกสารบนเว็บที่ต้องแสดงบันทึกของผู้ตรวจสอบ
  • พัฒนาแพลตฟอร์มการตรวจสอบร่วมที่ต้องการให้ข้อเสนอแนะมองเห็นได้
  • แปลงสัญญาเก่าสำหรับการแสดงออนไลน์ในพอร์ทัลกฎหมาย
  • พัฒนาโซลูชัน e‑learning ที่ฝังคอมเมนต์ของผู้สอนในเนื้อหาเรียน

ข้อกำหนดเบื้องต้นและการตั้งค่าสภาพแวดล้อม

สิ่งที่คุณต้องการ

  • Java Development Kit (JDK) 8+ – runtime ที่ใช้ในแอปพลิเคชันของคุณ
  • Maven 3.6+ – สำหรับจัดการ dependencies และสร้างโปรเจค
  • IDE ที่คุณเลือก – IntelliJ IDEA, Eclipse หรือ VS Code
  • เอกสารตัวอย่างที่มีคอมเมนต์ – ไฟล์ DOCX, XLSX, PPTX ที่มีบันทึกของผู้ตรวจสอบ

การตั้งค่าสภาพแวดล้อมการพัฒนา

ขั้นตอนที่ 1: ตรวจสอบการติดตั้ง Java

เปิดเทอร์มินัลและรัน:

java -version

คุณควรเห็นสตริงเวอร์ชันที่ขึ้นต้นด้วย 1.8 หรือสูงกว่า หากไม่เห็น ให้ดาวน์โหลด JDK ล่าสุดจากเว็บไซต์ของ Oracle หรือ OpenJDK อย่างเป็นทางการ

ขั้นตอนที่ 2: ตรวจสอบการติดตั้ง Maven

รัน:

mvn -v

Maven ควรแสดงเวอร์ชันและเวอร์ชัน Java ที่ใช้ หากคำสั่งไม่ถูกจำกัด ให้ติดตั้ง Maven จากเว็บไซต์ Apache

ขั้นตอนที่ 3: สร้างโปรเจค Maven ใหม่

สร้างโครงสร้างโปรเจคพื้นฐานด้วย:

mvn archetype:generate -DgroupId=com.example.viewer -DartifactId=viewer-demo -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

เข้าไปในโฟลเดอร์ viewer-demo ที่สร้างขึ้นใหม่ แล้วคุณก็พร้อมเพิ่ม GroupDocs Viewer

การตั้งค่า GroupDocs.Viewer สำหรับ Java

การเพิ่ม Dependency

ขั้นตอนแรกของทุกบทเรียน GroupDocs Viewer Java คือการนำไลบรารีเข้ามาในโปรเจค เพิ่มการกำหนดต่อไปนี้ในไฟล์ pom.xml ของคุณ:

<dependency>
    <groupId>com.groupdocs</groupId>
    <artifactId>groupdocs-viewer</artifactId>
    <version>25.2</version>
</dependency>

Pro Tip: ตรวจสอบเสมอที่ GroupDocs releases page เพื่อดูเวอร์ชันล่าสุด ไลบรารีได้รับการอัปเดตอย่างต่อเนื่องพร้อมการแก้บั๊ก

ทำความเข้าใจตัวเลือกการให้ลิขสิทธิ์

GroupDocs มีลิขสิทธิ์ที่ยืดหยุ่นตามความต้องการของโครงการ:

  • Free Trial (Perfect for Learning): การประเมิน 30 วันพร้อมเข้าถึงฟีเจอร์ทั้งหมดและลายน้ำสำหรับการประเมิน
  • Temporary License (For Development): การประเมินต่อเนื่องโดยไม่มีลายน้ำ; เหมาะสำหรับโครงการ proof‑of‑concept ขอที่ GroupDocs Temporary License Page
  • Full License (Production Ready): ไม่มีข้อจำกัดหรือลายน้ำ, ใช้เชิงพาณิชย์ได้เต็มที่ สามารถซื้อได้ที่ GroupDocs Purchase Page

รูปแบบการเริ่มต้นพื้นฐาน

นี่คือรูปแบบพื้นฐานที่คุณจะใช้ตลอดบทเรียน:

try (Viewer viewer = new Viewer("input.docx")) {
    // Rendering options will be set later
}

Why This Pattern Works:

  • Automatic resource management ป้องกันการรั่วไหลของหน่วยความจำ
  • Exception handling จับข้อผิดพลาดทั่วไปในการเข้าถึงไฟล์
  • Clean, readable code ที่ง่ายต่อการบำรุงรักษาในโครงการขนาดใหญ่

การดำเนินการหลัก: การแสดงเอกสารพร้อมคอมเมนต์

ทำความเข้าใจกระบวนการ

เมื่อคุณเรนเดอร์เอกสารด้วย GroupDocs Viewer ไลบรารีจะทำสี่ขั้นตอนสำคัญ:

  1. Document Analysis – วิเคราะห์ไฟล์อินพุตและสร้างการแสดงผลภายใน
  2. Comment Extraction – ค้นหาคอมเมนต์, หมายเหตุเชิงล่าง, และคำอธิบายทั้งหมด
  3. HTML Generation – สร้าง HTML ที่สะอาดและเป็นมาตรฐานซึ่งสะท้อนเลย์เอาต์ต้นฉบับ
  4. Resource Handling – รวมรูปภาพ, CSS, และฟอนต์ไว้ในไฟล์เดียวหรือแยกเป็นไฟล์ภายนอก

การดำเนินการแบบขั้นตอน

ขั้นตอนที่ 1: ตั้งค่าเส้นทางไฟล์ของคุณ

จัดระเบียบตำแหน่งอินพุตและเอาต์พุตตั้งแต่แรกเพื่อหลีกเลี่ยงข้อผิดพลาดเกี่ยวกับพาธ:

Path inputPath = Paths.get("documents/sample-with-comments.docx");
Path outputDir = Paths.get("output/html");
Files.createDirectories(outputDir);

Why This Approach:

  • ใช้ Java NIO.2 Path API ที่เชื่อถือได้กว่า java.io.File
  • ชื่อแปรที่อธิบายทำให้ดีบักง่ายขึ้น
  • ตัวแปร {0} ในรูปแบบเอาต์พุตจะถูกแทนที่ด้วยหมายเลขหน้าโดยอัตโนมัติ

ขั้นตอนที่ 2: กำหนดค่า HTML Rendering Options

นี่คือจุดที่เกิด “เวทมนตร์” เราบอก GroupDocs ว่าเราต้องการให้เอกสารแสดงผลอย่างไร:

HtmlViewOptions กำหนดวิธีการเรนเดอร์เอกสารเป็น HTML รวมถึงการจัดการทรัพยากรและการเรนเดอร์คอมเมนต์

HtmlViewOptions viewOptions = HtmlViewOptions.forEmbeddedResources(outputDir);
viewOptions.setRenderComments(true);   // Preserve every comment
viewOptions.setPageNumberPrefix("page_");

Key Configuration Details:

  • forEmbeddedResources() ฝัง CSS, รูปภาพ, และฟอนต์ลงใน HTML ทำให้ไฟล์เอาต์พุตพกพาได้ง่าย
  • setRenderComments(true) เป็นบรรทัดเดียวที่ทำให้ แปลง word เป็น html คงบันทึกของผู้ตรวจสอบทั้งหมดไว้
  • forExternalResources() เป็นทางเลือกที่ให้คุณเก็บทรัพยากรแยกต่างหาก หากต้องการไฟล์ HTML ที่บางลง

ขั้นตอนที่ 3: ดำเนินการเรนเดอร์

ตอนนี้เรานำทุกอย่างมารวมกัน:

Viewer เป็นคลาสหลักที่ใช้โหลดเอกสารและทำการเรนเดอร์

try (Viewer viewer = new Viewer(inputPath.toFile())) {
    viewer.view(viewOptions);
}

เมธอด view จะอ่านไฟล์ Word, ดึงคอมเมนต์, สร้างหน้า HTML, และเขียนผลลัพธ์ไปที่ output/html แต่ละหน้าจะบันทึกเป็น page_1.html, page_2.html เป็นต้น

ตัวอย่างการทำงานเต็มรูปแบบ

การรวมส่วนต่าง ๆ เข้าด้วยกันให้คลาสเดียวที่สามารถรันได้ ซึ่งจะแปลงไฟล์ Word เป็น HTML พร้อมคอมเมนต์ (ซอร์สโค้ดเต็มอยู่ใน GitHub อย่างเป็นทางการ)

การกำหนดค่าขั้นสูงและตัวเลือก

การตั้งค่าไดเรกทอรีเอาต์พุตแบบไดนามิก

สำหรับแอปพลิเคชันขนาดใหญ่ คุณอาจต้องการสร้างไดเรกทอรีเอาต์พุตตาม ID ผู้ใช้หรือ timestamp:

String userId = "12345";
Path dynamicOutput = Paths.get("output", userId, LocalDate.now().toString());
Files.createDirectories(dynamicOutput);
HtmlViewOptions dynamicOptions = HtmlViewOptions.forEmbeddedResources(dynamicOutput);

ปัญหาทั่วไปและการแก้ไขปัญหา

ปัญหา 1: ข้อผิดพลาด “File Not Found”

ตรวจสอบให้แน่ใจว่าเส้นทางอินพุตเป็นแบบ absolute หรือ relative ต่อ working directory และตรวจสอบสิทธิ์ไฟล์ การใช้ Path ช่วยหลีกเลี่ยงข้อผิดพลาดจากการต่อสตริง

ปัญหา 2: คอมเมนต์ไม่ปรากฏในผลลัพธ์

ตรวจสอบว่าได้เรียก setRenderComments(true) ก่อน viewer.view() อีกทั้งตรวจสอบว่าไฟล์ต้นฉบับมีคอมเมนต์จริง ๆ โดยใช้ viewer.getDocumentInfo().getComments()

ปัญหา 3: ข้อผิดพลาด Out of Memory กับเอกสารขนาดใหญ่

GroupDocs Viewer สตรีมข้อมูล แต่ไฟล์ที่ใหญ่มาก (> 500 หน้า) อาจทำให้ heap ของ JVM แรงเกิน ควรเพิ่มขนาด heap ด้วย -Xmx4g หรือเรนเดอร์เฉพาะหน้าที่ต้องการ

ปัญหา 4: ประสิทธิภาพการเรนเดอร์ช้า

เรนเดอร์ช่วงหน้าที่ต้องการโดยใช้ viewer.view(pageRange, viewOptions) การใช้ทรัพยากรภายนอก (forExternalResources()) ยังช่วยลดขนาด HTML ทำให้เบราว์เซอร์โหลดเร็วขึ้น

รูปแบบการใช้งานจริง

แพทเทิร์น 1: การผสานรวมกับเว็บแอปพลิเคชัน

ผสานตรรกะการเรนเดอร์เข้าไปในคอนโทรลเลอร์ Spring Boot เพื่อให้บริการ HTML ตามคำขอ:

@RestController
@RequestMapping("/api/view")
public class DocumentController {

    @GetMapping("/{id}")
    public ResponseEntity<Resource> renderDocument(@PathVariable String id) throws IOException {
        Path docPath = Paths.get("documents", id + ".docx");
        Path outDir = Files.createTempDirectory("viewer");
        HtmlViewOptions options = HtmlViewOptions.forEmbeddedResources(outDir);
        options.setRenderComments(true);
        try (Viewer viewer = new Viewer(docPath.toFile())) {
            viewer.view(options);
        }
        // Return the first HTML page as a Resource
        Path firstPage = outDir.resolve("page_1.html");
        Resource resource = new UrlResource(firstPage.toUri());
        return ResponseEntity.ok()
                .contentType(MediaType.TEXT_HTML)
                .body(resource);
    }
}

แพทเทิร์น 2: การประมวลผลหลายเอกสารเป็นชุด

เมื่อคุณต้องแปลงโฟลเดอร์เต็มของไฟล์ Word ให้วนลูปผ่านไดเรกทอรีและใช้ HtmlViewOptions ตัวเดียวกันเพื่อหลีกเลี่ยงการสร้างอ็อบเจ็กต์ซ้ำ ๆ

การเพิ่มประสิทธิภาพและแนวปฏิบัติที่ดีที่สุด

เคล็ดลับการจัดการหน่วยความจำ

  • Always use try‑with‑resources สำหรับอ็อบเจ็กต์ Viewer
  • Process large documents in batches แทนการโหลดทั้งหมดเข้าหน่วยความจำพร้อมกัน
  • Monitor JVM heap usage ด้วยเครื่องมือเช่น VisualVM และปรับ -Xmx ตามต้องการ
  • Implement proper caching สำหรับเอกสารที่เข้าถึงบ่อย เพื่อลดการเรนเดอร์ซ้ำ

แนวทางการใช้ทรัพยากร

สำหรับแอปพลิเคชันขนาดเล็ก (< 100 เอกสาร/วัน):

HtmlViewOptions options = HtmlViewOptions.forEmbeddedResources(Paths.get("output"));
options.setRenderComments(true);

สำหรับแอปพลิเคชันปริมาณสูง (1000+ เอกสาร/วัน):

HtmlViewOptions options = HtmlViewOptions.forExternalResources(Paths.get("output"));
options.setRenderComments(true);
options.setCacheEnabled(true);

กลยุทธ์การแคช

เก็บ HTML ที่เรนเดอร์ไว้ในแคชแบบกระจาย (เช่น Redis) โดยใช้ hash ของเอกสารเป็นคีย์ เมื่อมีคำขอเข้ามาให้ตรวจสอบแคชก่อน หากพบให้ส่ง HTML ที่แคชไว้ทันทีโดยไม่ต้องผ่านเครื่องยนต์เรนเดอร์

เมื่อควรใช้ GroupDocs Viewer เทียบกับทางเลือกอื่น

GroupDocs Viewer เหมาะสำหรับ

  • Document Management Systems – ต้องการแสดงไฟล์หลายประเภทพร้อมคอมเมนต์
  • Collaborative Review Platforms – คอมเมนต์ต้องมองเห็นได้โดยผู้เข้าร่วมทุกคน
  • Educational Tools – คอมเมนต์ของผู้สอนปรากฏพร้อมสไลด์การบรรยาย
  • Legal Applications – สัญญาที่มีคอมเมนต์ของทนายต้องการการเรนเดอร์ที่แม่นยำ

พิจารณาทางเลือกอื่นเมื่อ

  • Simple PDF Display – ตัวแสดง PDF ของเบราว์เซอร์อาจเพียงพอ
  • Basic Image ConversionImageIO หรือไลบรารีคล้าย ๆ จะเบากว่า
  • Pure Text Extraction – Apache POI หรือ iText อาจเหมาะกว่า

คำถามที่พบบ่อย

Q: Can I render documents without comments?
A: ใช่—เพียงแค่ไม่เรียก setRenderComments(true) หรือกำหนดเป็น false

Q: What file formats support comment rendering?
A: ส่วนใหญ่รูปแบบหลัก ๆ รวมถึง DOC/DOCX, XLS/XLSX, PPT/PPTX, PDF และอื่น ๆ ดูที่ เอกสารอย่างเป็นทางการ สำหรับรายการเต็ม

Q: Can I customize the HTML output styling?
A: แน่นอน ใช้ HtmlViewOptions.setEmbedResources(false) เพื่อสร้างไฟล์ CSS แยกจากนั้นเพิ่มสไตล์ชีตของคุณหลังการเรนเดอร์

Q: How do I handle password‑protected documents?
A: ให้สร้างอินสแตนซ์ LoadOptions พร้อมรหัสผ่าน:

LoadOptions ช่วยกำหนดพารามิเตอร์การโหลดเอกสาร เช่น รหัสผ่าน

LoadOptions loadOptions = new LoadOptions("myPassword");
try (Viewer viewer = new Viewer(inputPath.toFile(), loadOptions)) {
    viewer.view(viewOptions);
}

Q: Is it possible to render only specific pages?
A: ใช่—ใช้เมธอด view ที่รับคอลเลกชัน PageNumber:

PageNumber แทนหมายเลขหน้าที่ต้องการเรนเดอร์เป็นส่วนย่อย

viewer.view(new int[]{1, 3, 5}, viewOptions);

Q: Why is rendering slow for large documents?
A: ไฟล์ขนาดใหญ่ต้องใช้เวลาประมวลผลมากขึ้น ปรับความเร็วโดยเรนเดอร์เฉพาะหน้าที่ต้องการ ใช้ทรัพยากรภายนอก เพิ่ม heap ของ JVM และเปิดใช้งานการประมวลผลแบบอะซิงโครนัส

Q: How can I monitor rendering progress?
A: แม้ GroupDocs Viewer จะไม่มีคอลแบ็กในตัว คุณสามารถวัดเวลาโดยใช้ System.nanoTime() ก่อนและหลัง viewer.view() เพื่อบันทึกระยะเวลา

Q: What happens if the source document is corrupted?
A: ไลบรารีจะโยน ViewerException ให้ห่อเมธอดด้วย try‑catch และบันทึกข้อผิดพลาดเพื่อให้ระบบทำงานต่อได้อย่างราบรื่น

Q: Can I use GroupDocs Viewer in a commercial application?
A: ใช่ แต่ต้องมีใบอนุญาตเชิงพาณิชย์ ลำใบนทดลองมีลายน้ำที่ต้องลบออกสำหรับการใช้งานในสภาพแวดล้อมการผลิต

Q: Are there any usage limits?
A: ไลบรารีเองไม่มีข้อจำกัด อย่างไรก็ตาม สัญญาใบอนุญาตของคุณอาจกำหนดขีดจำกัดการใช้งาน ตรวจสอบสัญญาของคุณสำหรับรายละเอียด

Q: Can I redistribute applications that include GroupDocs Viewer?
A: คุณสามารถแจกจ่ายแอปพลิเคชันของคุณเองได้ แต่ห้ามแจกจ่ายไบนารีของ GroupDocs เอง ตรวจสอบเงื่อนไขใบอนุญาตเพื่อความสอดคล้อง

ขั้นตอนต่อไปและหัวข้อขั้นสูง

คุณมีพื้นฐานที่มั่นคงสำหรับ แปลง word เป็น html พร้อมคอมเมนต์แล้ว ต่อไปนี้คือแนวทางเพื่อเพิ่มพูนความเชี่ยวชาญของคุณ:

  1. Watermarking – เพิ่มลายน้ำแบบกำหนดเองลงในหน้าที่เรนเดอร์เพื่อการสร้างแบรนด์หรือความลับ
  2. Metadata Extraction – ดึงข้อมูลผู้เขียน, วันที่สร้าง, และจำนวนหน้า ผ่าน viewer.getDocumentInfo()
  3. Custom Viewers – สร้างตัวดูเฉพาะสำหรับ PDF, สเปรดชีต, หรือพรีเซนเทชันที่ซ่อนหรือไฮไลท์คอมเมนต์ต่างกัน
  4. Cloud Storage Integration – เรนเดอร์ไฟล์โดยตรงจาก AWS S3, Azure Blob, หรือ Google Drive โดยไม่ต้องดาวน์โหลดลงเครื่อง

เส้นทางการเรียนแนะนำ

  1. Experiment with Different File Types – ลองไฟล์ Excel, PowerPoint, และ PDF เพื่อดูว่าคอมเมนต์ถูกจัดการอย่างไรในแต่ละรูปแบบ
  2. Build a Simple Web Viewer – สร้างหน้า HTML ขั้นต่ำที่โหลด HTML ที่สร้างขึ้นผ่าน <iframe> หรือ AJAX
  3. Explore the GroupDocs Ecosystem – ศึกษา GroupDocs Annotation, Comparison, และ Signature สำหรับเวิร์กโฟลว์เอกสารครบวงจร
  4. Join the Community – มีส่วนร่วมใน GroupDocs Forum เพื่อรับเคล็ดลับ, ตัวอย่างโครงการ, และการสนับสนุน

การขอความช่วยเหลือและสนับสนุน

Official Resources

Community Resources

  • Stack Overflow (tag: groupdocs-viewer)
  • ชุมชนโปรแกรมมิ่งบน Reddit
  • เซิร์ฟเวอร์ Discord ของนักพัฒนา Java

Last Updated: 2026-05-21
Tested With: GroupDocs.Viewer 25.2 for Java
Author: GroupDocs

java -version
javac -version
mvn -version
mvn archetype:generate -DgroupId=com.example.documentviewer -DartifactId=groupdocs-viewer-demo -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
<repositories>
   <repository>
      <id>repository.groupdocs.com</id>
      <name>GroupDocs Repository</name>
      <url>https://releases.groupdocs.com/viewer/java/</url>
   </repository>
</repositories>
<dependencies>
   <dependency>
      <groupId>com.groupdocs</groupId>
      <artifactId>groupdocs-viewer</artifactId>
      <version>25.2</version>
   </dependency>
</dependencies>
import com.groupdocs.viewer.Viewer;

// The try-with-resources pattern ensures proper cleanup
try (Viewer viewer = new Viewer("path/to/your/document.docx")) {
    // All rendering operations happen here
    // Resources are automatically closed when done
} catch (Exception e) {
    System.err.println("Error rendering document: " + e.getMessage());
    e.printStackTrace();
}
import java.nio.file.Path;
import java.nio.file.Paths;

// Create a descriptive output directory
Path outputDirectory = Paths.get("rendered-documents");
Path pageFilePathFormat = outputDirectory.resolve("page_{0}.html");
import com.groupdocs.viewer.options.HtmlViewOptions;

// Create HTML options with embedded resources
HtmlViewOptions viewOptions = HtmlViewOptions.forEmbeddedResources(pageFilePathFormat);

// The crucial setting – enable comment rendering!
viewOptions.setRenderComments(true);
import com.groupdocs.viewer.Viewer;

try (Viewer viewer = new Viewer("path/to/your/document.docx")) {
    // Create output directory if it doesn't exist
    if (!outputDirectory.toFile().exists()) {
        outputDirectory.toFile().mkdirs();
    }
    
    // Perform the actual rendering
    viewer.view(viewOptions);
    
    System.out.println("Document rendered successfully!");
    System.out.println("Output location: " + outputDirectory.toAbsolutePath());
    
} catch (Exception e) {
    System.err.println("Rendering failed: " + e.getMessage());
    e.printStackTrace();
}
package com.example.documentviewer;

import com.groupdocs.viewer.Viewer;
import com.groupdocs.viewer.options.HtmlViewOptions;
import java.nio.file.Path;
import java.nio.file.Paths;

public class DocumentRenderer {
    
    public static void main(String[] args) {
        renderDocumentWithComments("sample-document.docx", "output");
    }
    
    public static void renderDocumentWithComments(String inputFile, String outputDir) {
        // Set up paths
        Path outputDirectory = Paths.get(outputDir);
        Path pageFilePathFormat = outputDirectory.resolve("page_{0}.html");
        
        // Configure rendering options
        HtmlViewOptions viewOptions = HtmlViewOptions.forEmbeddedResources(pageFilePathFormat);
        viewOptions.setRenderComments(true);
        
        // Render the document
        try (Viewer viewer = new Viewer(inputFile)) {
            // Ensure output directory exists
            outputDirectory.toFile().mkdirs();
            
            // Execute rendering
            viewer.view(viewOptions);
            
            System.out.println("✓ Document rendered with comments preserved");
            System.out.println("📂 Output directory: " + outputDirectory.toAbsolutePath());
            
        } catch (Exception e) {
            System.err.println("❌ Rendering failed: " + e.getMessage());
            e.printStackTrace();
        }
    }
}
import java.nio.file.Path;
import java.nio.file.Paths;

public class PathManager {
    
    /**
     * Creates a structured output path based on document name and timestamp
     */
    public static Path getOutputDirectoryPath(String documentName) {
        String timestamp = String.valueOf(System.currentTimeMillis());
        String cleanDocName = documentName.replaceAll("[^a-zA-Z0-9]", "_");
        
        return Paths.get("rendered-docs")
                   .resolve(cleanDocName)
                   .resolve(timestamp);
    }
    
    /**
     * Simple output directory for basic use cases
     */
    public static Path getSimpleOutputPath(String folderName) {
        return Paths.get("output").resolve(folderName);
    }
}
// Always check if file exists before processing
Path inputPath = Paths.get("your-document.docx");
if (!inputPath.toFile().exists()) {
    throw new IllegalArgumentException("Input file not found: " + inputPath.toAbsolutePath());
}

// Check if file is readable
if (!inputPath.toFile().canRead()) {
    throw new IllegalArgumentException("Cannot read input file: " + inputPath.toAbsolutePath());
}
HtmlViewOptions viewOptions = HtmlViewOptions.forEmbeddedResources(pageFilePathFormat);
// This line is crucial – don't forget it!
viewOptions.setRenderComments(true);

// For debugging, you can verify the setting:
System.out.println("Comments enabled: " + viewOptions.isRenderComments());
// Increase JVM heap size when running
// java -Xmx2g -Xms1g YourApplication

// Or process documents page by page for very large files
HtmlViewOptions viewOptions = HtmlViewOptions.forEmbeddedResources(pageFilePathFormat);
viewOptions.setRenderComments(true);

// Render only specific pages if needed
viewer.view(viewOptions, 1, 2, 3); // Renders only pages 1, 2, and 3
// Use external resources for faster processing of multiple pages
HtmlViewOptions viewOptions = HtmlViewOptions.forExternalResources(
    pageFilePathFormat, 
    "resources/page_{0}/", 
    "resources/page_{0}/{0}"
);

// Enable caching if processing the same document multiple times
// (Note: Implement caching at application level)
@RestController
@RequestMapping("/api/documents")
public class DocumentController {
    
    @PostMapping("/render")
    public ResponseEntity<String> renderDocument(
            @RequestParam("file") MultipartFile file) {
        
        try {
            // Save uploaded file temporarily
            Path tempFile = Files.createTempFile("upload", ".tmp");
            file.transferTo(tempFile.toFile());
            
            // Render with comments
            String outputDir = renderDocumentWithComments(
                tempFile.toString(), 
                "web-output"
            );
            
            return ResponseEntity.ok("Document rendered: " + outputDir);
            
        } catch (Exception e) {
            return ResponseEntity.badRequest()
                .body("Rendering failed: " + e.getMessage());
        }
    }
}
public class BatchDocumentProcessor {
    
    public void processFolderWithComments(String inputFolder) {
        File folder = new File(inputFolder);
        File[] files = folder.listFiles((dir, name) -> 
            name.toLowerCase().endsWith(".docx") || 
            name.toLowerCase().endsWith(".xlsx") ||
            name.toLowerCase().endsWith(".pptx")
        );
        
        if (files == null) return;
        
        for (File file : files) {
            try {
                String outputDir = file.getName().replace(".", "_") + "_output";
                renderDocumentWithComments(file.getAbsolutePath(), outputDir);
                System.out.println("✓ Processed: " + file.getName());
                
            } catch (Exception e) {
                System.err.println("❌ Failed to process " + file.getName() + ": " + e.getMessage());
            }
        }
    }
}
// Simple approach works fine
try (Viewer viewer = new Viewer(documentPath)) {
    viewer.view(viewOptions);
}
public class DocumentRenderingService {
    private final ExecutorService executorService = 
        Executors.newFixedThreadPool(4); // Limit concurrent renderings
    
    public CompletableFuture<String> renderAsync(String documentPath) {
        return CompletableFuture.supplyAsync(() -> {
            try (Viewer viewer = new Viewer(documentPath)) {
                // Rendering logic here
                return "success";
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }, executorService);
    }
}
public class CachedDocumentRenderer {
    private final Map<String, String> renderCache = new ConcurrentHashMap<>();
    
    public String renderWithCaching(String documentPath) {
        String cacheKey = generateCacheKey(documentPath);
        
        return renderCache.computeIfAbsent(cacheKey, key -> {
            // Only render if not already cached
            return performActualRendering(documentPath);
        });
    }
    
    private String generateCacheKey(String documentPath) {
        // Include file modification time in cache key
        File file = new File(documentPath);
        return documentPath + "_" + file.lastModified();
    }
}
LoadOptions loadOptions = new LoadOptions();
loadOptions.setPassword("your-password");
try (Viewer viewer = new Viewer("protected-doc.docx", loadOptions)) {
    // Render as usual
}
viewer.view(viewOptions, 1, 3, 5); // Renders only pages 1, 3, and 5
System.out.println("Starting render for: " + documentName);
long startTime = System.currentTimeMillis();
viewer.view(viewOptions);
long endTime = System.currentTimeMillis();
System.out.println("Rendering completed in: " + (endTime - startTime) + "ms");
try (Viewer viewer = new Viewer(documentPath)) {
    viewer.view(viewOptions);
} catch (CorruptOrDamagedFileException e) {
    System.err.println("Document is corrupted: " + e.getMessage());
} catch (Exception e) {
    System.err.println("General error: " + e.getMessage());
}

บทเรียนที่เกี่ยวข้อง