How to generate PDFs in Java using iText

written by Răzvan Puiu


In this article we'll see how to create and manipulate a PDF document in Java using the iText library.


First, you have to add the iText Maven dependency:

<dependency>
 <groupId>com.itextpdf</groupId>
 <artifactId>itextpdf</artifactId>
 <version>5.5.13.1</version> <!-- For the latest version go HERE: -->
</dependency>

Insert text block:

The following code snippet will insert "Hello getPDFapi!" text in the hello-world.pdf file.

import com.itextpdf.text.Document;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.DocumentException;

Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream("hello-world.pdf"));
document.open();
Chunk chunk = new Chunk("Hello getPDFapi!");
document.add(chunk);
document.close();

In iText, the Document class is used to represent a PDF. Once the document is created, you can add some meta-information or set the headers/footers, but before writing any content, the document must be opened and once the document is opened, you cannot add meta-information anymore.

All the components of which a Document is composed need to implement the Element interface. The simplest component that implements the Element interface is called Chunk which is the smallest significant part of text that can be added to a Document.

To add a font to a chunk, you have to first create it as follows: Font font = FontFactory.getFont(FontFactory.HELVETICA, 32, BaseColor.RED); and then pass it to the chunk constructor: Chunk chunk = new Chunk("Hello getPDFapi!", font);

After closing the document, every listener (as well as its OutputStream) is closed too.

Place text at specific position in the document:

Unfortunately I couldn't find an easy way to place the text at an absolute position in iText 5, but it's not impossible though.

1: Wrap your text in a simple column

PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("hello-world.pdf"));
PdfContentByte cb = writer.getDirectContent();
ColumnText ct = new ColumnText(cb);
Phrase myText = new Phrase("Hello World! \n Hello new line!");
ct.setSimpleColumn(myText, 250, 400, 580, 317, 15, Element.ALIGN_CENTER);
ct.go();


PdfContentByte is a class that contains positioned text and graphic contents of a page. By calling getDirectContent() we retrieve the content of the current document. There is only 1 instance of this content, so calling this method multiple times will yield the same result

ColumnText formats the text in a columnwise form. The text is bound on the left and on the right by a sequence of lines and the column can have any shape. By calling setSimpleColumn() we create a rectangular column that contains "myText". The parameters represent (in order):

  • the phrase
  • lower left x corner
  • lower left y corner
  • upper right x corner
  • upper right y corner
  • the leading
  • the column alignment

The go() method outputs the changes to the document.


2: Directly manipulate the text matrix

cb.beginText();
BaseFont baseFont = BaseFont.createFont(BaseFont.TIMES_ROMAN, "Cp1252", false);
cb.setFontAndSize(baseFont, 6);
cb.setTextMatrix(475, 15);
cb.showText("Hello text matrix!");
cb.endText();

You will still need the PdfContentByte, but now instead of wrapping in a ColumnText, you can directly set the absolute position on the text matrix. First you need to inform the PdfContentByte that you want to start writing text. This is achieved with cb.beginText();. Then, it is mandatory to set the font and the size. I create a 'Times New Roman' BaseFont with the Cp1252 encoding and the embeded parameter set to false, and I set the font size to 6.

Then I set the positions in the text matrix. The text matrix is like an XY graph with 0,0 being in the bottom left of the page. The setTextMatrix() is overloaded to support different kinds of positioning. Make sure you check the implementation if you're comfortable with math :)

In the last 2 lines the text is displayed in the document and the writing is ended.

3: iText 7's Paragraph

import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.Document;

PdfDocument pdf = new PdfDocument(new PdfWriter(dest));
Document document = new Document(pdf);
Paragraph p = new Paragraph();
p.setFixedPosition(150, 500, 80)
p.add("Hello iText 7"));
document.add(p);

In iText 7 adding a text at a fixed position is fairly easy. You just need to call setFixedPosition() on a paragraph and pass the X (150), Y (500) and width (80) parameters then add the Paragraph to the document


Insert image at a specific position:
String filename = "path/to/getPdfApi.png";
Image image = Image.getInstance(filename);
image.setAbsolutePosition(0f, 0f);
document.add(image);

To position an image in your pdf document, you simply need to create an instance of Image, set the absoulute position on the XY axis and add the image to the document.

Insert table
import com.itextpdf.text.pdf.PdfPTable;
PdfPTable table = new PdfPTable(4);
for(int aw = 0; aw < 16; aw++){
table.addCell("Hello Table!");
}
document.add(table);

The code above will create a 4x4 table and attach it to the document in iText5.

PdfPCell cell = new PdfPCell(new Phrase("Hello large celL!")); cell.setFixedHeight(50); table.addCell(cell);

You can create custom cells and add them to the table. Notice that by setting the fixed height of the custom cell, all the other cells in the row will be resized.

Creating a PDF file in Java using iText is quite straight forward, but wouldn't it be even better if you would only have to worry about the contents of your PDF and let us handle the code?