如何在当前页面位置使用IText 7添加PdfFormField

时间:2016-06-22 13:11:30

标签: itext7

我们已经能够使用以下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)

但是,我们希望能够在我们插入的页面上的最后一个段落之后添加它。 (即此字段直接来自)。有没有办法可以得到正确的矩形,还是有更简单的方法? 感谢

1 个答案:

答案 0 :(得分:3)

目前没有现成的方法可以在布局中添加字段,但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的完整代码。但请注意,链接可能会随着样本存储库现在重组而发生变化。