Преобразование PDF-документов в Java
Введение
В этой статье мы расскажем о программном преобразовании PDF- файлов в Java. Опишем, как сохранять PDF-файлы в PNG или JPEG, Microsoft Word, экспортировать в HTML. А также как извлекать из них текст, используя библиотеки Java с открытым исходным кодом.
Ссылки на Maven
Первая библиотека, которую мы рассмотрим, Pdf2Dom. Начнём с добавления зависимостей Maven в наш проект:
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox-tools</artifactId>
<version>2.0.3</version>
</dependency>
<dependency>
<groupId>net.sf.cssbox</groupId>
<artifactId>pdf2dom</artifactId>
<version>1.6</version>
</dependency>
Мы будем использовать первую зависимость для загрузки выбранного PDF-файла. Вторая зависимость отвечает непосредственно за преобразование. Актуальные версии библиотек доступны по следующим ссылкам: pdfbox-tools и pdf2dom.
Кроме этого мы будем использовать iText для извлечения текста из PDF-файла и POI для создания документа в формате .docx.
Рассмотрим зависимости Maven, которые нужно добавить в проект:
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.10</version>
</dependency>
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.10</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.15</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>3.15</version>
</dependency>
Актуальная версия iText доступна здесь, а Apache POI здесь.
Преобразования из PDF в HTML
Для работы с файлами HTML используйте Pdf2Dom. Это парсер PDF, преобразующий документы в представление HTML DOM.
Чтобы преобразовать PDF в HTML, применяется библиотека XMLWorker, входящая в состав iText.
PDF в HTML
Рассмотрим простое преобразование из PDF в HTML:
private void generateHTMLFromPDF(String filename) {
PDDocument pdf = PDDocument.load(new File(filename));
Writer output = new PrintWriter("src/output/pdf.html", "utf-8");
new PDFDomTree().writeText(pdf, output);
output.close();
}
В приведенном выше примере мы загрузили PDF-файл, используя API от PDFBox. После этого мы применили парсер для разбора файла и вывода результата с помощью java.io.Writer.
Обратите внимание, что преобразование PDF в HTML не является на 100% точным. Результат зависят от сложности и структуры конкретного PDF-файла.
HTML в PDF
Теперь рассмотрим преобразование HTML в PDF:
private static void generatePDFFromHTML(String filename) {
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document,
new FileOutputStream("src/output/html.pdf"));
document.open();
XMLWorkerHelper.getInstance().parseXHtml(writer, document,
new FileInputStream(filename));
document.close();
}
При преобразовании HTML в PDF нужно убедиться, что все теги правильно открываются и закрываются. Иначе PDF-документ не будет создан.
Преобразование PDF в изображение
Есть много способов преобразовать PDF-файл в изображение. Одно из наиболее популярных решений – библиотека с открытым исходным кодом Apache PDFBox. Для преобразования изображения в PDF-документ мы снова используем iText.
PDF в изображение
Для конвертации используем зависимость pdfbox-tools, упомянутую в предыдущих разделах. Рассмотрим следующий пример:
private void generateImageFromPDF(String filename, String extension) {
PDDocument document = PDDocument.load(new File(filename));
PDFRenderer pdfRenderer = new PDFRenderer(document);
for (int page = 0; page < document.getNumberOfPages(); ++page) {
BufferedImage bim = pdfRenderer.renderImageWithDPI(
page, 300, ImageType.RGB);
ImageIOUtil.writeImage(
bim, String.format("src/output/pdf-%d.%s", page + 1, extension), 300);
}
document.close();
}
В приведенном примере PDFRenderer применяется, чтобы отрисовать PDF как BufferedImage. При этом каждая страница PDF- файла должна быть отрисована отдельно.
Также мы используем ImageIOUtil из Apache PDFBox Tools для записи изображения в файл с указанным расширением. Поддерживаемые форматы: jpeg, jpg, gif, tiff или png.
Apache PDFBox – это продвинутый инструмент. Он позволяет создавать PDF-файлы с нуля, заполнять формы внутри PDF-файла, подписывать и шифровать его содержимое.
Изображение в PDF
Рассмотрим следующий пример:
private static void generatePDFFromImage(String filename, String extension) {
Document document = new Document();
String input = filename + "." + extension;
String output = "src/output/" + extension + ".pdf";
FileOutputStream fos = new FileOutputStream(output);
PdfWriter writer = PdfWriter.getInstance(document, fos);
writer.open();
document.open();
document.add(Image.getInstance((new URL(input))));
document.close();
writer.close();
}
Расширения выходного файла могут быть следующими: jpeg, jpg, gif, tiff или png.
Преобразования PDF в текст
Чтобы извлечь текст из PDF-файла, нам снова понадобится Apache PDFBox. Для преобразования текста в PDF мы будем использовать iText.
PDF в текст
Мы создадим метод generateTxtFromPDF(…) и разделим его код на три функциональных части: загрузка PDF, извлечение текста и создание итогового файла.
Начнём с загрузки PDF:
File f = new File(filename);
String parsedText;
PDFParser parser = new PDFParser(new RandomAccessFile(f, "r"));
parser.parse();
Чтобы прочитать PDF-файл, используем PDFParser с флагом r (read). А также метод parser.parse(), который разберёт файл в поток и создаст из него объект COSDocument.
Часть кода, отвечающая за извлечение текста:
COSDocument cosDoc = parser.getDocument();
PDFTextStripper pdfStripper = new PDFTextStripper();
PDDocument pdDoc = new PDDocument(cosDoc);
parsedText = pdfStripper.getText(pdDoc);
Сначала мы сохраняем объект COSDocument в переменную cosDoc. Затем он будет использован для создания PDDocument, который является представлением PDF-документа в памяти. После этого используем PDFTextStripper, чтобы вернуть документ с текстом. В конце вызываем метод close(), чтобы закрыть все использованные потоки.
В последней части метода мы сохраним текст в созданный файл с помощью класса PrintWriter:
PrintWriter pw = new PrintWriter("src/output/pdf.txt");
pw.print(parsedText);
pw.close();
Текст в PDF
Преобразование текстовых файлов в PDF – операция с подвохом. Чтобы сохранить форматирование исходного файла, необходимо применить дополнительные правила.
В следующем примере мы определяем размер страницы PDF-файла, версию и выходной файл:
Document pdfDoc = new Document(PageSize.A4);
PdfWriter.getInstance(pdfDoc, new FileOutputStream("src/output/txt.pdf"))
.setPdfVersion(PdfWriter.PDF_VERSION_1_7);
pdfDoc.open();
Затем задаем шрифт, а также символ для разделения параграфов:
Font myfont = new Font();
myfont.setStyle(Font.NORMAL);
myfont.setSize(11);
pdfDoc.add(new Paragraph("n"));
После этого добавляем параграфы в созданный PDF-файл:
BufferedReader br = new BufferedReader(new FileReader(filename));
String strLine;
while ((strLine = br.readLine()) != null) {
Paragraph para = new Paragraph(strLine + "n", myfont);
para.setAlignment(Element.ALIGN_JUSTIFIED);
pdfDoc.add(para);
}
pdfDoc.close();
br.close();
Преобразования PDF в Docx
Чтобы создать файл Microsoft Word из PDF-файла, понадобятся две библиотеки с открытым исходным кодом: iText – для извлечения текста из PDF- файла, POI – для создания документа в формате .docx.
Рассмотрим код, предназначенный для загрузки PDF-файла:
XWPFDocument doc = new XWPFDocument();
String pdf = filename;
PdfReader reader = new PdfReader(pdf);
PdfReaderContentParser parser = new PdfReaderContentParser(reader);
После загрузки PDF-файла необходимо прочитать и отрисовать каждую страницу отдельно, а затем записать результат в файл:
for (int i = 1; i <= reader.getNumberOfPages(); i++) {
TextExtractionStrategy strategy =
parser.processContent(i, new SimpleTextExtractionStrategy());
String text = strategy.getResultantText();
XWPFParagraph p = doc.createParagraph();
XWPFRun run = p.createRun();
run.setText(text);
run.addBreak(BreakType.PAGE);
}
FileOutputStream out = new FileOutputStream("src/output/pdf.docx");
doc.write(out);
// Закрыть все открытые файлы
Коммерческие библиотеки для преобразования PDF в X
В предыдущих разделах статьи мы рассмотрели библиотеки с открытым исходным кодом. Кроме них существуют и платные решения:
- jPDFImages – позволяет создавать изображения из страниц PDF-документа и экспортировать их в изображения JPEG, TIFF или PNG.
- JPEDAL – мощная библиотека, используемая в SDK для печати, просмотра и преобразования файлов.
- pdfcrowd – библиотека, предназначенная для преобразования из Web/HTML в PDF и из PDF в Web/HTML.
Заключение
В этой статье мы обсудили пути преобразование PDF-файлов в различные форматы. Полный код примеров, приведенных в данной публикации, доступен на GitHub.