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

แสดงเอกสารพร้อมความคิดเห็นด้วย 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 ไลบรารีจะทำสี่ขั้นตอนสำคัญ:
- Document Analysis – วิเคราะห์ไฟล์อินพุตและสร้างการแสดงผลภายใน
- Comment Extraction – ค้นหาคอมเมนต์, หมายเหตุเชิงล่าง, และคำอธิบายทั้งหมด
- HTML Generation – สร้าง HTML ที่สะอาดและเป็นมาตรฐานซึ่งสะท้อนเลย์เอาต์ต้นฉบับ
- 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
PathAPI ที่เชื่อถือได้กว่า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 Conversion –
ImageIOหรือไลบรารีคล้าย ๆ จะเบากว่า - 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 พร้อมคอมเมนต์แล้ว ต่อไปนี้คือแนวทางเพื่อเพิ่มพูนความเชี่ยวชาญของคุณ:
- Watermarking – เพิ่มลายน้ำแบบกำหนดเองลงในหน้าที่เรนเดอร์เพื่อการสร้างแบรนด์หรือความลับ
- Metadata Extraction – ดึงข้อมูลผู้เขียน, วันที่สร้าง, และจำนวนหน้า ผ่าน
viewer.getDocumentInfo() - Custom Viewers – สร้างตัวดูเฉพาะสำหรับ PDF, สเปรดชีต, หรือพรีเซนเทชันที่ซ่อนหรือไฮไลท์คอมเมนต์ต่างกัน
- Cloud Storage Integration – เรนเดอร์ไฟล์โดยตรงจาก AWS S3, Azure Blob, หรือ Google Drive โดยไม่ต้องดาวน์โหลดลงเครื่อง
เส้นทางการเรียนแนะนำ
- Experiment with Different File Types – ลองไฟล์ Excel, PowerPoint, และ PDF เพื่อดูว่าคอมเมนต์ถูกจัดการอย่างไรในแต่ละรูปแบบ
- Build a Simple Web Viewer – สร้างหน้า HTML ขั้นต่ำที่โหลด HTML ที่สร้างขึ้นผ่าน
<iframe>หรือ AJAX - Explore the GroupDocs Ecosystem – ศึกษา GroupDocs Annotation, Comparison, และ Signature สำหรับเวิร์กโฟลว์เอกสารครบวงจร
- 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());
}