Преобразование 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» , подготовленной дружной командой проекта Интернет-технологии.ру

Меню