現在、フィールドをレイアウトに追加するすぐに使える方法はありませんが、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()
ますが、フォーム フィールドが正しく挿入されるように、この要素のカスタム オペレーターを定義しました。やりたい正確な位置を知っているとき。
サンプルの完全なコードは、ここにあります。ただし、サンプルリポジトリは現在再編成中であるため、リンクが変更される可能性があることに注意してください。