Reputation: 1596
I'm applying header on a pdf/a document
I embed my font in document, no problem if I have hundreds of page, in pdf created I see just one font embedded in document properties.
Now I worked on adding an header using canvas as seen in many examples.
At first it throw error because it says font must be embedded.
When I embed the font it works, but in document properties I see the font repeated for every page.
So the document kb size grows a lot.
I want font embedded just one time.
Spring boot, but i think it does not matter.
The code of header:
@Slf4j
public class Header implements IEventHandler {
private IFontProviderService fontProviderService;
private String logoPath;
private String header;
private List<String> subHeaders;
public Header(IFontProviderService fontProviderService, String logoPath, String header, List<String> subHeaders) {
this.fontProviderService = fontProviderService;
this.header = header;
this.subHeaders = subHeaders;
this.logoPath = logoPath;
}
@Override
public void handleEvent(Event event) {
try {
PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
PdfDocument pdf = docEvent.getDocument();
PdfPage page = docEvent.getPage();
PdfDictionary pdfObject = page.getPdfObject();
PdfCanvas headerPdfCanvas = new PdfCanvas(page.newContentStreamBefore(), page.getResources(), pdf);
Rectangle headerRect = new Rectangle(35, 740, 495, 96);
Canvas headerCanvas = new Canvas(headerPdfCanvas, headerRect);
headerCanvas.setFont(fontProviderService.getDefaultPdfFont());
headerCanvas.enableAutoTagging(page);
CreateHeaderContent(headerCanvas);
headerCanvas.close();
} catch (Exception e) {
log.error("Error in header settings.", e);
}
}
private void CreateHeaderContent(Canvas canvas) throws MalformedURLException {
Table table = new Table(UnitValue.createPercentArray(new float[] { 80, 20 }));
table.setWidth(UnitValue.createPercentValue(100));
Cell cell1 = new Cell().add(new Paragraph(header).setBold().setFontSize(11).setTextAlignment(TextAlignment.LEFT));
for (int i = 0; i < subHeaders.size(); i++) {
cell1.add(new Paragraph(subHeaders.get(i)).setFontSize(8).setTextAlignment(TextAlignment.LEFT));
}
cell1.setBorder(Border.NO_BORDER);
table.addCell(cell1);
ImageData imageData = ImageDataFactory.create(logoPath);
Image image = new Image(imageData);
image.getAccessibilityProperties().setAlternateDescription("...");
Cell cell2 = new Cell().add(image.setTextAlignment(TextAlignment.RIGHT));
cell2.setBorder(Border.NO_BORDER);
cell2.setVerticalAlignment(VerticalAlignment.MIDDLE);
table.addCell(cell2);
canvas.add(table);
}
}
@Slf4j
@Service
public class FontProviderService implements IFontProviderService {
@Value("${pdf.resources.external.path}")
private String staticResourcesPath;
@Override
public FontProvider getFontProvider() throws IOException {
FontProvider fontProvider = new FontProvider("DMSans-Regular");
fontProvider.addFont(FontProgramFactory.createFont(staticResourcesPath + "pdf/fonts/DMSans-Regular.ttf"));
fontProvider.addFont(FontProgramFactory.createFont(staticResourcesPath + "pdf/fonts/DMSans-Bold.ttf"));
fontProvider.addFont(FontProgramFactory.createFont(staticResourcesPath + "pdf/fonts/DMSans-Italic.ttf"));
fontProvider.addFont(FontProgramFactory.createFont(staticResourcesPath + "pdf/fonts/DMSans-BoldItalic.ttf"));
fontProvider.addFont(FontProgramFactory.createFont(staticResourcesPath + "pdf/fonts/DMSans-Medium.ttf"));
fontProvider.addFont(FontProgramFactory.createFont(staticResourcesPath + "pdf/fonts/DMSans-MediumItalic.ttf"));
return fontProvider;
}
@Override
public PdfFont getDefaultPdfFont() throws IOException {
String defaultFontFamily = this.getFontProvider().getDefaultFontFamily();
Collection<FontInfo> fonts = this.getFontProvider().getFontSet().getFonts();
FontInfo fontInfo = fonts.stream().filter(f -> f.getFontName().equals(defaultFontFamily)).findFirst().get();
PdfFont pdfFont = this.getFontProvider().getPdfFont(fontInfo);
return pdfFont;
}
}
Upvotes: 2
Views: 475
Reputation: 1596
...Spring had something to do with it in some way ...at least in the manner i wrote the service...
Well... Actually in my case the problem was just how I used the service sprint to retrieve the fontProvider and the font.
I'm passing to my handler the entire fontProviderService:
public Header(IFontProviderService fontProviderService, String logoPath, String header, List<String> subHeaders)
and calling every time:
headerCanvas.setFont(fontProviderService.getDefaultPdfFont());
That's equal to create every time a new provider:
FontProvider fontProvider = new FontProvider("DMSans-Regular");
The point to focus is that the FontProvider object and the PdfFont objects must be always the same
So modified my Handler like this:
@Slf4j
public class Header implements IEventHandler {
private FontProvider fontProvider;
private PdfFont pdfFont;
private String logoPath;
private String header;
private List<String> subHeaders;
public Header(FontProvider fontProvider, PdfFont pdfFont, String logoPath, String header, List<String> subHeaders) {
this.fontProvider = fontProvider;
this.pdfFont = pdfFont;
this.header = header;
this.subHeaders = subHeaders;
this.logoPath = logoPath;
}
@Override
public void handleEvent(Event event) {
try {
PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
PdfDocument pdf = docEvent.getDocument();
PdfPage page = docEvent.getPage();
PdfDictionary pdfObject = page.getPdfObject();
PdfCanvas headerPdfCanvas = new PdfCanvas(page.newContentStreamBefore(), page.getResources(), pdf);
Rectangle headerRect = new Rectangle(35, 740, 495, 96);
Canvas headerCanvas = new Canvas(headerPdfCanvas, headerRect);
headerCanvas.setFontProvider(fontProvider);
headerCanvas.setFont(pdfFont);
headerCanvas.enableAutoTagging(page);
CreateHeaderContent(headerCanvas);
headerCanvas.close();
} catch (Exception e) {
log.error("Error in header settings.", e);
}
}
private void CreateHeaderContent(Canvas canvas) throws MalformedURLException {
Table table = new Table(UnitValue.createPercentArray(new float[] { 80, 20 }));
table.setWidth(UnitValue.createPercentValue(100));
Cell cell1 = new Cell().add(new Paragraph(header).setBold().setFontSize(11).setTextAlignment(TextAlignment.LEFT));
for (int i = 0; i < subHeaders.size(); i++) {
cell1.add(new Paragraph(subHeaders.get(i)).setFontSize(8).setTextAlignment(TextAlignment.LEFT));
}
cell1.setBorder(Border.NO_BORDER);
table.addCell(cell1);
ImageData imageData = ImageDataFactory.create(logoPath);
Image image = new Image(imageData);
image.getAccessibilityProperties().setAlternateDescription("...");
Cell cell2 = new Cell().add(image.setTextAlignment(TextAlignment.RIGHT));
cell2.setBorder(Border.NO_BORDER);
cell2.setVerticalAlignment(VerticalAlignment.MIDDLE);
table.addCell(cell2);
canvas.add(table);
}
}
Just for complete, I removed the getDefaultFont from Service and this is an extract of the pdf creator calling the Handler:
FontProvider fontProvider = fontProviderService.getFontProvider();
String defaultFontFamily = fontProvider.getDefaultFontFamily();
Collection<FontInfo> fonts = fontProvider.getFontSet().getFonts();
FontInfo fontInfo = fonts.stream().filter(f -> f.getFontName().equals(defaultFontFamily)).findFirst().get();
PdfFont defaultPdfFont = fontProvider.getPdfFont(fontInfo);
...
converterProperties.setFontProvider(fontProvider);
Header headerHandler = new Header(fontProvider, defaultPdfFont, staticResourcesPath + "....png", "...", "...");
pdf.addEventHandler(PdfDocumentEvent.START_PAGE, headerHandler);
Upvotes: 0