如何使用iText获取动态pdf中所有控件的值和键?

时间:2017-09-25 16:18:10

标签: itext pdf-generation itext7 xfa

我试图从动态表单中提取所有字段。但我观察到代码适用于某些形式而不适用于其他形式。最糟糕的是,代码对于相同的表单有不同的工作方式,但有两个不同的下载文件。但经过深入挖掘后,我发现那些正确的表格是经过新加工的。甚至没有一个细节来自PDF软件(Adobe Reader)。此外,如果表单已填写并保存,则表单在浏览器中的缩略图将更改。代码段如下:

PdfDocument pdfDoc;
pdfDoc = new PdfDocument(new PdfReader(src), new PdfWriter(dest));
PdfDictionary perms = pdfDoc.getCatalog().getPdfObject().getAsDictionary(PdfName.Perms);
    if (perms != null) {
        perms.remove(new PdfName("UR"));
        perms.remove(PdfName.UR3);
        if (perms.size() == 0) {
            pdfDoc.getCatalog().remove(PdfName.Perms);
        }
    }
    PdfAcroForm form = PdfAcroForm.getAcroForm(pdfDoc, true);

    List<String> result = new ArrayList<String>(form.getFormFields().keySet());

    Map<String, PdfFormField> fields = form.getFormFields();

下面是同一表格的图片,但下载了两次。带有彩色缩略图的那个没有填充。其他使用Adobe Reader填充并保存,并在保存缩略图时消失。

我怀疑在保存表单时可能会设置一个标志。感谢任何帮助。另一个特殊的观察结果是,对于上述两种形式,PdfCatalog对象中的参数数量不匹配。该物业的入口&#39; NeedsRendering&#39;存在于错误的PDF中,否则存在于工作的PDf中。我在调试会话期间附加了工作PDF的屏幕截图。

hrsa_working_form:

hrsa_working_form

更新1 @Browno,为新手的头脑中令人困惑的问题道歉。我已经发布了来自迭代RUPS的屏幕截图,用于密钥&#39; / AcroForm&#39;。在探索XFAForm的答案时,我已经学会了如何填充它们。但是压扁它们会导致异常。我已经在AGPL的许可下使用了pdfxfa jar。我缺乏XFAFlattener的知识以及它在XFAFlattenerProperties类中使用的属性。下面是代码快照:

public void fillData2(String src, String xml, String dest, String newDest){
        throws IOException, ParserConfigurationException, SAXException, InterruptedException {
    PdfReader reader = new PdfReader(src);
    reader.setUnethicalReading(true);
    PdfDocument pdfDoc = new PdfDocument(reader, new PdfWriter(dest), new StampingProperties().useAppendMode());
    PdfAcroForm form = PdfAcroForm.getAcroForm(pdfDoc, true);

    List<String> result = new ArrayList<String>(form.getFormFields().keySet());
    System.out.println(result.size());
    XfaForm xfa = form.getXfaForm();
    xfa.fillXfaForm(new FileInputStream(xml));
    xfa.write(pdfDoc);
    //form.flattenFields(); throws exception
    pdfDoc.close();
    FileInputStream fis = new FileInputStream(dest);
    FileOutputStream fos = new FileOutputStream(newDest);
    XFAFlattener xfaFlattener = new XFAFlattener();
    xfaFlattener.setFontSettings(new XFAFontSettings().setEmbedExternalFonts(true));
    xfaFlattener.flatten(fis, fos);
    fis.close();
    fos.close();
}

遇到的异常是:

Exception in thread "main" java.lang.NoSuchFieldError: FONTFAMILY
at com.itextpdf.tool.xml.xtra.xfa.font.XFAFontProvider.addFonts(XFAFontProvider.java:117)
at com.itextpdf.tool.xml.xtra.xfa.font.XFAFontProvider.<init>(XFAFontProvider.java:56)
at com.itextpdf.tool.xml.xtra.xfa.XFAFlattener.initFlattener(XFAFlattener.java:643)
at com.itextpdf.tool.xml.xtra.xfa.XFAFlattener.flatten(XFAFlattener.java:201)
at com.itextpdf.tool.xml.xtra.xfa.XFAFlattener.flatten(XFAFlattener.java:396)
at com.mycompany.kitext.kitext.fillData2(kitext.java:153)
at com.mycompany.kitext.kitext.main(kitext.java:81)

另外,根据@ mkl的评论,我已附上PDF表格:

https://drive.google.com/file/d/0B6w278NcMSCrZDZoZklmVTNuOWc/view?usp=sharing
//iText RUPS /AcroForm Snapshot
https://drive.google.com/file/d/0B6w278NcMSCrZ1Q1VHc5YzY4UG8/view?usp=sharing
//Form filled with fillXfaForm()
//running low on reputation

表格填写XFA

我还阅读了面向开发人员的pdfXFA发行说明。但无法找到类似的例子。感谢您的帮助和iText的出色工作。

0 个答案:

没有答案