PDF Conversions in Java – Java中的PDF转换

最后修改: 2016年 11月 16日


1. Introduction


In this quick article, we’ll focus on doing programmatic conversion between PDF files and other formats in Java.


More specifically, we’ll describe how to save PDFs as image files, such as PNG or JPEG, convert PDFs to Microsoft Word documents, export as an HTML, and extract the texts, by using multiple Java open-source libraries.

更具体地说,我们将描述如何通过使用多个Java开源库将PDF保存为图像文件,如PNG或JPEG,将PDF转换成Microsoft Word文档,导出为HTML,并提取文本。

2. Maven Dependencies


The first library we’ll look at is Pdf2Dom. Let’s start with the Maven dependencies we need to add to our project:



We’re going to use the first dependency to load the selected PDF file. The second dependency is responsible for the conversion itself. The latest versions can be found here: pdfbox-tools and pdf2dom.

我们将使用第一个依赖关系来加载选定的 PDF 文件。第二个依赖关系负责转换本身。最新的版本可以在这里找到。pdfbox-toolspdf2dom

What’s more, we’ll use iText to extract the text from a PDF file and POI to create the .docx document.


Let’s take a look at Maven dependencies that we need to include in our project:



The latest version of iText can be found here and you can look for Apache POI here.

最新版本的iText可以在这里找到,你可以在这里寻找Apache POI。

3. PDF and HTML Conversions


To work with HTML files we’ll use Pdf2Dom – a PDF parser that converts the documents to an HTML DOM representation. The obtained DOM tree can then be then serialized to an HTML file or further processed.

为了处理HTML文件,我们将使用Pdf2Dom–一个PDF解析器,它可以将文档转换为HTML DOM表示。然后得到的DOM树可以被序列化为一个HTML文件或进一步处理。

To convert PDF to HTML, we need to use XMLWorker, library that is provided by iText.


3.1. PDF to HTML


Let’s have a look at a simple conversion from PDF to 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);

In the code snippet above we load the PDF file, using the load API from PDFBox. With the PDF loaded, we use the parser to parse the file and write to output specified by java.io.Writer.

在上面的代码片段中,我们使用 PDFBox 的加载 API 加载 PDF 文件。装入 PDF 后,我们使用解析器来解析文件,并写入由 java.io.Writer. 指定的输出。

Note that converting PDF to HTML is never a 100%, pixel-to-pixel result. The results depend on the complexity and the structure of the particular PDF file.


3.2. HTML to PDF


Now, let’s have a look at conversion from HTML to PDF:


private static void generatePDFFromHTML(String filename) {
    Document document = new Document();
    PdfWriter writer = PdfWriter.getInstance(document,
      new FileOutputStream("src/output/html.pdf"));
    XMLWorkerHelper.getInstance().parseXHtml(writer, document,
      new FileInputStream(filename));

Note that converting HTML to PDF, you need to ensure that HTML has all tags properly started and closed, otherwise the PDF will be not created. The positive aspect of this approach is that PDF will be created exactly the same as it was in HTML file.


4. PDF to Image Conversions


There are many ways of converting PDF files to an image. One of the most popular solutions is named Apache PDFBox. This library is an open source Java tool for working with PDF documents. For image to PDF conversion, we’ll use iText again.

有许多方法可以将PDF文件转换为图像。其中一个最流行的解决方案名为Apache PDFBox。这个库是一个用于处理PDF文档的开源Java工具。对于图像到PDF的转换,我们将再次使用iText

4.1. PDF to Image


To start converting PDFs to images, we need to use dependency mentioned in the previous section – pdfbox-tools.


Let’s take a look at the code example:


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);
          bim, String.format("src/output/pdf-%d.%s", page + 1, extension), 300);

There are few important parts in the above-mentioned code. We need to use PDFRenderer, in order to render PDF as a BufferedImage. Also, each page of the PDF file needs to be rendered separately.


Finally, we use ImageIOUtil, from Apache PDFBox Tools, to write an image, with the extension that we specify. Possible file formats are jpeg, jpg, gif, tiff or png.

最后,我们使用Apache PDFBox工具中的ImageIOUtil,来写一个图像,扩展名是我们指定的。可能的文件格式是jpeg、jpg、gif、tiffpng

Note that Apache PDFBox is an advanced tool – we can create our own PDF files from scratch, fill forms inside PDF file, sign and/or encrypt the PDF file.

注意,Apache PDFBox是一个高级工具 – 我们可以从头开始创建我们自己的PDF文件,在PDF文件内填写表格,签署和/或加密PDF文件。

4.2. Image to PDF


Let’s take a look at the code example:


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);
    document.add(Image.getInstance((new URL(input))));

Please note, that we can provide an image as a file, or load it from URL, as it is shown in the example above. Moreover, the extensions of the output file that we can use are jpeg, jpg, gif, tiff or png.


5. PDF to Text Conversions


To extract the raw text out of a PDF file, we’ll also use Apache PDFBox again. For text to PDF conversion, we are going to use iText.

为了从PDF文件中提取原始文本,我们还将再次使用Apache PDFBox。对于文本到PDF的转换,我们将使用iText

5.1. PDF to Text


We created a method named generateTxtFromPDF(…) and divided it into three main parts: loading of the PDF file, extraction of text, and final file creation.


Let’s start with loading part:


File f = new File(filename);
String parsedText;
PDFParser parser = new PDFParser(new RandomAccessFile(f, "r"));

In order to read a PDF file, we use PDFParser, with an “r” (read) option. Moreover, we need to use the parser.parse() method that will cause the PDF to be parsed as a stream and populated into the COSDocument object.

为了读取一个PDF文件,我们使用PDFParser,其中有一个 “r”(读取)选项。此外,我们需要使用parser.parse()方法,该方法将使PDF被解析为一个流,并填充到COSDocument对象中。

Let’s take a look at the extracting text part:


COSDocument cosDoc = parser.getDocument();
PDFTextStripper pdfStripper = new PDFTextStripper();
PDDocument pdDoc = new PDDocument(cosDoc);
parsedText = pdfStripper.getText(pdDoc);

In the first line, we’ll save COSDocument inside the cosDoc variable. It will be then used to construct PDocument, which is the in-memory representation of the PDF document. Finally, we will use PDFTextStripper to return the raw text of a document. After all of those operations, we’ll need to use close() method to close all the used streams.


In the last part, we’ll save text into the newly created file using the simple Java PrintWriter:

在最后一部分,我们将使用简单的Java PrintWriter将文本保存到新创建的文件中。

PrintWriter pw = new PrintWriter("src/output/pdf.txt");

Please note that you cannot preserve formatting in a plain text file because it contains text only.


5.2. Text to PDF


Converting text files to PDF is bit tricky. In order to maintain the file formatting, you’ll need to apply additional rules.


In the following example, we are not taking into consideration the formatting of the file.


First, we need to define the size of the PDF file, version and output file. Let’s have a look at the code example:


Document pdfDoc = new Document(PageSize.A4);
PdfWriter.getInstance(pdfDoc, new FileOutputStream("src/output/txt.pdf"))

In the next step, we’ll define the font and also the command that is used to generate new paragraph:


Font myfont = new Font();
pdfDoc.add(new Paragraph("\n"));

Finally, we are going to add paragraphs into newly created PDF file:


BufferedReader br = new BufferedReader(new FileReader(filename));
String strLine;
while ((strLine = br.readLine()) != null) {
    Paragraph para = new Paragraph(strLine + "\n", myfont);

6. PDF to Docx Conversions


Creating PDF file from Word document is not easy, and we’ll not cover this topic here. We recommend 3rd party libraries to do it, like jWordConvert.


To create Microsoft Word file from a PDF, we’ll need two libraries. Both libraries are open source. The first one is iText and it is used to extract the text from a PDF file. The second one is POI and is used to create the .docx document.

为了从PDF创建Microsoft Word文件,我们将需要两个库。这两个库都是开源的。第一个是iText,它被用来从PDF文件中提取文本。第二个是POI,用于创建.docx文档。

Let’s take a look at the code snippet for the PDF loading part:


XWPFDocument doc = new XWPFDocument();
String pdf = filename;
PdfReader reader = new PdfReader(pdf);
PdfReaderContentParser parser = new PdfReaderContentParser(reader);

After loading of the PDF, we need to read and render each page separately in the loop, and then write to the output file:


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();
FileOutputStream out = new FileOutputStream("src/output/pdf.docx");
// Close all open files

Please note, that with the SimpleTextExtractionStrategy() extraction strategy, we’ll lose all formatting rules. In order to fix it, play with extraction strategies described here, to achieve a more complex solution.


7. PDF to X Commercial Libraries

7.PDF to X商业程序库

In previous sections, we described open source libraries. There are few more libraries worth notice, but they are paid:


  • jPDFImages – jPDFImages can create images from pages in a PDF document and export them as JPEG, TIFF, or PNG images.
  • JPEDAL – JPedal is an actively developed and very capable native Java PDF library SDK used for printing, viewing and conversion of files
  • pdfcrowd – it’s another Web/HTML to PDF and PDF to Web/HTML conversion library, with advanced GUI

8. Conclusion


In this article, we discussed the ways to convert PDF file into various formats.


The full implementation of this tutorial can be found in the GitHub project – this is a Maven-based project. In order to test, just simply run the examples and see the results in the output folder.

本教程的完整实现可以在GitHub项目中找到 – 这是一个基于Maven的项目。为了进行测试,只需简单地运行示例并在output文件夹中看到结果。