如果我理解正確,您希望在其他佈局元素中添加註釋到您的文檔流。
目前在iText7
有沒有快速的方法來實現它(如setAnnotation
方法在iText5
)。但是,iText7
足夠靈活,可以讓您創建自定義元素,而不是深入挖掘代碼。
初始部分與當前示例中的相同。這裏的註釋本身正在建立:
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(DEST));
Rectangle rect = new Rectangle(36, 700, 50, 50);
PdfFileSpec fs = PdfFileSpec.createEmbeddedFileSpec(pdfDoc, PATH, null, "test.docx", null, null, false);
PdfAnnotation attachment = new PdfFileAttachmentAnnotation(rect, fs)
.setContents("Click me");
PdfFormXObject xObject = new PdfFormXObject(rect);
ImageData imageData = ImageDataFactory.create(IMG);
PdfCanvas canvas = new PdfCanvas(xObject, pdfDoc);
canvas.addImage(imageData, rect, true);
attachment.setNormalAppearance(xObject.getPdfObject());
然後,我們要實現的是能夠自定義註解的元素添加到佈局Document
流。 在最好的情況下,代碼應該是這樣的:
Document document = new Document(pdfDoc);
Paragraph p = new Paragraph("There are two").add(new AnnotationElement(attachment)).add(new Text("elements"));
document.add(p);
document.close();
現在我們只剩下定義AnnotationElement
和相應的渲染器。元素本身不具有任何特定的邏輯除了創建自定義渲染和傳遞一個註解吧:
private static class AnnotationElement extends AbstractElement<AnnotationElement> implements ILeafElement {
private PdfAnnotation annotation;
public AnnotationElement(PdfAnnotation annotation) {
this.annotation = annotation;
}
@Override
protected IRenderer makeNewRenderer() {
return new AnnotationRenderer(annotation);
}
}
渲染器實現了更多的代碼,但它是簡單的定義上layout
佔用面積,並增加了註釋到draw
上的頁面。請注意,它並沒有涵蓋所有情況(例如沒有足夠的空間來容納註釋),但這對於簡單情況和演示目的來說已經足夠了。
private static class AnnotationRenderer extends AbstractRenderer implements ILeafElementRenderer {
private PdfAnnotation annotation;
public AnnotationRenderer(PdfAnnotation annotat) {
this.annotation = annotat;
}
@Override
public float getAscent() {
return annotation.getRectangle().toRectangle().getHeight();
}
@Override
public float getDescent() {
return 0;
}
@Override
public LayoutResult layout(LayoutContext layoutContext) {
occupiedArea = layoutContext.getArea().clone();
float myHeight = annotation.getRectangle().toRectangle().getHeight();
float myWidth = annotation.getRectangle().toRectangle().getWidth();
occupiedArea.getBBox().moveUp(occupiedArea.getBBox().getHeight() - myHeight).setHeight(myHeight);
occupiedArea.getBBox().setWidth(myWidth);
return new LayoutResult(LayoutResult.FULL, occupiedArea, null, null);
}
@Override
public void draw(DrawContext drawContext) {
super.draw(drawContext);
annotation.setRectangle(new PdfArray(occupiedArea.getBBox()));
drawContext.getDocument().getPage(occupiedArea.getPageNumber()).addAnnotation(annotation);
}
@Override
public IRenderer getNextRenderer() {
return new AnnotationRenderer(annotation);
}
}
請注意,該示例適用於當前的7.0.3-SNAPSHOT
版本。可能不適用於版本7.0.2
版本,因爲ILeafElementRenderer
接口稍後添加,但如果確實需要,仍然可以將代碼調整爲7.0.2
。
謝謝! @mkl –
請不要將您的解決方案添加到問題主體,而是將其作爲答案發布。 – mkl