PDFBox customize page size, adding images and custom fonts

PDFBox customize page size, adding images and custom fonts

In this article, we will look at some of the features offered by Apache PDFBox. In the real world, documents created using PDF libraries may require an additional feature of setting custom page size. Fortunately, PDFBox comes with API to specify page size as per standard units referred in a day to day business. The page sizes are A0, A1, …, A6, LEGAL, and LETTER.


public class PageSize {
  /**
   * Creates PDF with different page size.
   *
   * @param args
   * @throws Exception
   */
public static void main(String[] args) throws Exception {
  PDDocument pdfDoc = new PDDocument();

  PDPage page = createPage(PDRectangle.A0);
  pdfDoc.addPage(page);
  writeTextToPage(pdfDoc, page, "A0");

  page = createPage(PDRectangle.A1);
  pdfDoc.addPage(page);
  writeTextToPage(pdfDoc, page, "A1");

  page = createPage(PDRectangle.A2);
  pdfDoc.addPage(page);
  writeTextToPage(pdfDoc, page, "A2");

  page = createPage(PDRectangle.A3);
  pdfDoc.addPage(page);
  writeTextToPage(pdfDoc, page, "A3");

  page = createPage(PDRectangle.A4);
  pdfDoc.addPage(page);
  writeTextToPage(pdfDoc, page, "A4");

  page = createPage(PDRectangle.A5);
  pdfDoc.addPage(page);
  writeTextToPage(pdfDoc, page, "A5");

  page = createPage(PDRectangle.A6);
  pdfDoc.addPage(page);
  writeTextToPage(pdfDoc, page, "A6");

  page = createPage(PDRectangle.LEGAL);
  pdfDoc.addPage(page);
  writeTextToPage(pdfDoc, page, "LEGAL");

  page = createPage(PDRectangle.LETTER);
  pdfDoc.addPage(page);
  writeTextToPage(pdfDoc, page, "LETTER");

  pdfDoc.save("d:/temp/page_size.pdf");
  pdfDoc.close();
  }
  /**
   * Creates new page with specified size.
   *
   * @param size Size for new page.
   * @return Returns page instance.
   */
  private static PDPage createPage(PDRectangle size) {
    return new PDPage(size);
  }
  /**
   * Writes given text to PDF page.
   *
   * @param pdfDoc An instance of PDF Document.
   * @param page   An instance of PDF Page.
   * @param text   Text to be written.
   */
  private static void writeTextToPage(PDDocument pdfDoc, PDPage page, String text) throws Exception {
  int textPosition = (int)(page.getBBox().getHeight() * (60f/100f));
  PDPageContentStream stream = new PDPageContentStream(pdfDoc, page);
  stream.beginText();
  stream.setFont(PDType1Font.HELVETICA, 12);
  stream.newLineAtOffset(10, textPosition);
  stream.showText(text);
  stream.endText();
  stream.close();
  }
}

Have a look at the createPage method. It specifies the desired page size while creating the PDPage instance. Also, you will notice that writeTextToPage method calculates offset for text (60% from bottom), based on the size of the page. Since the page dimensions will differ for each page, the calculation is done based on the height retrieved using page.getBBox().getHeight() API.

Images

Apart from the textual content, it is also possible to add images to a PDF page. Apache PDFBox offers convenient APIs to add images and offers support for a wide variety of images including

  • JPG / JPEG
  • TIF / TIFF
  • GIF / BMP / PNG

The easiest way of adding an image to PDF is to use PDImageXObject. The class offers methods createFromFile, createFromFileByExtension and createFromFileByContent etc., to get an image instance either by file path or based on a file extension or automatic determination of the image type.
Refer following code snippet, which adds a .png image to the PDF page.

public class EmbedImage {

 public static void main(String[] args) throws Exception{

  PDDocument pdDoc = new PDDocument();
  PDPage pdPage = addPage();
  pdDoc.addPage(pdPage);

  addImageToPage(pdDoc, pdPage);

  pdDoc.save("d:/temp/pdfWithImage.pdf");

  pdDoc.close();
 }

 private static PDPage addPage(){
  return new PDPage(PDRectangle.A4);
 }

private static void addImageToPage(PDDocument pdDoc, PDPage pdPage) throws Exception{

  PDImageXObject pdImage = PDImageXObject.createFromFile("d:/temp/android.png", pdDoc);

  PDPageContentStream contentStream = new PDPageContentStream(pdDoc, pdPage);

  contentStream.drawImage(pdImage,10,400);

  contentStream.close();
 }
}

Note the addImageToPage method, it constructs an instance of PDImageXObject using PDImageXObject.createFromFile method, which accepts two arguments, file path and an instance of PDDocument.
To add an image, using stream, have a look at the PDImageXObject source code. The code has a lot of hints about using streams and offers convenient API for determining file types. Additionally, the file provides hints about the list of Image formats currently supported by Apache PDFBox.

Embedding Fonts

There might be a need to add text with different font family and size. PDFBox supports few fonts out of the box and also has provision to load custom fonts. As of now, PDFBox supports following fonts

  • Courier
  • Helvetica
  • Times new roman

A font can be configured for text using setFont API available on Content Stream.

PDPageContentStream contentStream = new PDPageContentStream(pdDoc, pdPage);
...
contentStream.setFont(PDType1Font.HELVETICA, 12);
...

Above example uses built-in font for displaying text. In case, if you want to render text using custom font, refer below example.

public class EmbedFont {

 public static void main(String[] args) throws Exception{

  PDDocument pdDoc = new PDDocument();

  PDPage pdPage = new PDPage(PDRectangle.A4);
  addText(pdPage, pdDoc);
  pdDoc.addPage(pdPage);

  pdDoc.save("d:/temp/with_font_pdf.pdf");

  pdDoc.close();
 }

 private static void addText(PDPage pdPage, PDDocument pdDoc) throws IOException {

  PDPageContentStream contentStream = new PDPageContentStream(pdDoc, pdPage);

  contentStream.beginText();
  contentStream.newLineAtOffset(10, 500);
  contentStream.setFont(getFont(pdDoc),12);
  contentStream.showText("Hello World!!!");
  contentStream.endText();
  contentStream.close();
 }

 private static PDType0Font getFont(PDDocument pdDocument) throws IOException {

  PDType0Font font = PDType0Font.load(pdDocument, new File("d:/temp/Roboto-Light.ttf"));

  return font;
 }
}
Load custom font for Apache PDFBox

Font is loaded from a file using PDType0Font API.