How to define a default font to create a PDF with a PdfPTable and the PdfAWriter class from iText 5.3.3 library

alain carette picture alain carette · Nov 23, 2012 · Viewed 10.2k times · Source

I'm working with the library iText 5.3.3 and i wan't to create a PDF with the class PdfAWriter which needs to specify which compliancelevel must be respected.

I wan't to add a PdfPTable to my document but i don't manage to do it cause of this error : "All the fonts must be embedded. This one isn't: Helvetica".

I think that this problem is due to the fact that we have to embed the fonts we use when we want to make PDF with PDFAConformanceLevel ; and it's what i did but in some case it seems that a default font is used : Helvetica, and this default font is not embedded and cannot be embedded ! This happen when we add new lines, empty lines, new page, or when we work with elements like PdfPTable.

I think it must be a way to define the default font to use when we work with elements like PdfPTable ; i heard that someone manage to do this by defining a new Chunk constructor, but i don't know how to do.... Some one has an idea ?

Here you can find my code... i have simplified it for the purpose :

I define 2 embedded fonts with this code :

FontFactory.register("c:/NewYorker.ttf");
baseFont = (FontFactory.getFont("new yorker","UTF-8",BaseFont.EMBEDDED)).getBaseFont();
baseFont.setSubset(true);
BOLD = new Font(timesbd, 12);
NORMAL = new Font(times, 12);

And i use these fonts to add 3 paragraphs in 3 cells to put in one table :

Document document = new Document();
PdfAWriter writer = PdfAWriter.getInstance(document, new FileOutputStream(filename), PdfAConformanceLevel.PDF_A_1B);
document.open();

float[] columnWidths = { 3.5f, 4.5f, 2.8f };
PdfPTable table = new PdfPTable(columnWidths);

PdfPCell defaultCell = table.getDefaultCell();
defaultCell.setPhrase(new Phrase("",NORMAL)); 

table.setWidthPercentage(90);
table.setHorizontalAlignment(Element.ALIGN_RIGHT);

PdfPCell cell1 = new PdfPCell(new Phrase("test 1",BOLD));
PdfPCell cell2 = new PdfPCell(new Phrase("test 2",NORMAL));
PdfPCell cell3 = new PdfPCell(new Phrase("test 3",NORMAL));

cell1.setBorder(0);
cell2.setBorder(0);
cell3.setBorder(0);

cell1.setIndent(27);
cell2.setIndent(27);
cell3.setIndent(27);

cell1.setLeading(4.5f, 1);
cell2.setLeading(4.5f, 1);
cell3.setLeading(4.5f, 1);

table.addCell(cell1);
table.addCell(cell2);
table.addCell(cell3);

document.add(table);

document.close();

And i have this stack when i execute my code :

Exception in thread "main" com.itextpdf.text.DocumentException: com.itextpdf.text.pdf.PdfAConformanceException: All the fonts must be embedded. This one isn't: Helvetica
at com.itextpdf.text.pdf.PdfDocument.add(PdfDocument.java:708)
at com.itextpdf.text.Document.add(Document.java:260)
at test.MainClass.createPdfA(MainClass.java:163)
at test.MainClass.main(MainClass.java:68)

Answer

Bruno Lowagie picture Bruno Lowagie · Nov 23, 2012

There are different errors in your code, and the font isn't the biggest problem.

I copy/pasted your code as good as possible: http://itextsupport.com/files/stackoverflow/PdfATest.java

  • I had to change the font because I don't have NewYorker.ttf on my PC.
  • I didn't embed the complete font; that seemed like overkill.
  • I added a line to create the XMP data (this is mandatory in PDF/A).
  • I added a color profile (also mandatory; I chose sRGB).

I ran the code and it didn't throw any exception. You can check the result for yourself: http://itextsupport.com/files/stackoverflow/pdfa.pdf

Of course: don't trust Adobe Reader if you see a blue bar saying this is PDF/A1b. You need to check the conformance in a Preflight tool as is done in the image shown below: enter image description here

My guess:

  • Maybe your assumption that "new yorker" is the actual PostScript name of the font is wrong.
  • Why are you using "UTF-8" as encoding. The documentation clearly says you need to use Identity-H if you want to use Unicode.

I can't reproduce your problem, so I suggest you try running my code.