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());
使用
我动态生成的 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());