iText html2pdf 从 HTML 转换后 PDF 中标签的可视化问题

Posted

技术标签:

【中文标题】iText html2pdf 从 HTML 转换后 PDF 中标签的可视化问题【英文标题】:iText html2pdf Issue with visualization of label in PDF after conversion from HTML 【发布时间】:2018-10-01 08:20:11 【问题描述】:

我用:

html2pdf v2.0.1 iText 7.1.1

在我的 HTML 中,我有以下标签,它占据了页面的整个宽度:

<label class="test">Patient</label>

这是我的 CSS:

.test 
    display: block;
    font-weight: bold;
    color: #009fd1;
    font-size: .6em;
    text-align: left;
    padding: 0.5rem;
    background: #085a9f;
    border-radius: 3px;
 

当我使用 iText 将 HTML 转换为 PDF 时,我的标签显示如下:

在我看来,除了display: blockborder-radius: 3px 之外,他所做的一切都是正确的

这是 iText 中的问题吗?

为了完整,这是我的转换代码:

    public ByteArrayOutputStream createPdf(String html) throws IOException 
    ByteArrayOutputStream baos = null;
    html = replaceStylesheet(html);
    try 
        baos = new ByteArrayOutputStream();
        WriterProperties writerProperties = new WriterProperties();
        //Add metadata
        writerProperties.addXmpMetadata();
        PdfWriter pdfWriter = new PdfWriter(baos, writerProperties);

        PdfDocument pdfDoc = new PdfDocument(pdfWriter);
        PageSize pageSize = PageSize.A4;
        pdfDoc.setDefaultPageSize(pageSize);
        pdfDoc.getCatalog().setLang(new PdfString("en-US"));
        //Set the document to be tagged
        pdfDoc.setTagged();
        PdfViewerPreferences pdfViewerPreferences = new PdfViewerPreferences();
        pdfViewerPreferences.setDisplayDocTitle(true);
        pdfDoc.getCatalog().setViewerPreferences(pdfViewerPreferences);

        //Create event-handlers
        String header = "© 2018 Generated by OpenNCP Portal";
        Header headerHandler = new Header(header);
        PageXofY footerHandler = new PageXofY(pdfDoc);

        //Assign event-handlers
        pdfDoc.addEventHandler(PdfDocumentEvent.START_PAGE,headerHandler);
        pdfDoc.addEventHandler(PdfDocumentEvent.END_PAGE,footerHandler);

        // pdf conversion
        ConverterProperties props = new ConverterProperties();
        FontProvider dfp = new DefaultFontProvider(true, false, false);

        props.setFontProvider(dfp);

        HtmlConverter.convertToDocument(html, pdfDoc, props);
        footerHandler.writeTotal(pdfDoc);
        pdfDoc.close();
     catch (Exception e) 
        LOGGER.error("Error occurred when converting HTML to PDF", e);
    
    return baos;

【问题讨论】:

【参考方案1】:

确实,这是当前版本的 iText 中的问题,您的假设是正确的。

有两个不同的问题,第一个是在 pdfHTML 中 display:block 不支持 label 元素,而是默认为 inline。 但是,对于label,支持display:block 似乎相当容易,您只需像这样扩展DefaultTagWorkerFactoryDefaultCssApplierFactory

private static class LabelBlockTagWorkerFactory extends DefaultTagWorkerFactory 
    @Override
    public ITagWorker getCustomTagWorker(IElementNode tag, ProcessorContext context) 
        if (!TagConstants.LABEL.equals(tag.name())) 
            return null;
        
        String display;
        if (tag.getStyles() == null || (display = tag.getStyles().get(CssConstants.DISPLAY)) == null) 
            return null;
        
        if (CssConstants.BLOCK.equals(display)) 
            return new DivTagWorker(tag, context);
        
        return null;
    



private static class LabelBlockCssApplierFactory extends DefaultCssApplierFactory 
    @Override
    public ICssApplier getCustomCssApplier(IElementNode tag) 
        if (!TagConstants.LABEL.equals(tag.name())) 
            return null;
        
        String display;
        if (tag.getStyles() == null || (display = tag.getStyles().get(CssConstants.DISPLAY)) == null) 
            return null;
        
        if (CssConstants.BLOCK.equals(display)) 
            return new BlockCssApplier();
        
        return null;
    

然后你可以在ConverterProperties中设置它们:

props.setTagWorkerFactory(new LabelBlockTagWorkerFactory());
props.setCssApplierFactory(new LabelBlockCssApplierFactory());

第二个问题是border-radius 属性对内联元素背景的支持。它实际上是当前 iText 中的一个错误,修复起来并不容易,但是它对块元素工作正常,所以在您解决 display:block 问题后,它现在不应该成为您的问题。

【讨论】:

以上是关于iText html2pdf 从 HTML 转换后 PDF 中标签的可视化问题的主要内容,如果未能解决你的问题,请参考以下文章

iText7高级教程之html2pdf——1.从Hello HTML开始

iText7高级教程之html2pdf——0.引言

iText7高级教程之html2pdf——6.在pdfHTML中使用字体

iText7高级教程之html2pdf——6.在pdfHTML中使用字体

iText7高级教程之html2pdf——5.自定义标签和CSS应用

iText7高级教程之html2pdf——4.使用pdfHTML创建报告