#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. Если вы разберетесь в этом, дайте мне знать, как это сработало!