【发布时间】:2021-08-04 20:47:26
【问题描述】:
我使用 iText7 将 HTML 转换为 PDF,并且需要为 HTML 中的特定文本添加文本标记注释。我正在使用 link 中解释的 CustomTagWorkers,然后使用 here 给出的注释示例。
我可以通过将 qr 标记替换为链接注释来成功添加链接注释。但是我的要求是添加一个文本标记注释。 Text Markup注解只能通过给出我在代码中不知道的页面(矩形对象)的具体坐标来绘制。我试图给Rectangle(0, 0),希望iText 能代替标签呈现它。但是我无法将文本标记注释添加到段落对象,这是public IPropertyContainer getElementResult() { 的返回对象。
这是我的全部代码:
/**
* Converts an HTML file to a PDF document, introducing a custom tag to create a
* QR Code involving a custom TagWorker and a custom CssApplier.
*/
public class C05E04_QRCode2 {
/**
* The path to the resulting PDF file.
*/
public static final String DEST = "C:\\Samples\\itext-annotation\\qrcode.pdf";
/**
* The path to the source HTML file.
*/
public static final String SRC = "C:\\Samples\\itext-annotation\\qrcode.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();
properties.setCssApplierFactory(new QRCodeTagCssApplierFactory())
.setTagWorkerFactory(new QRCodeTagWorkerFactory());
HtmlConverter.convertToPdf(new File(src), new File(dest), properties);
}
/**
* A factory for creating QRCodeTagCssApplier objects.
*/
class QRCodeTagCssApplierFactory extends DefaultCssApplierFactory {
/**
* Gets the custom css applier.
*
* @param tag the tag
* @return the custom css applier
*/
/*
* (non-Javadoc)
*
* @see com.itextpdf.html2pdf.css.apply.impl.DefaultCssApplierFactory#
* getCustomCssApplier(com.itextpdf.html2pdf.html.node.IElementNode)
*/
@Override
public ICssApplier getCustomCssApplier(IElementNode tag) {
if (tag.name().equals("qr")) {
return new BlockCssApplier();
}
return null;
}
}
/**
* A factory for creating QRCodeTagWorker objects.
*/
class QRCodeTagWorkerFactory extends DefaultTagWorkerFactory {
/**
* Gets the custom tag worker.
*
* @param tag the tag
* @param context the context
* @return the custom tag worker
*/
@Override
public ITagWorker getCustomTagWorker(IElementNode tag, ProcessorContext context) {
if (tag.name().equals("qr")) {
return new QRCodeTagWorker(tag, context);
}
return null;
}
}
/**
* The custom ITagWorker implementation for the qr-tag.
*/
static class QRCodeTagWorker implements ITagWorker {
/** The p. */
private Paragraph p;
/** The annotation. */
private PdfLinkAnnotation linkAnnotation;
/**
* Instantiates a new QR code tag worker.
*
* @param element the element
* @param context the context
*/
public QRCodeTagWorker(IElementNode element, ProcessorContext context) {
}
/**
* Process content.
*
* @param content the content
* @param context the context
* @return true, if successful
*/
@Override
public boolean processContent(String content, ProcessorContext context) {
return true;
}
/**
* Process tag child.
*
* @param childTagWorker the child tag worker
* @param context the context
* @return true, if successful
*/
@Override
public boolean processTagChild(ITagWorker childTagWorker, ProcessorContext context) {
return false;
}
/**
* Process end.
*
* @param element the element
* @param context the context
*/
@Override
public void processEnd(IElementNode element, ProcessorContext context) {
//Link Annotation
linkAnnotation = new PdfLinkAnnotation(new Rectangle(0, 0)).setAction(PdfAction.createURI(
"https://kb.itextpdf.com/"));
Link link = new Link("here", linkAnnotation);
p = new Paragraph("The example of link annotation. Click ").add(link.setUnderline())
.add(" to learn more...");
//Line Annotation
float[] floatArray = new float[] { 169, 790, 105, 790, 169, 800, 105, 800 };
PdfAnnotation lineAnnotation = PdfTextMarkupAnnotation.createHighLight(new Rectangle(0, 0), floatArray);
lineAnnotation.setTitle(new PdfString("You are here:"));
lineAnnotation.setContents("Cambridge Innovation Center");
lineAnnotation.setColor(ColorConstants.YELLOW);
//Text Markup Annotation
PdfAnnotation ann = PdfTextMarkupAnnotation.createHighLight(
new Rectangle(105, 790, 64, 10),
new float[]{169, 790, 105, 790, 169, 800, 105, 800})
.setColor(Color.YELLOW)
.setTitle(new PdfString("Hello!"))
.setContents(new PdfString("I'm a popup."))
.setTitle(new PdfString("iText"))
.setOpen(true)
.setRectangle(new PdfArray(new float[]{100, 600, 200, 100}));
}
/**
* Gets the element result.
*
* @return the element result
*/
@Override
public IPropertyContainer getElementResult() {
return p;
}
}
}
HTML 文件:
<html>
<head>
<meta charset="UTF-8">
<title>QRCode Example</title>
<link rel="stylesheet" type="text/css" href="css/qrcode.css"/>
</head>
<body>
<span> The example of <qr> text markup </qr> annotation. </span>
</body>
</html>
CSS 文件:
qr {
border: solid 1px red;
height: 200px;
width: 200px;
}
最终输出的插图
【问题讨论】:
-
好的,您希望在页面的哪个位置绘制线条注释?可以加个插图吗?
-
@alexysubach - 我希望将
标记替换为行注释。我最初的要求是为带有 标签的特定文本添加注释。我不知道我是否可以这样做。所以我采取了一种方法,在我的超链接之后添加一个自定义标签 (qr),然后使用 CustomTagWorkers 将 标签替换为 Line Annotations。让我知道这是否有意义。 -
@AlexeySubach - 关于您询问的位置,HTML 是动态生成的。所以我们不知道它会在哪里。但是我们想在找到
标签的任何地方添加注释。 -
Qr 标签包含一些文本,可以是多行的。是否要将注释放在第一行和第二行的中间?在第一行之上?最后一行的底部?或者您确定文本不会跨行拆分?另外,线注释是您真正想要的,还是您只想要视觉下划线?
-
@AlexeySubach - 在查看了其他注释示例之后,看起来文本标记注释适合我的用例。我更新了我的原始帖子,以包含我想要的视觉说明。在图像“文本标记”中有一个文本标记注释。在我们的示例中,
标签将包含“文本标记”。我更新了原始帖子中的代码以包含文本标记注释。如何计算 的值new Rectangle(105, 790, 64, 10), new float[]{169, 790, 105, 790, 169, 800, 105, 800})