دليل GroupDocs Viewer Java: تحويل Word إلى HTML وعرض المستندات مع التعليقات
مقدمة
إذا كنت بحاجة إلى تحويل Word إلى HTML مع الحفاظ على كل ملاحظة أو تعليق أو توضيح من المراجعين، فقد وجدت المكان المناسب. يواجه العديد من مطوري Java عقبة عندما تقوم عملية تحويل المستندات بإزالة التعليقات القيمة المدمجة في الملف الأصلي. يشرح هذا الدليل كيفية استخدام GroupDocs Viewer for Java لـ تحويل Word إلى HTML وعرض مجموعة واسعة من أنواع المستندات — Word و Excel و PowerPoint و PDF وغيرها — دون فقدان أي بيانات التعليقات.

عرض المستندات مع التعليقات باستخدام GroupDocs.Viewer for Java
ما ستتمكن من إتقانه في هذا الدليل:
- إعداد وتكوين كامل لـ GroupDocs Viewer
- خطوة بخطوة تحويل Word إلى HTML مع الحفاظ على التعليقات
- حلول شائعة للمشكلات والنصائح لتجنب الأخطاء
- أنماط تنفيذ واقعية وأفضل الممارسات
- تقنيات تحسين الأداء للاستخدام في بيئات الإنتاج
إجابات سريعة
- هل يمكن لـ GroupDocs Viewer تحويل Word إلى HTML؟ نعم — قم بتمكين عرض HTML ودعم التعليقات في سطر واحد من الشيفرة.
- هل تبقى التعليقات في مخرجات HTML؟ بالتأكيد —
setRenderComments(true)يحافظ على كل تعليق وتوضيح. - ما نسخة Java المطلوبة؟ JDK 8 أو أعلى.
- هل تحتاج إلى ترخيص للإنتاج؟ الترخيص الكامل يزيل العلامات المائية ويفتح جميع الميزات.
- كيف يمكن تحسين سرعة العرض؟ عرض صفحات محددة، استخدام موارد خارجية، وزيادة حجم heap في JVM.
ما هو “تحويل word إلى html” مع التعليقات؟
“تحويل Word إلى HTML” يعني تحويل ملف Microsoft Word .docx إلى مستند HTML جاهز للويب مع الحفاظ على التخطيط الأصلي، التنسيق، وأي تعليقات مدمجة. تتيح هذه العملية للمتصفحات عرض المستند تمامًا كما قصده المؤلفون، مع ملاحظات المراجعين.
لماذا تختار GroupDocs Viewer لـ Java؟
قبل أن نغوص في الشيفرة، دعنا نستكشف لماذا يعتبر GroupDocs Viewer المكتبة المفضلة لعرض المستندات في Java:
- أكثر من 170 صيغة مدعومة – المكتبة تتعامل مع كل شيء من DOCX إلى ملفات CAD، مما يمنحك تبعية واحدة لجميع احتياجات التحويل.
- لا حاجة لتثبيت Office من طرف ثالث – تعمل على أي نظام تشغيل دون الحاجة إلى Microsoft Office أو LibreOffice أو أي بيئات تشغيل ثقيلة أخرى.
- تحافظ على التنسيق والتعليقات – التعليقات، الحواشي، وتغييرات التتبع تبقى في التحويل دون تعديل.
- محرك سريع وخفيف – المستندات المعتادة ذات 100 صفحة تُعرض في أقل من ثانيتين على خادم قياسي بأربع نوى.
- توثيق قوي ومجتمع نشط – ستجد أمثلة، منتديات، ودعم سريع كلما واجهت مشكلة.
متى تستخدم هذا النهج
- بناء عارضات مستندات ويب تحتاج إلى إظهار ملاحظات المراجعين
- إنشاء منصات مراجعة تعاونية حيث يجب أن يبقى التعليق مرئيًا
- تحويل العقود القديمة للعرض عبر الإنترنت في البوابات القانونية
- تطوير حلول التعلم الإلكتروني التي تدمج تعليقات المدربين في المواد الدراسية
المتطلبات المسبقة وإعداد البيئة
ما ستحتاجه
- Java Development Kit (JDK) 8+ – بيئة التشغيل التي تشغل تطبيقك.
- Maven 3.6+ – لإدارة التبعيات وبناء المشروع.
- IDE حسب اختيارك – IntelliJ IDEA أو Eclipse أو VS Code.
- نماذج مستندات مع تعليقات – ملفات DOCX و XLSX و PPTX التي تحتوي على ملاحظات المراجعين.
إعداد بيئة التطوير الخاصة بك
الخطوة 1: التحقق من تثبيت Java
Open a terminal and run:
java -version
You should see a version string beginning with 1.8 or higher. If not, download the latest JDK from the official Oracle or OpenJDK website.
الخطوة 2: التحقق من تثبيت Maven
Run:
mvn -v
Maven should report its version and the Java version it uses. Install Maven from the Apache website if the command is not recognised.
الخطوة 3: إنشاء مشروع Maven جديد
Generate a skeleton project with:
mvn archetype:generate -DgroupId=com.example.viewer -DartifactId=viewer-demo -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
Navigate into the newly created viewer-demo folder and you’re ready to add GroupDocs Viewer.
إعداد GroupDocs.Viewer لـ Java
إضافة التبعيات
The first step in any GroupDocs Viewer Java tutorial is getting the library into your project. Add this configuration to your pom.xml file:
<dependency>
<groupId>com.groupdocs</groupId>
<artifactId>groupdocs-viewer</artifactId>
<version>25.2</version>
</dependency>
نصيحة احترافية: Always check the صفحة إصدارات GroupDocs for the latest version. The library is actively maintained with regular updates and bug fixes.
فهم خيارات الترخيص
GroupDocs offers flexible licensing that fits different project needs:
- نسخة تجريبية مجانية (مثالية للتعلم): تقييم لمدة 30 يومًا مع الوصول الكامل للميزات وعلامات مائية تجريبية.
- ترخيص مؤقت (للتطوير): تقييم ممتد بدون علامات مائية؛ مثالي لمشاريع إثبات المفهوم. اطلبه من صفحة الترخيص المؤقت لـ GroupDocs.
- ترخيص كامل (جاهز للإنتاج): لا قيود أو علامات مائية، يُسمح بالاستخدام التجاري. متاح في صفحة شراء GroupDocs.
نمط التهيئة الأساسي
Here’s the fundamental pattern you’ll use throughout this tutorial:
try (Viewer viewer = new Viewer("input.docx")) {
// Rendering options will be set later
}
لماذا يعمل هذا النمط:
- إدارة الموارد تلقائيًا تمنع تسرب الذاكرة.
- معالجة الاستثناءات تلتقط مشكلات الوصول إلى الملفات الشائعة.
- كود نظيف وقابل للقراءة يسهل صيانته عبر المشاريع الكبيرة.
التنفيذ الأساسي: عرض المستندات مع التعليقات
فهم العملية
When you render a document with GroupDocs Viewer, the library performs four key steps:
- تحليل المستند – يحلل ملف الإدخال ويبني تمثيلًا داخليًا.
- استخراج التعليقات – يحدد كل تعليق، حاشية، وتوضيح.
- إنشاء HTML – ينشئ HTML نظيف ومتوافق مع المعايير يعكس التخطيط الأصلي.
- معالجة الموارد – يجمع الصور، CSS، والخطوط إما مدمجة أو كملفات خارجية.
تنفيذ خطوة بخطوة
الخطوة 1: إعداد مسارات الملفات الخاصة بك
Organise your input and output locations early to avoid path‑related errors:
Path inputPath = Paths.get("documents/sample-with-comments.docx");
Path outputDir = Paths.get("output/html");
Files.createDirectories(outputDir);
لماذا هذا النهج:
- يستخدم API
Pathالحديثة في Java NIO.2، وهي أكثر موثوقية منjava.io.File. - أسماء المتغيرات الوصفية تجعل تصحيح الأخطاء أسهل.
- العنصر النائب
{0}في نمط الإخراج يُستبدل تلقائيًا بأرقام الصفحات.
الخطوة 2: تكوين خيارات عرض HTML
This is where the magic happens. We tell GroupDocs exactly how we want the document rendered:
HtmlViewOptions viewOptions = HtmlViewOptions.forEmbeddedResources(outputDir);
viewOptions.setRenderComments(true); // Preserve every comment
viewOptions.setPageNumberPrefix("page_");
تفاصيل التكوين الرئيسية:
forEmbeddedResources()يدمج CSS والصور والخطوط مباشرةً في HTML، مما يجعل الإخراج قابلًا للنقل.setRenderComments(true)هو السطر الوحيد الذي يضمن أن تحويل word إلى html يحتفظ بجميع ملاحظات المراجعين.forExternalResources()يتيح لك تخزين الأصول بشكل منفصل إذا كنت تفضل ملف HTML أصغر.
الخطوة 3: تنفيذ العرض
Now we bring everything together:
try (Viewer viewer = new Viewer(inputPath.toFile())) {
viewer.view(viewOptions);
}
The view call reads the Word file, extracts comments, generates HTML pages, and writes them to output/html. Each page is saved as page_1.html, page_2.html, etc.
مثال عملي كامل
Putting all pieces together gives you a single, runnable class that converts a Word document to HTML while keeping comments intact. (The full source code is available in the official GitHub repository.)
التكوين المتقدم والخيارات
إعداد أدلة إخراج ديناميكية
For larger applications you may want to generate output directories based on user IDs or timestamps:
String userId = "12345";
Path dynamicOutput = Paths.get("output", userId, LocalDate.now().toString());
Files.createDirectories(dynamicOutput);
HtmlViewOptions dynamicOptions = HtmlViewOptions.forEmbeddedResources(dynamicOutput);
المشكلات الشائعة واستكشاف الأخطاء
المشكلة 1: أخطاء “الملف غير موجود”
Make sure the input path is absolute or relative to the working directory, and verify file permissions. Using Path objects helps avoid common string‑concatenation mistakes.
المشكلة 2: التعليقات لا تظهر في الإخراج
Double‑check that setRenderComments(true) is called before viewer.view(). Also ensure the source document actually contains comments; you can inspect them via viewer.getDocumentInfo().getComments().
المشكلة 3: أخطاء نفاد الذاكرة مع المستندات الكبيرة
GroupDocs Viewer streams data, but extremely large files (> 500 pages) may still strain the JVM heap. Increase heap size with -Xmx4g or render only needed pages.
المشكلة 4: بطء أداء العرض
Render specific page ranges using viewer.view(pageRange, viewOptions). External resources (forExternalResources()) also reduce HTML payload size, speeding up browser rendering.
أنماط التنفيذ في العالم الحقيقي
النمط 1: دمج تطبيق ويب
Integrate the rendering logic into a Spring Boot controller to serve HTML on demand:
@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: معالجة دفعة متعددة من المستندات
When you need to convert a whole folder of Word files, loop through the directory and reuse the same HtmlViewOptions instance to minimise object creation overhead.
تحسين الأداء وأفضل الممارسات
نصائح إدارة الذاكرة
- استخدم دائمًا try‑with‑resources لكائنات
Viewer. - عالج المستندات الكبيرة على دفعات بدلاً من تحميل كل شيء في الذاكرة مرة واحدة.
- راقب استخدام heap في JVM باستخدام أدوات مثل VisualVM واضبط
-Xmxحسب الحاجة. - نفذ التخزين المؤقت المناسب للمستندات التي يتم الوصول إليها بشكل متكرر لتجنب إعادة العرض المتكرر.
إرشادات استخدام الموارد
For Small Applications (< 100 documents/day):
HtmlViewOptions options = HtmlViewOptions.forEmbeddedResources(Paths.get("output"));
options.setRenderComments(true);
For High‑Volume Applications (1000+ documents/day):
HtmlViewOptions options = HtmlViewOptions.forExternalResources(Paths.get("output"));
options.setRenderComments(true);
options.setCacheEnabled(true);
استراتيجيات التخزين المؤقت
Store rendered HTML in a distributed cache (e.g., Redis) keyed by document hash. When a request arrives, check the cache first; if a hit, serve the cached HTML instantly, bypassing the rendering engine.
متى تستخدم GroupDocs Viewer مقابل البدائل
GroupDocs Viewer مثالي لـ
- أنظمة إدارة المستندات – تحتاج إلى عرض العديد من أنواع الملفات مع التعليقات.
- منصات المراجعة التعاونية – يجب أن تبقى التعليقات مرئية لجميع المشاركين.
- أدوات التعليم – تظهر ملاحظات المدربين بجانب شرائح المحاضرات.
- تطبيقات قانونية – العقود التي تحتوي على تعليقات المحامين تتطلب عرضًا دقيقًا.
فكر في البدائل عندما
- عرض PDF بسيط – قد تكون عارضات PDF المدمجة في المتصفح كافية.
- تحويل الصور الأساسي –
ImageIOأو مكتبات مماثلة أخف. - استخراج النص فقط – قد يكون Apache POI أو iText أكثر ملاءمة.
الأسئلة المتكررة
س: هل يمكنني عرض المستندات بدون تعليقات؟
ج: نعم — ما عليك سوى حذف استدعاء setRenderComments(true) أو تعيينه إلى false.
س: ما صيغ الملفات التي تدعم عرض التعليقات؟
ج: معظم الصيغ الرئيسية — بما في ذلك DOC/DOCX و XLS/XLSX و PPT/PPTX و PDF والعديد غيرها. راجع التوثيق الرسمي للقائمة الكاملة.
س: هل يمكنني تخصيص تنسيق مخرجات HTML؟
ج: بالتأكيد. استخدم HtmlViewOptions.setEmbedResources(false) لإنشاء ملفات CSS خارجية، ثم أضف ورقة الأنماط الخاصة بك بعد العرض.
س: كيف أتعامل مع المستندات المحمية بكلمة مرور؟
ج: Provide a LoadOptions instance with the password:
LoadOptions allows you to specify document loading parameters such as passwords.
LoadOptions loadOptions = new LoadOptions("myPassword");
try (Viewer viewer = new Viewer(inputPath.toFile(), loadOptions)) {
viewer.view(viewOptions);
}
س: هل من الممكن عرض صفحات محددة فقط؟
ج: Yes—use the overloaded view method that accepts a PageNumber collection:
viewer.view(new int[]{1, 3, 5}, viewOptions);
س: لماذا يكون العرض بطيئًا للمستندات الكبيرة؟
ج: Large files require more processing time. Improve speed by rendering only needed pages, using external resources, increasing JVM heap, and enabling asynchronous processing.
س: كيف يمكنني مراقبة تقدم العرض؟
ج: While GroupDocs Viewer lacks built‑in callbacks, you can time the operation with System.nanoTime() before and after viewer.view() to log duration.
س: ماذا يحدث إذا كان المستند المصدر تالفًا؟
ج: The library throws a ViewerException. Wrap the call in a try‑catch block and log the error for graceful degradation.
س: هل يمكنني استخدام GroupDocs Viewer في تطبيق تجاري؟
ج: Yes, but a commercial license is required. The free trial includes watermarks that must be removed for production use.
س: هل هناك أي حدود للاستخدام؟
ج: The library itself imposes no limits, though your license agreement may define usage caps. Review your contract for details.
س: هل يمكنني إعادة توزيع التطبيقات التي تتضمن GroupDocs Viewer؟
ج: You may distribute your own application, but you cannot redistribute the GroupDocs library binaries themselves. Check the license terms for compliance.
الخطوات التالية والمواضيع المتقدمة
You now have a solid foundation for convert word to html while preserving comments. Here are a few directions to deepen your expertise:
- إضافة علامة مائية – أضف علامات مائية مخصصة للصفحات المعروضة للعلامة التجارية أو السرية.
- استخراج البيانات الوصفية – استرجاع المؤلف، تاريخ الإنشاء، وعدد الصفحات عبر
viewer.getDocumentInfo(). - عارضات مخصصة – بناء عارضات متخصصة للـ PDF أو جداول البيانات أو العروض التي تخفي أو تبرز التعليقات بشكل مختلف.
- دمج التخزين السحابي – عرض الملفات مباشرةً من AWS S3 أو Azure Blob أو Google Drive دون تحميلها محليًا.
مسار التعلم الموصى به
- جرب أنواع ملفات مختلفة – جرّب ملفات Excel و PowerPoint و PDF لترى كيف يتم التعامل مع التعليقات عبر الصيغ.
- بناء عارض ويب بسيط – أنشئ صفحة HTML بسيطة تقوم بتحميل HTML المولد عبر
<iframe>أو AJAX. - استكشف نظام GroupDocs – راجع GroupDocs Annotation و Comparison و Signature لتدفقات عمل المستندات من البداية إلى النهاية.
- انضم إلى المجتمع – شارك في منتدى GroupDocs للحصول على نصائح، مشاريع نموذجية، ودعم.
الحصول على المساعدة والدعم
الموارد الرسمية
موارد المجتمع
- Stack Overflow (الوسم:
groupdocs-viewer) - مجتمعات برمجة Reddit
- خوادم Discord لمطوري Java
آخر تحديث: 2026-05-21
تم الاختبار مع: GroupDocs.Viewer 25.2 for Java
المؤلف: 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());
}