2017-07-13 177 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完成。