【问题标题】:Add n-textfields with same fieldName with iText使用 iText 添加具有相同 fieldName 的 n-textfields
【发布时间】:2013-11-26 09:15:46
【问题描述】:

我想使用 iText 将共享相同 fieldName 的文本字段添加到文档中。目的是能够设置一个值,并且该值应该出现在所有页面上(自动填充)。

我的问题是,使用下面的代码只有第一个 TextField 出现在 Adob​​e Reader 中。经过研究,看起来我必须使用“一个字典条目”和多个视觉表示“小部件”,但我不知道如何用 iText 实现它。

有什么建议吗? 谢谢 齐格飞

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:我找到了解决方案,但我还有一个问题。这是建议的方式吗?为什么我必须在每页上标记父级? (只在第一页盖章是行不通的)。

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 {

【问题讨论】:

    标签: java itext textfield


    【解决方案1】:

    您不必将父级添加到每个页面。您可以使用 PdfAnnotation.setPlaceInPage(pagenumber) 为每个小部件设置页面并添加一次父级。我已经调整了您添加到问题中的解决方案:

        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 {
    

    【讨论】:

    • 是否可以避免在 PdfStamperImp.addFieldResources() 中添加 /Helv 和 /ZaDb 字体?
    • 这样我们每个页面只能添加一个Textfield,但是如何在单个或多个页面中添加不同坐标的多个文本字段。
    猜你喜欢
    • 1970-01-01
    • 2018-04-30
    • 1970-01-01
    • 1970-01-01
    • 2019-04-28
    • 2021-05-14
    • 2017-08-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多