如何拼合具有相同名称的字段

问题描述

我正在使用itext 7.1.8,我需要弄平包含相同名称字段的文档。
我将如下创建文档:

private static PdfDocument createPdfDocument(final String name,final int countFields) {
        PdfDocument pdf;
        try {
            final FileOutputStream os = new FileOutputStream(name + ".pdf");
            PdfWriter pdfWriter = new PdfWriter(os);
            pdf = new PdfDocument(pdfWriter);


            final PdfPage pdfPage = pdf.addNewPage();

            final float height = pdfPage.getCropBox().getHeight();

            final PdfTextFormField txt1Fld = PdfFormField.createText(pdf,new Rectangle( 100,height - 100,200,18),"Text_1");
            txt1Fld.setValue("Hello");

            for (int i = 0; i < countFields; i++) {
                PdfAcroForm.getAcroForm(pdf,true)
                        .addField(txt1Fld,i == 0 ? pdfPage : pdf.addNewPage());
            }

            pdf.close();
        } catch (Exception e) {
            e.printStackTrace();
            pdf = null;
        }
        return pdf;
    }

在那之后,我试图将文档整理如下:

private static void flattenPdf(String name,String flattenName) {
        try {
            OutputStream os = new FileOutputStream(flattenName + ".pdf");
            InputStream is = new FileInputStream(name + ".pdf");
            PdfReader reader = new PdfReader(is);
            PdfWriter writer = new PdfWriter(os);
            final PdfDocument pdfDocument = new PdfDocument(reader,writer);
            final PdfAcroForm acroForm = PdfAcroForm.getAcroForm(pdfDocument,true);
            acroForm.setNeedAppearances(true);
            acroForm.flattenFields();
            pdfDocument.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

有我的主要方法:

public static void main(String[] args) throws IOException {
    final String flattenName = "ItextPdfTwoFields";

    System.out.println("Create " + flattenName + ".pdf");
    createPdfDocument(flattenName,2);
    System.out.println(flattenName + ".pdf created successfully");
    System.out.println("Trying to flat " + flattenName + "_flatten.pdf...");
    flattenPdf(flattenName,flattenName + "_flatten");
}

展平后,我得到包含一个展平字段的文档,但是我必须得到两个展平字段。
我该如何解决这个问题?

解决方法

首先,我绝对会建议您使用最新版本7.1.12。但是仅使用该版本是不够的,您将需要编写一些其他代码来创建具有多个小部件的表单字段,即跨多个字段表示形式共享值。拼合的代码很好,我们只需要修改代码即可创建文档,因为当前代码中发生的是将相同的字段添加到两个页面,并且小部件注释和页面之间的关联不一致。代替此代码:

final PdfTextFormField txt1Fld = PdfFormField.createText(pdf,new Rectangle( 100,height - 100,200,18),"Text_1");
txt1Fld.setValue("Hello");

for (int i = 0; i < countFields; i++) {
    PdfAcroForm.getAcroForm(pdf,true)
            .addField(txt1Fld,i == 0 ? pdfPage : pdf.addNewPage());
}

我们只需要创建一个字段,然后将窗口小部件添加到其余页面(第一个页面除外)的字段中,并将页面与窗口小部件关联(将窗口小部件注释添加到相应页面)。最后,将值设置为将为所有小部件注释生成外观的字段,并将该字段添加到表单。这是代码:

Rectangle rect = new Rectangle( 100,18);
final PdfTextFormField txt1Fld = PdfFormField.createText(pdf,rect,"Text_1");

for (int i = 1; i < countFields; i++) {
    PdfWidgetAnnotation annotation = new PdfWidgetAnnotation(rect);
    annotation.makeIndirect(pdf);
    txt1Fld.addKid(annotation);
}

for (int i = 0; i < countFields; i++) {
    if (pdf.getNumberOfPages() <= i) {
        pdf.addNewPage();
    }
    pdf.getPage(i + 1).addAnnotation(txt1Fld.getWidgets().get(i));
}

txt1Fld.setValue("Hello");

PdfAcroForm.getAcroForm(pdf,true).addField(txt1Fld,pdfPage);

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...