Monday, December 20, 2010

Embedding fonts into PDF generated by JasperReports

Today I was creating a report that needed to be exported to PDF. I used the de facto Java standard for when you need a good report: JasperReports (http://jasperforge.org/projects/jasperreports). To make things easier for me, I used the iReport report designer (http://jasperforge.org/projects/ireport), which is a WYSIWYG tool to create JasperReports reports.

I used different fonts, some bold, some regular. The output looked really good in the iReport preview. Then I ran my application and created the PDF. All the fonts and font styles (bold, italic) were gone and had been replaced by one plain font. After googling a bit, I found the cause of the problem: the fonts I used were not embedded in the generated PDF, so they could not be shown correctly.

I will now explain how you can embed fonts in your PDF. The methods described here work on JasperReports 3.7 and greater, so make sure you have a recent version.

There are two methods to embed the fonts in your PDF. Both methods yield the same result, but one method requires the use of iReport. I will first explain the method without iReport, then the method with iReport. If you use iReport, I strongly suggest using the method with iReport, since it is much easier.

1. No iReport (the hard way)


We will use a JasperReports extension, called the simple font extension. This extension registers the necessary fonts with JasperReports so it can embed them in a PDF when needed. The first thing you need to do is to create a file called jasperreports_extension.properties. This file should have the following content (I broke up the lines so they fit the screen, don't do this yourself):


net.sf.jasperreports.extension.registry.factory.fonts=
net.sf.jasperreports.engine.fonts.SimpleFontExtensionsRegistryFactory
net.sf.jasperreports.extension.simple.font.families.myfamily=
fonts/myfamily.xml


Then you'll need a file called myfamily.xml in a fonts folder. This is what the content should look like:

<?xml version="1.0" encoding="UTF-8"?>
<fontFamilies>

<fontFamily name="Arial">
<normal><![CDATA[fonts/arial.ttf]]></normal>
<bold><![CDATA[fonts/arialbd.ttf]]></bold>
<italic><![CDATA[fonts/ariali.ttf]]></italic>
<boldItalic><![CDATA[fonts/arialbi.ttf]]></boldItalic>
<pdfEmbedded><![CDATA[true]]></pdfEmbedded>
</fontFamily>


<fontFamily name="Tahoma">
<normal><![CDATA[fonts/tahoma.ttf]]></normal>
<bold><![CDATA[fonts/tahomabd.ttf]]></bold>
<pdfEmbedded><![CDATA[true]]></pdfEmbedded>
</fontFamily>


</fontFamilies>

As you can see, I embedded two fonts here: Arial and Tahoma. Arial has a regular, bold and italic variant, while Tahoma lacks the italic variant. I set both pdfEmbedded to true, to make sure they get embedded into pdfs. You will of course also have to copy the ttf files to the fonts directory you created earlier. You will have to locate the ttf files on your harddisk. For windows, they are located in \windows\fonts.

Now all you need to do is add all the files we created and copied to the classpath of your application. To sum it up, you'll have the following files on your classpath:
  • jasperreports_extension.properties: This file needs to go in the root of your classpath (so not in a package). It will be automatically picked up by JasperReports.
  • fonts/myfamily.xml: The xml file defining the fonts. It should be named as you declared it in the .properties file.
  • fonts/*.ttf: All the ttf files you reference in your xml file


2. Using iReport (the easy way)


Everything we did in the first method can be automated using iReport. The first thing you need to do is make sure the all the fonts you used in your report have been defined in iReport. You can do this by starting iReport and going to Tools -> Options -> iReport -> Fonts. You will see the following window:



If the fonts you used are not yet installed (they probably aren't), you'll need to install them. Click the "Install Font" button. A wizard will pop up, asking you the font name and the location of the ttf files. Just direct the application to the location of the ttf files (for windows systems this is generally in the \windows\fonts folder). Make sure to check the "Embed this font in PDF" checkbox on the second page! All other settings can be left at their defaults. Once all the fonts are installed, you select all the fonts you used in your report (hold ctrl to select multiple entries from the list). Then you click the "Export as extension" button. This will create a jar file. All you need to do is add the created jar file to the classpath of your application and you're done!