Si j'ai bien compris, vous souhaitez ajouter une annotation parmi les autres éléments de disposition à votre flux de documents.
Il n'existe actuellement aucun moyen rapide d'y parvenir (comme la méthode setAnnotation
dans iText5
) actuellement dans iText7
. Cependant, iText7
est assez flexible pour vous permettre de créer des éléments personnalisés et ne pas creuser très profondément dans le code.
La partie initiale sera la même que dans l'exemple actuel. Ici, une annotation lui-même est mis en place:
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());
Alors, ce que nous voulons atteindre est d'être capable d'ajouter des éléments d'annotation personnalisée à la mise en page flux Document
. Dans le meilleur des cas, le code ressemblerait à ceci:
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();
Nous nous retrouvons maintenant avec la définition de la AnnotationElement
et correspondant renderer. Élément lui-même n'a pas de logique spécifique à part de créer renderer personnalisé et en passant une annotation à elle:
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);
}
}
La mise en œuvre de renderer a plus de code, mais ce qu'il qui est définit simplement la zone occupée sur layout
et ajoute la annotation à la page sur draw
. Veuillez noter que cela ne couvre pas tous les cas (par exemple, il n'y a pas assez d'espace pour une annotation), mais cela est plus que suffisant pour les cas simples et à des fins de démonstration.
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);
}
}
S'il vous plaît noter que l'exemple est pour la version actuelle 7.0.3-SNAPSHOT
. Peut-être ne fonctionne pas pour la version 7.0.2
encore parce que l'interface ILeafElementRenderer
a été ajouté plus tard, mais il serait encore possible d'adapter le code à 7.0.2
si vraiment nécessaire.
Merci beaucoup! @mkl –
Veuillez ne pas ajouter votre solution au corps de la question, postez-la plutôt comme réponse. – mkl