2017-07-13 101 views
0

好吧,我必须用C#编程式地填写XFA PDF。我已经能够成功提取PDF的XML结构。但是,我遇到了使用AcroFields.Xfa.FillXfaForm(sourceXML)调用的问题。使用iText编辑XFA PDF(仅编辑节点内的字段)

基本上发生了什么是这样的:我正在采取整个XML树,编辑XML中的字段,然后尝试使用新的XML编辑表单字段。我最终得到了一个没有添加新输入的所有AcroForm字段的PDF。但是,当我解析此编辑的PDF并提取XML树时,我发现我的编辑已保存。

此特定XFA PDF的安全设置允许编辑表单域,但是我被迫使用PdfReader.unethicalreading = true;与我目前的设置(这就是为什么我相信表单域被剥离)。我相信XFA PDF将我的XML编辑完整地编辑为文档本身的格式。

这是到目前为止我的代码:

命名空间ConsoleApplication2 { 类节目 {

static void Main(string[] args) 
    { 
     System.IO.StreamWriter file = new System.IO.StreamWriter(@"E:\XMLOutPut\outPutTest.xml"); 
     file.WriteLine(ReadFileNames()); 
     file.Close(); 

     using (FileStream existingPdf = new FileStream(@"E:\ORIGINAL.pdf", FileMode.Open)) 
     { 
      using (PdfReader pdfReader = new PdfReader(existingPdf)) 
      { 
       using (FileStream sourceXML = new FileStream(@"E:\XMLOutPut\outPutTest.xml", FileMode.Open)) 
       { 
        using (FileStream targetPdf = new FileStream(@"E:\ORIGINAL.pdf", FileMode.Open)) 
        { 
         PdfReader.unethicalreading = true; 
         PdfStamper stamper = new PdfStamper(pdfReader, targetPdf,'\0', true); 
         stamper.AcroFields.Xfa.FillXfaForm(sourceXML); 
         stamper.Close(); 
        } 
       } 
      } 
     } 
    } 

    public static string ReadFileNames() 
    { 

     string SRC = @"E:\ORIGINAL.pdf"; 
     using (PdfReader reader = new PdfReader(SRC)) 
     { 
      return ReadXFA(reader); 
     } 
    } 

    public static string ReadXFA(PdfReader reader) 
    { 
     XfaForm xfa = new XfaForm(reader); 
     XmlDocument document = xfa.DomDocument; 
     reader.Close(); 

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

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

}

我开始相信,我必须以某种方式通过XML迭代并拔出我希望编辑的许多字段并以此方式执行?

任何帮助将不胜感激。

亲切的问候。

回答

0
static void Main(string[] args) 
    { 
     using (FileStream existingPdf = new FileStream(SRC, FileMode.Open)) 
     using (PdfReader pdfReader = new PdfReader(existingPdf)) 
     using (FileStream targetPdf = new FileStream(Target, FileMode.Create)) 
     { 
      PdfReader.unethicalreading = true; 
      using (PdfStamper stamper = new PdfStamper(pdfReader, targetPdf, '\0', true)) 
      { 
       XfaForm form = new XfaForm(pdfReader); 
       XDocument xdoc = form.DomDocument.ToXDocument(); 
       var nodeElements = from nodeElement in xdoc.Descendants("form1").Descendants("A1") 
            select nodeElement; 
       foreach (XElement singleNodeElement in nodeElements) 
       { 
        if (singleNodeElement.Name == "A1") 
        { 
         singleNodeElement.Value = "LOLGG"; 
        } 
       } 
       XmlDocument xmlDoc = xdoc.ToXmlDocument(); 
       XmlNamespaceManager namespaces = new XmlNamespaceManager(xmlDoc.NameTable); 
       namespaces.AddNamespace("xfa", "http://www.xfa.org/schema/xfa-data/1.0/"); 
       XmlNode baseNode = xmlDoc.SelectSingleNode("//xfa:datasets", namespaces); 
       stamper.AcroFields.Xfa.FillXfaForm(baseNode); 
      } 
     } 

    } 
} 
public static class DocumentExtensions 
{ 
    public static XmlDocument ToXmlDocument(this XDocument xDocument) 
    { 
     var xmlDocument = new XmlDocument(); 
     using (var xmlReader = xDocument.CreateReader()) 
     { 
      xmlDocument.Load(xmlReader); 
     } 
     return xmlDocument; 
    } 

    public static XDocument ToXDocument(this XmlDocument xmlDocument) 
    { 
     using (var nodeReader = new XmlNodeReader(xmlDocument)) 
     { 
      nodeReader.MoveToContent(); 
      return XDocument.Load(nodeReader); 
     } 
    } 
} 

Alrighty人因此能够除了LINQ和Xml.Linq与iText的做到这一点,如上面的代码示例示出。

为了使这成为可能,我们必须采用XMLDocument并将其转换为XDocument,然后使用Linq遍历节点。一旦我们能够得到正确的节点,我们必须添加一个名称空间来正确标识前缀。然后,我们必须将XDoc格式转换回XMLDoc格式,才能使用iText中的FillXfaForm。

3

这是目前不可能使用iText。您需要从文件中提取XFA(您可以使用iText来执行此操作),然后遍历XFA结构以进行编辑,您需要对其他工具执行编辑,然后将XFA重新插入PDF,可以使用iText完成。