0
votes

I'm using iText 7 with Html2Pdf to convert Html elements inside cells of table to PDF.
For each cell that contains Html string I use this code:

ConverterProperties converterProperties = new ConverterProperties();
converterProperties.setOutlineHandler(new OutlineHandler());
converterProperties.setFontProvider(document.getFontProvider());

List<IElement> convertToElements = HtmlConverter.convertToElements(cellValue, converterProperties);
Paragraph p = (Paragraph)convertToElements.get(0);
cell.add(p);

The file contains other data as well but only this code adds duplicate of the font. (Link to example here). In the example above I added 1 <b> tag to specific cell. The Document object has the regular DejaVu font as it's default and the bold is inside the FontProvider.

Edit:
This is how I set the fonts to the document: Regular font -

pdfFont = PdfFontFactory.createFont(fontPath, PdfEncodings.IDENTITY_H, true);
document.setFont(pdfFont);

Bold font - (code from getBoldFont method)

FontProvider fontProvider = document.getFontProvider();

PdfFont createFont = null;
if (fontProvider == null) {
   fontProvider = new FontProvider();
   document.setFontProvider(fontProvider);
}
Collection<FontInfo> collection = fontProvider.getFontSet().get(boldFontName);
if (collection.isEmpty()) {
    createFont = PdfFontFactory.createFont(boldFontPath, PdfEncodings.IDENTITY_H, true);
    fontProvider.addFont(createFont.getFontProgram());

    // I need to call this part again because iText creates the font again
    // and in this way I eliminate another duplication of the font.
    collection = fontProvider.getFontSet().get(boldFontName);
    createFont = fontProvider.getPdfFont(collection.iterator().next());
    return createFont;
} else {
    return fontProvider.getPdfFont(collection.iterator().next());
}

As for how I "add resultant elements to the document", I use document#add and canvas#showTextAligned.

My question is why I get the bold font more than once if I keep using the same font (I use getBoldFont when needed) when need to convert Html to PDF and how to solve it.

Thank you in advance.

1
Hi, can you attach the more complete version of your code, namely how you create and set the font provider as well as add resultant elements to the document, and clarify what your question exactly is?Alexey Subach
Thank you for your answer. I've edited my question and added some code.Michael Azarzar

1 Answers

2
votes

In your use case iText indeed creates multiple instances of the same font and those instances end up in your resultant document. This redundancy is a byproduct of safety for other use cases, e.g. when the result of the call to HtmlConverter.convertToElements is added to multiple documents. However, it is very easy to overcome this problem.

pdfHTML sets the font provider as one of the properties to its resultant elements. You can set the font provider directly, overwriting that property value. Thus the cache will not be reset anymore. You can set the font provider to an element with the following piece of the code:

p.setProperty(Property.FONT_PROVIDER, fontProvider);

Also, you don't have to pass any converter properties to your HtmlConverter in this case. Just use that font provider to set it on the resultant elements. Here is the minimal code snipped demonstrating how to get rid of font duplication:

FontProvider fontProvider = new FontProvider("Arial");
fontProvider.addFont("C:/Windows/Fonts/arial.ttf");
fontProvider.addFont("C:/Windows/Fonts/arialbd.ttf");

Document document = new Document(pdfDocument);
document.setFontProvider(fontProvider);

for (int i = 0; i < 10; i++) {
    List<IElement> convertToElements = HtmlConverter.convertToElements(html);
    Paragraph p = (Paragraph) convertToElements.get(0);
    p.setProperty(Property.FONT_PROVIDER, fontProvider);
    document.add(p);
}