Samouczek GroupDocs Viewer Java: Konwertowanie Word do HTML i renderowanie dokumentów z komentarzami

Wprowadzenie

Jeśli potrzebujesz konwertować Word do HTML zachowując wszystkie notatki recenzentów, komentarze lub adnotacje, trafiłeś we właściwe miejsce. Wielu programistów Java napotyka problem, gdy konwersja dokumentu usuwa cenne informacje zwrotne osadzone w oryginalnym pliku. Ten samouczek przeprowadzi Cię przez użycie GroupDocs Viewer dla Java do konwertowania Word do HTML i renderowania szerokiego zakresu typów dokumentów — Word, Excel, PowerPoint, PDF i innych — bez utraty danych komentarzy.

Dowiesz się, dlaczego GroupDocs Viewer jest gotowym do produkcji wyborem, jak skonfigurować środowisko, jaki kod jest potrzebny oraz sprawdzone triki, które utrzymają wydajność nawet przy dużych plikach.

Renderuj dokumenty z komentarzami przy użyciu GroupDocs.Viewer dla Java

Renderuj dokumenty z komentarzami przy użyciu GroupDocs.Viewer dla Java

Co opanujesz w tym samouczku:

  • Pełna konfiguracja i ustawienia GroupDocs Viewer
  • Krok po kroku konwertowanie Word do HTML z zachowanymi komentarzami
  • Typowe rozwiązania problemów i pułapki, których należy unikać
  • Wzorce implementacji w rzeczywistych projektach oraz najlepsze praktyki
  • Techniki optymalizacji wydajności dla środowisk produkcyjnych

Szybkie odpowiedzi

  • Czy GroupDocs Viewer może konwertować Word do HTML? Tak — włącz renderowanie HTML i obsługę komentarzy w jednej linii kodu.
  • Czy komentarze pozostają w wyjściowym HTML? Absolutnie — setRenderComments(true) zachowuje każdy komentarz i adnotację.
  • Jakiej wersji Javy wymaga? JDK 8 lub wyższej.
  • Czy potrzebna jest licencja do produkcji? Pełna licencja usuwa znaki wodne i odblokowuje wszystkie funkcje.
  • Jak przyspieszyć renderowanie? Renderuj konkretne strony, używaj zasobów zewnętrznych i zwiększ rozmiar sterty JVM.

Co oznacza „konwertowanie word do html” z komentarzami?

„Konwertowanie Word do HTML” oznacza przekształcenie pliku Microsoft Word .docx w dokument HTML gotowy do wyświetlenia w przeglądarce, zachowując pierwotny układ, stylizację oraz wszystkie osadzone komentarze. Proces ten umożliwia przeglądarkom wyświetlenie dokumentu dokładnie tak, jak autor tego zamierzał, wraz z opiniami recenzentów.

Dlaczego wybrać GroupDocs Viewer dla Java?

Zanim przejdziemy do kodu, przyjrzyjmy się, dlaczego GroupDocs Viewer jest biblioteką numer jeden do renderowania dokumentów w Javie:

  • Ponad 170 obsługiwanych formatów – biblioteka radzi sobie ze wszystkim, od DOCX po pliki CAD, dając jedną zależność dla wszystkich potrzeb konwersji.
  • Brak wymogu instalacji Office – działa na każdym systemie operacyjnym bez potrzeby Microsoft Office, LibreOffice czy innych ciężkich środowisk.
  • Zachowuje formatowanie i adnotacje – komentarze, przypisy i śledzone zmiany przechodzą konwersję nienaruszone.
  • Szybki, lekki silnik – typowy dokument 100‑stronicowy renderuje się w mniej niż 2 sekundy na standardowym serwerze 4‑rdzeniowym.
  • Rozbudowana dokumentacja i aktywna społeczność – znajdziesz przykłady, fora i szybką pomoc, gdy napotkasz problem.

Kiedy stosować to podejście

  • Budowanie przeglądarek dokumentów w sieci, które muszą wyświetlać notatki recenzentów
  • Tworzenie platform współpracy, gdzie opinie muszą pozostać widoczne
  • Konwersja starszych umów do wyświetlania online w portalach prawnych
  • Opracowywanie rozwiązań e‑learningowych, które wstawiają komentarze instruktora do materiałów szkoleniowych

Wymagania wstępne i konfiguracja środowiska

Czego będziesz potrzebować

  • Java Development Kit (JDK) 8+ – środowisko uruchomieniowe Twojej aplikacji.
  • Maven 3.6+ – do zarządzania zależnościami i budowania projektu.
  • IDE według wyboru – IntelliJ IDEA, Eclipse lub VS Code.
  • Przykładowe dokumenty z komentarzami – pliki DOCX, XLSX, PPTX zawierające notatki recenzentów.

Konfiguracja środowiska programistycznego

Krok 1: Sprawdź instalację Javy

Otwórz terminal i uruchom:

java -version

Powinieneś zobaczyć ciąg wersji zaczynający się od 1.8 lub wyższego. Jeśli nie, pobierz najnowszy JDK ze strony Oracle lub OpenJDK.

Krok 2: Sprawdź instalację Maven

Uruchom:

mvn -v

Maven powinien wyświetlić swoją wersję oraz wersję Javy, której używa. Zainstaluj Maven ze strony Apache, jeśli polecenie nie zostanie rozpoznane.

Krok 3: Utwórz nowy projekt Maven

Wygeneruj szkielet projektu poleceniem:

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

Wejdź do nowo utworzonego folderu viewer-demo i możesz dodać GroupDocs Viewer.

Konfiguracja GroupDocs.Viewer dla Java

Dodanie zależności

Pierwszy krok w każdym samouczku GroupDocs Viewer Java to dodanie biblioteki do projektu. Dodaj tę konfigurację do pliku pom.xml:

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

Wskazówka: Zawsze sprawdzaj stronę wydań GroupDocs pod kątem najnowszej wersji. Biblioteka jest aktywnie utrzymywana, z regularnymi aktualizacjami i poprawkami błędów.

Zrozumienie opcji licencjonowania

GroupDocs oferuje elastyczne licencje dopasowane do różnych potrzeb projektowych:

  • Bezpłatna wersja próbna (Idealna do nauki): 30‑dniowa ocena z pełnym dostępem do funkcji i znakami wodnymi w wersji testowej.
  • Licencja tymczasowa (Do rozwoju): wydłużona ocena bez znaków wodnych; idealna do projektów proof‑of‑concept. Zamów pod adresem GroupDocs Temporary License Page.
  • Pełna licencja (Gotowa do produkcji): brak ograniczeń i znaków wodnych, do użytku komercyjnego. Dostępna pod adresem GroupDocs Purchase Page.

Podstawowy wzorzec inicjalizacji

Oto podstawowy wzorzec, którego będziesz używać w całym samouczku:

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

Dlaczego ten wzorzec działa:

  • Automatyczne zarządzanie zasobami zapobiega wyciekom pamięci.
  • Obsługa wyjątków przechwytuje typowe problemy z dostępem do plików.
  • Czysty, czytelny kod łatwy do utrzymania w dużych projektach.

Główna implementacja: renderowanie dokumentów z komentarzami

Zrozumienie procesu

Podczas renderowania dokumentu przy użyciu GroupDocs Viewer biblioteka wykonuje cztery kluczowe kroki:

  1. Analiza dokumentu – parsuje plik wejściowy i buduje wewnętrzną reprezentację.
  2. Ekstrakcja komentarzy – identyfikuje każdy komentarz, przypis i adnotację.
  3. Generowanie HTML – tworzy czysty, zgodny ze standardami HTML odzwierciedlający oryginalny układ.
  4. Obsługa zasobów – pakuje obrazy, CSS i czcionki jako wbudowane lub zewnętrzne pliki.

Implementacja krok po kroku

Krok 1: Ustaw ścieżki plików

Zorganizuj lokalizacje wejścia i wyjścia na wczesnym etapie, aby uniknąć błędów związanych ze ścieżkami:

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

Dlaczego to podejście:

  • Używa nowoczesnego API Java NIO.2 Path, które jest bardziej niezawodne niż java.io.File.
  • Opisowe nazwy zmiennych ułatwiają debugowanie.
  • Symbol {0} w wzorcu wyjścia jest automatycznie zastępowany numerami stron.

Krok 2: Skonfiguruj opcje renderowania HTML

Tutaj dzieje się magia. Mówimy GroupDocs, jak dokładnie ma zostać wyrenderowany dokument:

HtmlViewOptions konfiguruje sposób renderowania dokumentu do HTML, w tym obsługę zasobów i renderowanie komentarzy.

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

Kluczowe szczegóły konfiguracji:

  • forEmbeddedResources() wstawia CSS, obrazy i czcionki bezpośrednio do HTML, co czyni wynik przenośnym.
  • setRenderComments(true) to jedyna linia, która zapewnia, że konwertowanie word do html zachowuje wszystkie notatki recenzentów.
  • Alternatywa forExternalResources() pozwala przechowywać zasoby osobno, jeśli wolisz lżejszy plik HTML.

Krok 3: Wykonaj renderowanie

Teraz łączymy wszystkie elementy:

Viewer jest główną klasą używaną do ładowania dokumentu i wykonywania operacji renderowania.

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

Wywołanie view odczytuje plik Word, wyodrębnia komentarze, generuje strony HTML i zapisuje je w output/html. Każda strona jest zapisywana jako page_1.html, page_2.html itd.

Kompletny działający przykład

Połączenie wszystkich elementów daje jedną, gotową do uruchomienia klasę, która konwertuje dokument Word do HTML, zachowując komentarze. (Pełny kod źródłowy dostępny jest w oficjalnym repozytorium GitHub.)

Zaawansowana konfiguracja i opcje

Ustawianie dynamicznych katalogów wyjściowych

W większych aplikacjach możesz chcieć generować katalogi wyjściowe na podstawie identyfikatorów użytkowników lub znaczników czasu:

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

Typowe problemy i ich rozwiązywanie

Problem 1: Błąd „File Not Found”

Upewnij się, że ścieżka wejściowa jest absolutna lub względna względem katalogu roboczego oraz sprawdź uprawnienia do pliku. Użycie obiektów Path pomaga unikać typowych błędów przy łączeniu łańcuchów.

Problem 2: Komentarze nie pojawiają się w wyniku

Sprawdź, czy setRenderComments(true) jest wywołane przed viewer.view(). Upewnij się także, że źródłowy dokument rzeczywiście zawiera komentarze; możesz je sprawdzić przez viewer.getDocumentInfo().getComments().

Problem 3: Błędy pamięci przy dużych dokumentach

GroupDocs Viewer strumieniuje dane, ale bardzo duże pliki (> 500 stron) mogą nadal obciążać stertę JVM. Zwiększ rozmiar sterty, np. -Xmx4g, lub renderuj tylko potrzebne strony.

Problem 4: Wolne renderowanie

Renderuj określone zakresy stron przy użyciu viewer.view(pageRange, viewOptions). Zasoby zewnętrzne (forExternalResources()) także zmniejszają rozmiar HTML, przyspieszając wyświetlanie w przeglądarce.

Wzorce implementacji w rzeczywistych projektach

Wzorzec 1: Integracja z aplikacją webową

Zintegruj logikę renderowania w kontrolerze Spring Boot, aby serwować HTML na żądanie:

@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);
    }
}

Wzorzec 2: Przetwarzanie wsadowe wielu dokumentów

Gdy musisz konwertować cały folder plików Word, przeiteruj katalog i ponownie użyj tej samej instancji HtmlViewOptions, aby zminimalizować narzut tworzenia obiektów.

Optymalizacja wydajności i najlepsze praktyki

Wskazówki dotyczące zarządzania pamięcią

  • Zawsze używaj try‑with‑resources dla instancji Viewer.
  • Przetwarzaj duże dokumenty partiami, zamiast ładować wszystko jednocześnie do pamięci.
  • Monitoruj zużycie sterty JVM narzędziami takimi jak VisualVM i dostosowuj -Xmx w razie potrzeby.
  • Wdrażaj odpowiednie buforowanie często używanych dokumentów, aby uniknąć powtarzającego się renderowania.

Wytyczne dotyczące zużycia zasobów

Dla małych aplikacji (< 100 dokumentów/dzień):

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

Dla aplikacji o wysokim wolumenie (1000+ dokumentów/dzień):

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

Strategie buforowania

Przechowuj wyrenderowany HTML w rozproszonym cache (np. Redis) z kluczem opartym na hashu dokumentu. Przy przychodzącym żądaniu najpierw sprawdź cache; w przypadku trafienia serwuj natychmiast, omijając silnik renderujący.

Kiedy wybrać GroupDocs Viewer zamiast alternatyw

GroupDocs Viewer jest idealny dla

  • Systemów zarządzania dokumentami – potrzeba wyświetlania wielu typów plików z adnotacjami.
  • Platform współpracy – komentarze muszą być widoczne dla wszystkich uczestników.
  • Narzędzi e‑learningowych – notatki instruktorów pojawiają się obok slajdów.
  • Aplikacji prawnych – umowy z komentarzami prawników wymagają wiernego renderowania.

Rozważ alternatywy, gdy

  • Potrzebny jest prosty podgląd PDF – wbudowane przeglądarki PDF mogą wystarczyć.
  • Wystarczy konwersja obrazówImageIO lub podobne biblioteki są lżejsze.
  • Wystarczy wyodrębnienie czystego tekstu – Apache POI lub iText mogą być bardziej odpowiednie.

Najczęściej zadawane pytania

P: Czy mogę renderować dokumenty bez komentarzy?
O: Tak — po prostu pomiń wywołanie setRenderComments(true) lub ustaw je na false.

P: Jakie formaty plików obsługują renderowanie komentarzy?
O: Większość popularnych formatów — w tym DOC/DOCX, XLS/XLSX, PPT/PPTX, PDF i wiele innych. Pełną listę znajdziesz w oficjalnej dokumentacji.

P: Czy mogę dostosować stylowanie wyjściowego HTML?
O: Oczywiście. Użyj HtmlViewOptions.setEmbedResources(false), aby wygenerować zewnętrzne pliki CSS, a następnie dodaj własny arkusz stylów po renderowaniu.

P: Jak obsłużyć dokumenty zabezpieczone hasłem?
O: Dostarcz instancję LoadOptions z hasłem:

LoadOptions pozwala określić parametry ładowania dokumentu, takie jak hasła.

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

P: Czy mogę renderować tylko wybrane strony?
O: Tak — użyj przeciążonej metody view, która przyjmuje kolekcję PageNumber:

PageNumber reprezentuje konkretny indeks strony używany przy renderowaniu podzbioru stron.

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

P: Dlaczego renderowanie jest wolne przy dużych dokumentach?
O: Duże pliki wymagają więcej czasu przetwarzania. Popraw wydajność, renderując tylko potrzebne strony, używając zasobów zewnętrznych, zwiększając stertę JVM i włączając przetwarzanie asynchroniczne.

P: Jak mogę monitorować postęp renderowania?
O: Choć GroupDocs Viewer nie posiada wbudowanych callbacków, możesz zmierzyć czas operacji przy pomocy System.nanoTime() przed i po wywołaniu viewer.view(), aby zalogować czas trwania.

P: Co się stanie, jeśli źródłowy dokument jest uszkodzony?
O: Biblioteka rzuci ViewerException. Owiń wywołanie w blok try‑catch i zaloguj błąd, aby zapewnić łagodne zachowanie aplikacji.

P: Czy mogę używać GroupDocs Viewer w aplikacji komercyjnej?
O: Tak, ale wymagana jest licencja komercyjna. Bezpłatna wersja próbna zawiera znaki wodne, które muszą być usunięte w środowisku produkcyjnym.

P: Czy istnieją limity użytkowania?
O: Sama biblioteka nie narzuca limitów, choć umowa licencyjna może definiować limity wykorzystania. Sprawdź swój kontrakt pod kątem szczegółów.

P: Czy mogę rozpowszechniać aplikacje zawierające GroupDocs Viewer?
O: Możesz dystrybuować własną aplikację, ale nie możesz rozpowszechniać samych binarek biblioteki GroupDocs. Zapoznaj się z warunkami licencji.

Kolejne kroki i tematy zaawansowane

Masz już solidne podstawy do konwertowania word do html z zachowaniem komentarzy. Oto kilka kierunków, aby pogłębić wiedzę:

  1. Dodawanie znaków wodnych – wstaw własne znaki wodne na renderowanych stronach w celu brandingu lub ochrony poufności.
  2. Ekstrakcja metadanych – pobierz autora, datę utworzenia i liczbę stron za pomocą viewer.getDocumentInfo().
  3. Niestandardowe przeglądarki – buduj wyspecjalizowane przeglądarki dla PDF, arkuszy kalkulacyjnych lub prezentacji, które ukrywają lub podkreślają komentarze w inny sposób.
  4. Integracja z chmurą – renderuj pliki bezpośrednio z AWS S3, Azure Blob lub Google Drive, bez ich pobierania na dysk lokalny.

Zalecana ścieżka nauki

  1. Eksperymentuj z różnymi typami plików – wypróbuj Excel, PowerPoint i PDF, aby zobaczyć, jak komentarze są obsługiwane w różnych formatach.
  2. Zbuduj prostą przeglądarkę webową – stwórz minimalną stronę HTML, która ładuje wygenerowany HTML za pomocą <iframe> lub AJAX.
  3. Poznaj ekosystem GroupDocs – zapoznaj się z GroupDocs Annotation, Comparison i Signature, aby uzyskać pełny przepływ pracy z dokumentami.
  4. Dołącz do społeczności – uczestnicz w forum GroupDocs w celu uzyskania wskazówek, przykładów projektów i wsparcia.

Uzyskanie pomocy i wsparcia

Oficjalne zasoby

Zasoby społecznościowe

  • Stack Overflow (tag: groupdocs-viewer)
  • Społeczności programistyczne na Reddit
  • Serwery Discord dla programistów Java

Ostatnia aktualizacja: 2026-05-21
Testowane z: GroupDocs.Viewer 25.2 dla Java
Autor: 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());
}

Powiązane samouczki