问题
i want to use iText to add textfields sharing the same fieldName to a document. The purpose is to be able to set one value and the value should appear on all pages (auto-fill).
My problem is, that with the following code only the first TextField appears in Adobe Reader. After researching it looks like i have to use "one dictionary entry" and multiple visual representations "widgets", but i have no clue how to implement that with iText.
Any suggestions? thanks Siegfried
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.TextField;
public class ITextAddTextfieldDemo {
private static final String ORIGINAL = "original.pdf";
private static final String RESULT = "original_textfield.pdf";
public static void main(String[] args) throws IOException,
DocumentException {
ITextAddTextfieldDemo.createPdf(ORIGINAL, 5);
ITextAddTextfieldDemo.stamp(ORIGINAL, RESULT);
System.out.println("done");
}
public static void stamp(String src, String dest) throws IOException,
DocumentException {
PdfReader reader = new PdfReader(new File(src).getAbsolutePath());
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
int pages = reader.getNumberOfPages();
// test problem by switching true/false
boolean uniqueName = false;
String fieldName = "demoField";
if (uniqueName) {
TextField textField = new TextField(stamper.getWriter(),
new Rectangle(560, 600, 590, 800), fieldName);
textField.setText(""); // add text to see misrendered output
textField.setOptions(TextField.MULTILINE | TextField.DO_NOT_SCROLL);
textField.setRotation(90);
for (int page = 1; page <= pages; page++) {
stamper.addAnnotation(textField.getTextField(), page);
}
} else {
TextField[] textFields = new TextField[pages];
for (int page = 1; page <= pages; page++) {
int idx = page - 1;
fieldName += "_" + String.valueOf(page);
textFields[idx] = new TextField(stamper.getWriter(),
new Rectangle(560, 600, 590, 800), fieldName);
textFields[idx].setText(""); // add text to see misrendered output
textFields[idx].setOptions(TextField.MULTILINE
| TextField.DO_NOT_SCROLL);
textFields[idx].setRotation(90);
stamper.addAnnotation(textFields[idx].getTextField(), page);
}
}
stamper.close();
reader.close();
}
public static void createPdf(String filename, int pages)
throws IOException, DocumentException {
Document document = new Document(PageSize.A4);
PdfWriter.getInstance(document, new FileOutputStream(filename));
document.open();
for (int i = 0; i < pages; i++) {
Paragraph p = new Paragraph("Hello page " + String.valueOf(i + 1));
document.add(p);
document.newPage();
}
document.close();
}
}
@EDIT: I found a solution but i still have a question. Is this the suggested way and why do i have to stamp the parent on each page? (Stamping it only on the first page doesn't work).
if (uniqueName) {
PdfFormField parent = PdfFormField.createTextField(
stamper.getWriter(), true, false, 0);
parent.setFieldName(fieldName);
parent.setUserName("Please enter the common demo data.");
for (int page = 1; page <= pages; page++) {
TextField textField = new TextField(stamper.getWriter(),
new Rectangle(560, 600, 590, 800), null);
textField.setOptions(TextField.MULTILINE
| TextField.DO_NOT_SCROLL);
textField.setRotation(90);
PdfFormField pff = textField.getTextField();
parent.addKid(pff);
stamper.addAnnotation(pff, page);
// why is it necessary to add it on every page?
stamper.addAnnotation(parent, page);
}
} else {
回答1:
You don't have to add the parent to each page. You can set the page for each widget using PdfAnnotation.setPlaceInPage(pagenumber) and add the parent once. I have adjusted the solution you added to your question:
if (uniqueName) {
PdfFormField parent = PdfFormField.createTextField(
stamper.getWriter(), true, false, 0);
parent.setFieldName(fieldName);
parent.setUserName("Please enter the common demo data.");
for (int page = 1; page <= pages; page++) {
TextField textField = new TextField(stamper.getWriter(),
new Rectangle(560, 600, 590, 800), null);
textField.setOptions(TextField.MULTILINE
| TextField.DO_NOT_SCROLL);
textField.setRotation(90);
PdfFormField pff = textField.getTextField();
parent.addKid(pff);
// add widget to each page
pff.setPlaceInPage(page);
}
// add parent
stamper.addAnnotation(parent, 1);
} else {
来源:https://stackoverflow.com/questions/20212745/add-n-textfields-with-same-fieldname-with-itext