繁体   English   中英

itext7 只为 pdfa 在标题中嵌入字体 1 次

[英]itext7 embed font in header just 1 time for pdfa

我在 pdf/a 文档上应用标题

我将我的字体嵌入到文档中,如果我有数百页也没问题,在创建的 pdf 中,我只看到一种嵌入在文档属性中的字体。

现在我使用画布添加标题,如许多示例所示。

起初它抛出错误,因为它说必须嵌入字体。

当我嵌入字体时,它可以工作,但在文档属性中,我看到每个页面都重复使用该字体。

所以文档 kb 大小增长了很多。

我只想嵌入一次字体。

Spring boot,不过我觉得没关系。

标头代码:

@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;
    }

}

...Spring 以某种方式与它有关 ...至少在我编写服务的方式方面...

嗯...实际上在我的情况下,问题只是我如何使用服务冲刺来检索 fontProvider 和字体。

我将整个 fontProviderService 传递给我的处理程序:

public Header(IFontProviderService fontProviderService, String logoPath, String header, List<String> subHeaders)

并且每次都打电话:

headerCanvas.setFont(fontProviderService.getDefaultPdfFont());

这相当于每次创建一个新的提供者:

FontProvider fontProvider = new FontProvider("DMSans-Regular");

重点是 FontProvider 对象和 PdfFont 对象必须始终相同

所以像这样修改了我的处理程序:

@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);
    }
}

为了完整起见,我从 Service 中删除了 getDefaultFont,这是调用 Handler 的 pdf 创建者的摘录:

    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);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM