6

我正在尝试获取 XFA 表单中所有字段的简单列表。我正在使用这段代码:

private void ListFieldNames()
{
    string pdfTemplate = @"C:\Projects\iTextSharp\SReport.pdf";
    MemoryStream m = new MemoryStream();

    // title the form
    this.Text += " - " + pdfTemplate;

    // create a new PDF reader based on the PDF template document
    PdfReader pdfReader = new PdfReader(pdfTemplate);
    PdfStamper pdfStamper = new PdfStamper(pdfReader, m);
    AcroFields formFields = pdfStamper.AcroFields;        
    AcroFields form = pdfReader.AcroFields;
    XfaForm xfa = form.Xfa;
    StringBuilder sb = new StringBuilder();
    sb.Append(xfa.XfaPresent ? "XFA form" : "AcroForm");
    sb.Append(Environment.NewLine);

    foreach (string key in form.Fields.Keys)
    {
        sb.Append(key);
        sb.Append(Environment.NewLine);
        txtFields.Text = sb.ToString();
    }

    txtFields.Text = sb.ToString();
}

但我得到的只是 XFA 表格,而不是任何字段。知道我做错了什么吗?

提前致谢

4

1 回答 1

12

You've taken a code sample from chapter 8 of my book "iText in Action." The result of that code sample is consistent with what I wrote on page 273:

Running Listing 8.18 with this form as resource will give you the following result:

AcroForm

If your question is Any idea what I am doing wrong? then the answer is simple: you stopped reading on page 270, or you used a code sample without reading the accompanying documentation. How to fix this? Read the documentation!

If your question is Why don't I get any info about the fields? (which isn't your question, but let's assume it is), the answer is: you're using code to retrieve AcroForm fields, but your form doesn't contain any such fields. Your form is a pure XFA form, which means that all field information is stored as XML and XML only!

Suppose that you now want to know: How can I extract that XML? then you should go to the place where you found the example you copy/pasted.

That could be here: http://itextpdf.com/examples/iia.php?id=164

Or maybe here: http://sourceforge.net/p/itextsharp/code/HEAD/tree/trunk/book/iTextExamplesWeb/iTextExamplesWeb/iTextInAction2Ed/Chapter08/XfaMovie.cs

Or even here: http://kuujinbo.info/iTextInAction2Ed/index.aspx?ch=Chapter08&ex=XfaMovie

This code snippet will return the complete XFA stream:

public string ReadXfa(PdfReader reader) {
  XfaForm xfa = new XfaForm(reader);
  XmlDocument doc = xfa.DomDocument;
  reader.Close();

  if (!string.IsNullOrEmpty(doc.DocumentElement.NamespaceURI)) {
    doc.DocumentElement.SetAttribute("xmlns", "");
    XmlDocument new_doc = new XmlDocument();
    new_doc.LoadXml(doc.OuterXml);
    doc = new_doc;
  }

  var sb = new StringBuilder(4000);
  var Xsettings = new XmlWriterSettings() {Indent = true};
  using (var writer = XmlWriter.Create(sb, Xsettings)) {
    doc.WriteTo(writer);
  }
  return sb.ToString();    
}

Now look for the <xfa:datasets> tag; it will have a subtag <xfa:data> (probably empty if the form is empty) and a subtag <dd:dataDescription>. Inside the dataDescription tag, you'll find something that resembles XSD. That's what you need to know what the fields in the form are about.

I could go on guessing questions, such as: How do I fill out such a form? By using the method fillXfaForm(); How can I flatten such a form? By using XFA Worker (which is a closed source library written on top of iTextSharp), but let's keep those questions for another thread ;-)

于 2013-02-16T14:55:35.180 回答