I have been trying to write HTML into a PDF/A compliant PDF for a while. I'm using the following libraries :
- itext-pdfa-5.5.12
- itextpdf-5.5.12
- xmlworker-5.5.12
The following error seems to appear on a regular basis :
Exception in thread "main" com.itextpdf.text.pdf.PdfAConformanceException: All the fonts must be embedded. This one isn't: Helvetica
The message seems to be, in some cases, misleading. My code is very similar to another post. The key line is commented in code.
- When commented, I got an exception about a missing Helvetica font.
- When uncommented, the program executes without exception.
In the generated PDF file, I can see a single embedded font (ArialMT). I find the exception message quite odd but I cannot figure out why Helvetica appears when only Arial is used. Is this an issue (bug) or did I miss something ?
public class BugFontExceptionDemo {
public static void main(String[] args) {
StringBuffer buf = new StringBuffer();
buf.append("<body>");
buf.append("<h1 style=\"font-family:arial\">Text in arial</h1>");
buf.append("</body>");
OutputStream file = null;
Document document = null;
PdfAWriter writer = null;
try {
file = new FileOutputStream(
new File("C:\\Users\\Emilien\\PROJECTS_FILES\\PROJECT_EXPORT_TEST\\PDF_A_HTML_WORKING.pdf"));
document = new Document();
writer = PdfAWriter.getInstance(document, file, PdfAConformanceLevel.PDF_A_1B);
document.addTitle("Test document");
writer.createXmpMetadata();
document.open();
ICC_Profile icc = ICC_Profile.getInstance(new FileInputStream(
"C:\\Users\\Emilien\\PROJECTS_FILES\\PROJECT_EXPORT_TEST\\sRGB_CS_profile.icm"));
writer.setOutputIntents("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", icc);
CSSResolver cssResolver = new StyleAttrCSSResolver();
CssFile cssFile = XMLWorkerHelper.getCSS(new FileInputStream("./css/style.css"));
cssResolver.addCss(cssFile);
MyFontProvider fontProvider = new MyFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
// fontProvider.register("./fonts/arial.ttf");
CssAppliers cssAppliers = new CssAppliersImpl(fontProvider);
HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);
htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
PdfWriterPipeline pdf = new PdfWriterPipeline(document, writer);
HtmlPipeline html = new HtmlPipeline(htmlContext, pdf);
CssResolverPipeline css = new CssResolverPipeline(cssResolver, html);
XMLWorker worker = new XMLWorker(css, true);
XMLParser p = new XMLParser(worker);
Reader reader = new StringReader(buf.toString());
p.parse(reader);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (document != null && document.isOpen())
document.close();
try {
if (file != null)
file.close();
} catch (IOException e) {
}
if (writer != null && !writer.isCloseStream())
writer.close();
}
}
}
public static class MyFontProvider extends XMLWorkerFontProvider {
public MyFontProvider(String path) {
super(path);
}
@Override
public Font getFont(final String fontname, String encoding, float size, final int style) {
System.out.println("registered: " + isRegistered(fontname) + " fontname: " + fontname + " encoding: "
+ encoding + " size: " + size + " style: " + style);
Font font = super.getFont(fontname, encoding, size, style);
return font;
}
@Override
public Font getFont(String fontname, String encoding, boolean embedded, float size, int style,
BaseColor color) {
System.out.println("registered: " + isRegistered(fontname) + " fontname: " + fontname + " encoding: "
+ encoding + " embedded : " + embedded + " size: " + size + " style: " + style + " BaseColor: "
+ color);
Font font = super.getFont(fontname, encoding, embedded, size, style, color);
return font;
}
}