Reputation: 85
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.
Upvotes: 1
Views: 2090
Reputation: 12312
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);
}
Upvotes: 3