【问题标题】:ItextSharp - Acrofields are emptyItextSharp - Acrofields 是空的
【发布时间】:2014-04-07 10:37:21
【问题描述】:

我有一个已填写字段的 PDF 表单。如果我尝试阅读 acrofields,它们是空的。但在 PDF 中,我可以更改值并保存它们。

private static string GetFormFieldNamesWithValues(PdfReader pdfReader)
{
    return string.Join("\r\n", pdfReader.AcroFields.Fields
                                   .Select(x => x.Key + "=" +
                                    pdfReader.AcroFields.GetField(x.Key))
                                   .ToArray());
}

var reader = new PdfReader((DataContext as PDFContext).Datei);
AcroFields form = reader.AcroFields;
txt.Text = GetFormFieldNamesWithValues(reader);

如何读取字段?

【问题讨论】:

  • 您的代码适用于我的示例 PDF,您能否提供不起作用的 PDF?另外,您能否通过检查此属性form.Xfa.XfaPresent 来检查 PDF 表单是否使用 XFA
  • 对于我的 pdf,xfapresent 是错误的。但是在另一个我可以阅读字段的PDF中,它也是错误的。如何添加 pdf?
  • SO不允许上传文件,见meta.stackexchange.com/q/4637
  • 好的...这是链接:PDF。希望您能帮助我找出这些字段不可读的原因。如果 itext 无法读取它们,则可能您知道另一个组件。 ty
  • 如果它有助于使用 wpcubed 创建 PDF。

标签: itextsharp itext


【解决方案1】:

很明显,您的 PDF 已损坏。这些字段在页面级别定义为小部件注释,但在文档根级别上设置的/AcroForm 字段中没有引用它们。

您可以使用FixBrokenForm 代码示例修复您的 PDF:

PdfReader reader = new PdfReader(src);
PdfDictionary root = reader.getCatalog();
PdfDictionary form = root.getAsDict(PdfName.ACROFORM);
PdfArray fields = form.getAsArray(PdfName.FIELDS);

PdfDictionary page;
PdfArray annots;
for (int i = 1; i <= reader.getNumberOfPages(); i++) {
    page = reader.getPageN(i);
    annots = page.getAsArray(PdfName.ANNOTS);
    for (int j = 0; j < annots.size(); j++) {
        fields.add(annots.getAsIndirectObject(j));
    }
}
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
stamper.close();
reader.close();

您应该通知用于生成表单的工具的创建者,他们的 PDF 不符合 PDF 参考。

【讨论】:

  • 谢谢你,Lowagie;修复 PDF 后,我可以读取表单值。我会通知工具开发者。
  • 当我运行这段代码时,它说 annots 为空。我怎样才能克服它?
  • @hiule 没有注释的交互式表单是 XFA 表单。 XFA 代表 XML 表单架构。它与使用小部件注释来直观表示字段的 AcroForm 技术完全不同。请注意,如果您对 4 年前的帖子发表评论,您将不会收到太多反馈。
  • @BrunoLowagie 我现在明白了。由于“pdfStamper.AcroFields.Xfa”,这让我感到困惑。我认为它是 AcroForm 的一部分。谢谢!
【解决方案2】:

这是我的 c#-代码:

   PdfReader reader = new PdfReader(src);
        PdfDictionary root = reader.Catalog;
        PdfDictionary form = root.GetAsDict(PdfName.ACROFORM);
        PdfArray fields = form.GetAsArray(PdfName.FIELDS);

        PdfDictionary page;
        PdfArray annots;
        for (int i = 1; i <= reader.NumberOfPages; i++)
        {
            page = reader.GetPageN(i);
            annots = page.GetAsArray(PdfName.ANNOTS);
            for (int j = 0; j < annots.Size; j++)
            {
                fields.Add(annots.GetAsIndirectObject(j));
            }
        }
        PdfStamper stamper = new PdfStamper(reader, new FileStream(dest, FileMode.Create));
        stamper.Close();
        reader.Close();

【讨论】:

    【解决方案3】:

    C#版本

        public void FixBrokenForm(string src, string dest)
        {
            PdfReader reader = new PdfReader(src);
            PdfDictionary root = reader.Catalog;
            PdfDictionary form = root.GetAsDict(PdfName.ACROFORM);
            PdfArray fields = form.GetAsArray(PdfName.FIELDS);
    
            PdfDictionary page;
            PdfArray annots;
            for (int i = 1; i <= reader.NumberOfPages; i++)
            {
                page = reader.GetPageN(i);
                annots = page.GetAsArray(PdfName.ANNOTS);
                for (int j = 0; j < annots.Size; j++)
                {
                    fields.Add(annots.GetAsIndirectObject(j));
                }
            }
            PdfStamper stamper = new PdfStamper(reader, new FileStream(dest, FileMode.Create));
            stamper.Close();
            reader.Close();
          }
    

    您需要Itextsharp 才能使上述代码正常工作。

    【讨论】:

      【解决方案4】:

      FixBrokenForm 代码的答案很好,但不要忘记调用 fields.setGenerateAppearances(true),否则如果调用 stamper.setFormFlatening(true),您将丢失字段。 你可以这样做:

      PdfStamper stamper = new PdfStamper(reader, new FileStream(dest, FileMode.Create));
      // Add these 2 lines ***************************
      AcroFields acrofields = stamper.getAcroFields();
      acrofields.setGenerateAppearances(true);
      // *********************************************
      stamper.Close();
      reader.Close();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-12-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多