I just released the Master Class of "Learn Spring Security":
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.
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:
<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>
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.
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:
<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>
The latest version of iText can be found here and you can look for Apache POI here.
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.
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); output.close(); }
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.
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")); document.open(); XMLWorkerHelper.getInstance().parseXHtml(writer, document, new FileInputStream(filename)); document.close(); }
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.
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); ImageIOUtil.writeImage( bim, String.format("src/output/pdf-%d.%s", page + 1, extension), 300); } document.close(); }
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.
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.
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); writer.open(); document.open(); document.add(Image.getInstance((new URL(input)))); document.close(); writer.close(); }
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.
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")); parser.parse();
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.
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:
PrintWriter pw = new PrintWriter("src/output/pdf.txt"); pw.print(parsedText); pw.close();
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")) .setPdfVersion(PdfWriter.PDF_VERSION_1_7); pdfDoc.open();
In the next step, we’ll define the font and also the command that is used to generate new paragraph:
Font myfont = new Font(); myfont.setStyle(Font.NORMAL); myfont.setSize(11); 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); para.setAlignment(Element.ALIGN_JUSTIFIED); pdfDoc.add(para); } pdfDoc.close(); br.close();
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.
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(); run.setText(text); run.addBreak(BreakType.PAGE); } FileOutputStream out = new FileOutputStream("src/output/pdf.docx"); doc.write(out); // 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
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.