iText 7 文本注释样式问题

iText 7 text annotation styling issue

使用 中的方法,我能够成功地为特定文本创建文本注释。但是我 运行 使用这种方法遇到了样式问题。

我动态生成的 HTML 有一个带负文本缩进的 p 标签。自定义标签是此 p 标签的子标签。现在的问题是自定义注释标签从它的父级继承了负文本缩进,这使得内容与前面的文本重叠。我试图通过为注释标记添加 0pt 样式来覆盖文本缩进 属性。当我直接在浏览器中打开 HTML 时它工作正常。但 iText 在生成最终输出时不考虑这种样式。请参阅下面的示例。

PDF 输出:

HTML代码

<html>
<meta charset="utf-8">
<title>iText test</title> 
    <head>
        <style type="text/css">
                annot {
                display: inline-block;
                text-indent:0px !important;
            }
        </style> 
    </head> 
    <body>
        <div>
            <p style="margin-left:18pt; text-indent:-18pt; page-break-inside:avoid; page-break-after:avoid; line-height:120%"> The example of <annot> text markup </annot> annotation. </p>
        </div>
    </body>
</html>

Java代码:

public class C05E04_QRCode2 {

/**
 * The path to the resulting PDF file.
 */
public static final String DEST = "C:\dest.pdf";

/**
 * The path to the source HTML file.
 */
public static final String SRC = "C:\source.html";

/**
 * The main method of this example.
 *
 * @param args no arguments are needed to run this example.
 * @throws IOException signals that an I/O exception has occurred.
 */
public static void main(String[] args) throws IOException {
    File file = new File(DEST);
    file.getParentFile().mkdirs();

    C05E04_QRCode2 app = new C05E04_QRCode2();
    System.out.println("pdf");
    app.createPdf(SRC, DEST);
}

/**
 * Creates the PDF file.
 *
 * @param src  the path to the source HTML file
 * @param dest the path to the resulting PDF
 * @throws IOException signals that an I/O exception has occurred.
 */
public void createPdf(String src, String dest) throws IOException {
    ConverterProperties properties = new ConverterProperties().setTagWorkerFactory(new CustomTagWorkerFactory());
    HtmlConverter.convertToPdf(new File(SRC), new File(DEST), properties);
}


private static class CustomTagWorkerFactory extends DefaultTagWorkerFactory {
    @Override
    public ITagWorker getCustomTagWorker(IElementNode tag, ProcessorContext context) {
        if ("annot".equals(tag.name())) {
            return new AnnotTagWorker(tag, context);
        }
        return super.getCustomTagWorker(tag, context);
    }
}

private static class AnnotTagWorker extends PTagWorker {
    public AnnotTagWorker(IElementNode element, ProcessorContext context) {
        super(element, context);
    }

    @Override
    public IPropertyContainer getElementResult() {
        IPropertyContainer baseResult = super.getElementResult();
        if (baseResult instanceof Paragraph) {
            ((Paragraph) baseResult).setNextRenderer(new AnnotTagRenderer((Paragraph) baseResult));
        }
        return baseResult;
    }
}

private static class AnnotTagRenderer extends ParagraphRenderer {
    public AnnotTagRenderer(Paragraph modelElement) {
        super(modelElement);
    }

    @Override
    public IRenderer getNextRenderer() {
        return new AnnotTagRenderer((Paragraph) modelElement);
    }

    @Override
    public void draw(DrawContext drawContext) {
        super.draw(drawContext);

        Rectangle occupiedArea = this.getOccupiedAreaBBox();
        float[] quadPoints = new float[] {occupiedArea.getLeft(), occupiedArea.getTop(), occupiedArea.getRight(), occupiedArea.getTop(),
                occupiedArea.getLeft(), occupiedArea.getBottom(), occupiedArea.getRight(), occupiedArea.getBottom()};
        PdfAnnotation ann = PdfTextMarkupAnnotation.createHighLight(
                        new Rectangle(occupiedArea), quadPoints)
                .setColor(ColorConstants.YELLOW)
                .setTitle(new PdfString("Hello!"))
                .setContents(new PdfString("I'm a popup."))
                .setTitle(new PdfString("iText"));

        drawContext.getDocument().getPage(this.getOccupiedArea().getPageNumber()).addAnnotation(ann);
    }
}

}

默认情况下,<annot> 标记在 CSS 属性处理方面将被忽略,因此您的 text-indent: 0px !important 声明基本上被忽略。要为自定义标签启用 CSS 处理,请使用自定义 CSS applier 工厂:

private static class CustomCssApplierFactory extends DefaultCssApplierFactory {
    @Override
    public ICssApplier getCustomCssApplier(IElementNode tag) {
        if ("annot".equals(tag.name())) {
            return new BlockCssApplier();
        }
        return super.getCustomCssApplier(tag);
    }
}

它也通过 ConverterProperties 插入到 pdfHTML 中:

ConverterProperties properties = new ConverterProperties()
        .setTagWorkerFactory(new CustomTagWorkerFactory())
        .setCssApplierFactory(new CustomCssApplierFactory());