Преобразование 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.

Пожалуйста, оставьте ваши мнения по текущей теме материала. За комментарии, подписки, дизлайки, лайки, отклики огромное вам спасибо!

Пожалуйста, оставляйте свои отзывы по текущей теме статьи. За комментарии, лайки, отклики, дизлайки, подписки огромное вам спасибо!

Сергей Бензенкоавтор-переводчик статьи «PDF Conversions in Java»