Generating PDF Files Using Java
- 8 minsA step by step tutorial on how to generate PDF files in Java.
Intro
In my previous post, I have started describing a system for “checking-in” to a location using QR codes in Java. Now, I would like to describe another part of that system that will show you how to get started with generating PDF files using Java.
So, let’s have a look at how this can be implemented in your solution – step by step.
Choosing a Library
Generating PDFs is normally something you would like to do using 3rd party libraries, and there are quite a few alternatives available. While choosing a library it might be a good idea to have a closer look at the licensing for that library – some of them might be very permissive and some might force your code to comply to a specific licensing. Some libraries even come with dual licensing, one under a proprietary model and one supporting an open source model.
One should also consider other aspects like maturity and whether it is a high- or low-level library. The latter will tell you how much code you will actually end up writing to implement your features. In the course of this project, I ended up trying two different libraries – iText and, later, Apache PDFBox. Since the point of this code was a tutorial, I decided to stick with PDFBox as it is distributed under more permissive license – Apache License 2.0, as opposed to dual licensed iText that is under AGPL and a commercial license.
Generating PDF Files
As mentioned earlier, this library provides quite extensive functionality for generating PDF files, but it is also quite low-level, so you will have to be prepared to implement a few things you might usually take for granted, e.g. things like calculating coordinates for text that has to be centered on a page and a few other things. However, the library has a great community, so it is quite easy to get help.
Adding Maven Dependency
Ok, let’s get started. First things first, you will need to add the following dependencies to your pom.xml
to use PDFBox (assuming you are using Maven to build your project):
Getting Started With the Code
For this post, I decided to paste the source code for the whole function doing the PDF generation and separate it with a few sentences, explaining the most interesting parts of the code. You can always piece the code together, or just have a look at the code in my repo. (Bonus: If you are interested in how much work it was to port the code from iText to PDFBox, this commit should give you a rough idea.)
We start with defining a document object, a page object and add a page to a document. Afterwards, we create a content stream object that will be added to the page and document objects. This object will be responsible for holding the text and images we will be generating here.
Adding Text
Now we will need to calculate the coordinates for the header text string and make sure it will appear centered independent of the font and size. This is one of the “low-level” parts you will have to deal with when using PDFBox.
Next, we will be adding the text itself and setting font and coordinates for it on the page:
Adding Images
Now, let’s examine how to add an image to a PDF document. Here, you can use createFromFile()
in case your image is already available, or createFromImage()
is you are generating the image on the fly and/or returning it from another function.
Below, you will also find examples of code to scale and to calculate coordinates for centering the image:
Adding Metadata to the Document
Here, you can see a few examples of how you can add metadata to your document. This is done with a help of a few methods available thought the API:
Closing, Saving and Returning the Document
After your document is built and you have added all the contents, remember to save and close your document. Now you can either save the document to the file with document.save()
, or returning the document as a byte array to another function with byteArrayOutputStream.toByteArray()
:
What Now?
In the last two posts, we have seen how to generate QR codes with a hashed string and PDF files with Java. In the next post, I will be showing how to put it all together into a MicroProfile microservice.