Создание PDF из Word (DOC) с использованием Apache POI и iText на JAVA

#java #ms-word #pdf-generation #itext #apache-poi

#java #ms-word #генерация pdf #itext #apache-poi

Вопрос:

Я пытаюсь сгенерировать PDF-документ из документа *.doc. До сих пор и благодаря stackoverflow я успешно генерировал его, но с некоторыми проблемами.

Приведенный ниже пример кода генерирует PDF без форматирования и изображений, только текст. Документ содержит пробелы и изображения, которых нет в PDF.

Вот код:

         in = new FileInputStream(sourceFile.getAbsolutePath());
        out = new FileOutputStream(outputFile);

        WordExtractor wd = new WordExtractor(in);

        String text = wd.getText();

        Document pdf= new Document(PageSize.A4);

        PdfWriter.getInstance(pdf, out);

        pdf.open();
        pdf.add(new Paragraph(text));
  

Ответ №1:

docx4j включает в себя код для создания PDF из docx с использованием iText. Он также может использовать POI для преобразования документа doc в docx.

Было время, когда мы одинаково поддерживали оба метода (а также PDF через XHTML), но мы решили сосредоточиться на XSL-FO.

Если это возможно, вам было бы намного лучше использовать docx4j для преобразования docx в PDF через XSL-FO и FOP.

Используйте это следующим образом:

         wordMLPackage = WordprocessingMLPackage.load(new java.io.File(inputfilepath));

        // Set up font mapper
        Mapper fontMapper = new IdentityPlusMapper();
        wordMLPackage.setFontMapper(fontMapper);

        // Example of mapping missing font Algerian to installed font Comic Sans MS
        PhysicalFont font 
                = PhysicalFonts.getPhysicalFonts().get("Comic Sans MS");
        fontMapper.getFontMappings().put("Algerian", font);             

        org.docx4j.convert.out.pdf.PdfConversion c 
            = new org.docx4j.convert.out.pdf.viaXSLFO.Conversion(wordMLPackage);
        //  = new org.docx4j.convert.out.pdf.viaIText.Conversion(wordMLPackage);

        OutputStream os = new java.io.FileOutputStream(inputfilepath   ".pdf");         
        c.output(os);
  

Обновление июль 2016

Начиная с версии docx4j 3.3.0, коммерческий рендеринг PDF от Plutext является опцией docx4j по умолчанию для преобразования docx в PDF. Вы можете попробовать онлайн-демонстрацию на converter-eval.plutext.com

Если вы хотите использовать существующий подход docx к XSL-FO к PDF (или другой целевой, поддерживаемый Apache FOP), тогда просто добавьте docx4j-export-FO jar к вашему classpath.

В любом случае, чтобы преобразовать docx в PDF, вы можете использовать метод toPDF фасада Docx4J.

Старый перевод docx в PDF с помощью iText-кода можно найти по адресу https://github.com/plutext/docx4j-export-FO/…/docx4j-extras/PdfViaIText /

Ответ №2:

WordExtractor просто захватывает обычный текст, ничего больше. Вот почему все, что вы видите, — это обычный текст.

Что вам нужно сделать, это получить каждый абзац по отдельности, затем захватить каждый запуск, получить форматирование и сгенерировать эквивалент в формате PDF.

Одним из вариантов может быть поиск некоторого кода, который превращает XHTML в PDF. Затем используйте Apache Tika, чтобы преобразовать ваш документ word в XHTML (он использует POI под капотом и обрабатывает все форматирование за вас), а из XHTML — в PDF.

В противном случае, если вы собираетесь сделать это самостоятельно, взгляните на код в Apache Tika для синтаксического анализа файлов word. Это действительно отличный пример того, как получить доступ к изображениям, форматированию, стилям и т.д.

Комментарии:

1. Я действительно не мог попасть в проект Tika для разбора файлов word. Знаете ли вы о каком-либо другом проекте для разбора файла word или о примере проекта / описании, как разобрать его самостоятельно. Мне нужны только форматирование и картинки рядом с обычным текстом в файле word.

2. Начать работу с Tika должно быть очень просто! Просто возьмите программу Tika CLI и передайте ей файл word, и вы получите обратно XHTML. Будьте довольны этим, затем начните вызывать Java самостоятельно.

Ответ №3:

Я успешно использовал Apache FOP для преобразования документа WordML в PDF. WordML — это способ сохранения документа Word в формате xml в Office 2003. В Интернете можно найти таблицы стилей XSLT для преобразования этого xml в xml-fo, который, в свою очередь, может быть отображен FOP в PDF (среди прочих выходных данных).

Это не так уж сильно отличается от решения, предлагаемого plutext, за исключением того, что оно не читает документ .doc, в то время как docx4j, по-видимому, читает. Если ваши требования достаточно гибкие, чтобы использовать документы в стиле WordML в качестве входных данных, возможно, стоит изучить этот вопрос.

Удачи с вашим проектом! Wim

Ответ №4:

Используйте OpenOffice / LbreOffice и JODConnector Это также в основном работает для .doc в .docx. Проблемы с графикой, с которыми я, однако, еще не разобрался.

     private static void transformDocXToPDFUsingJOD(File in, File out)
{
    OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager);
    DocumentFormat pdf = converter.getFormatRegistry().getFormatByExtension("pdf");
    converter.convert(in, out, pdf);
}



private static OfficeManager officeManager;

@BeforeClass
public static void setupStatic() throws IOException {

    /*officeManager = new DefaultOfficeManagerConfiguration()
      .setOfficeHome("C:/Program Files/LibreOffice 3.6")
      .buildOfficeManager();
      */
    officeManager = new ExternalOfficeManagerConfiguration().setConnectOnStart(true).setPortNumber(8100).buildOfficeManager();


    officeManager.start();
}

@AfterClass
public static void shutdownStatic() throws IOException {

    officeManager.stop();
}
  

Чтобы это сработало, вы должны запустить LibreOffice в качестве сервера.
Из командной строки вы можете сделать это с помощью;

 "C:Program FilesLibreOffice 3.6programsoffice.exe" -accept="socket,host=0.0.0.0,port=8100;urp;LibreOffice.ServiceManager" -headless -nodefault -nofirststartwizard -nolockcheck -nologo -norestore
  

Ответ №5:

Другой вариант, с которым я недавно столкнулся, — это использование OpenOffice (или LibreOffice) API (смотрите здесь). Я не смог разобраться в этом, но он должен иметь возможность открывать документы в различных форматах и выводить их в формате pdf. Если вы разберетесь в этом, дайте мне знать, как это сработало!