如何在当前页面位置使用 IText 7 添加 PdfFormField
How can I add an PdfFormField using IText 7 at the current page position
我们已经能够使用以下 Scala 代码片段在页面的特定位置添加 PdfFormField。
val form = PdfAcroForm.getAcroForm(document.getPdfDocument(), true)
val nameField = PdfFormField.createText(document.getPdfDocument(), new Rectangle(data.x, data.y, data.width, data.height), data.formName, data.formText)
form.addField(nameField)
但是,我们希望能够将其添加到我们插入的页面的最后一个段落之后。 (即此字段紧随其后)。有没有一种方法可以导出正确的矩形,或者有更简单的方法吗?
谢谢
目前没有开箱即用的方法来向布局添加字段,但 iText 团队正在考虑实现此功能。
与此同时,实现您的目标有很多简单的方法,其中有一些。
我的示例将在 Java 中,但我认为您可以轻松地在 Scala 中使用它们。
第一种方法只是获取您添加的段落的底部位置,并根据该位置添加您的字段。最后一段的底部位置恰好是页面(区域)上其余可用内容框的顶部位置,转换为以下代码:
Document doc = new Document(pdfDoc);
doc.add(new Paragraph("This is a paragraph.\nForm field will be inserted after it"));
Rectangle freeBBox = doc.getRenderer().getCurrentArea().getBBox();
float top = freeBBox.getTop();
float fieldHeight = 20;
PdfTextFormField field = PdfFormField.createText(pdfDoc,
new Rectangle(freeBBox.getLeft(), top - fieldHeight, 100, fieldHeight), "myField", "Value");
form.addField(field);
您感兴趣的部分是
Rectangle freeBBox = doc.getRenderer().getCurrentArea().getBBox();
这会为您提供尚未放置内容的矩形。
但是请注意,此方法不会影响您要添加表单域之后的后续段落,这意味着此表单域和内容可能会重叠。
处理这种情况,您可能想利用在 iText7 中创建自定义布局元素的可能性。
依次转换为以下代码:
private static class TextFieldRenderer extends DivRenderer {
public TextFieldRenderer(TextFieldLayoutElement modelElement) {
super(modelElement);
}
@Override
public void draw(DrawContext drawContext) {
super.draw(drawContext);
PdfAcroForm form = PdfAcroForm.getAcroForm(drawContext.getDocument(), true);
PdfTextFormField field = PdfFormField.createText(drawContext.getDocument(),
occupiedArea.getBBox(), "myField2", "Another Value");
form.addField(field);
}
}
private static class TextFieldLayoutElement extends Div {
@Override
public IRenderer getRenderer() {
return new TextFieldRenderer(this);
}
}
然后你只需要以一种奇特的方式添加元素:
doc.add(new Paragraph("This is another paragraph.\nForm field will be inserted right after it."));
doc.add(new TextFieldLayoutElement().setWidth(100).setHeight(20));
doc.add(new Paragraph("This paragraph follows the form field"));
简而言之,我们在这里所做的是我们创建了一个自定义虚拟 Div 元素(这是 HTML 的 div 的模拟),它将占用区域在布局期间,但我们为该元素定义了自定义 #draw()
运算符,以便在我们知道要插入的确切位置时正确插入表单字段。
您可以找到示例的完整代码here。但是请注意,link 可能会随着样本存储库的重组而改变。
我们已经能够使用以下 Scala 代码片段在页面的特定位置添加 PdfFormField。
val form = PdfAcroForm.getAcroForm(document.getPdfDocument(), true)
val nameField = PdfFormField.createText(document.getPdfDocument(), new Rectangle(data.x, data.y, data.width, data.height), data.formName, data.formText)
form.addField(nameField)
但是,我们希望能够将其添加到我们插入的页面的最后一个段落之后。 (即此字段紧随其后)。有没有一种方法可以导出正确的矩形,或者有更简单的方法吗? 谢谢
目前没有开箱即用的方法来向布局添加字段,但 iText 团队正在考虑实现此功能。
与此同时,实现您的目标有很多简单的方法,其中有一些。
我的示例将在 Java 中,但我认为您可以轻松地在 Scala 中使用它们。
第一种方法只是获取您添加的段落的底部位置,并根据该位置添加您的字段。最后一段的底部位置恰好是页面(区域)上其余可用内容框的顶部位置,转换为以下代码:
Document doc = new Document(pdfDoc);
doc.add(new Paragraph("This is a paragraph.\nForm field will be inserted after it"));
Rectangle freeBBox = doc.getRenderer().getCurrentArea().getBBox();
float top = freeBBox.getTop();
float fieldHeight = 20;
PdfTextFormField field = PdfFormField.createText(pdfDoc,
new Rectangle(freeBBox.getLeft(), top - fieldHeight, 100, fieldHeight), "myField", "Value");
form.addField(field);
您感兴趣的部分是
Rectangle freeBBox = doc.getRenderer().getCurrentArea().getBBox();
这会为您提供尚未放置内容的矩形。
但是请注意,此方法不会影响您要添加表单域之后的后续段落,这意味着此表单域和内容可能会重叠。
处理这种情况,您可能想利用在 iText7 中创建自定义布局元素的可能性。
依次转换为以下代码:
private static class TextFieldRenderer extends DivRenderer {
public TextFieldRenderer(TextFieldLayoutElement modelElement) {
super(modelElement);
}
@Override
public void draw(DrawContext drawContext) {
super.draw(drawContext);
PdfAcroForm form = PdfAcroForm.getAcroForm(drawContext.getDocument(), true);
PdfTextFormField field = PdfFormField.createText(drawContext.getDocument(),
occupiedArea.getBBox(), "myField2", "Another Value");
form.addField(field);
}
}
private static class TextFieldLayoutElement extends Div {
@Override
public IRenderer getRenderer() {
return new TextFieldRenderer(this);
}
}
然后你只需要以一种奇特的方式添加元素:
doc.add(new Paragraph("This is another paragraph.\nForm field will be inserted right after it."));
doc.add(new TextFieldLayoutElement().setWidth(100).setHeight(20));
doc.add(new Paragraph("This paragraph follows the form field"));
简而言之,我们在这里所做的是我们创建了一个自定义虚拟 Div 元素(这是 HTML 的 div 的模拟),它将占用区域在布局期间,但我们为该元素定义了自定义 #draw()
运算符,以便在我们知道要插入的确切位置时正确插入表单字段。
您可以找到示例的完整代码here。但是请注意,link 可能会随着样本存储库的重组而改变。