使用iText编辑XFA PDF(仅编辑节点中的字段)

时间:2017-07-13 18:02:59

标签: c# xml pdf itext

好的,我必须使用C#以编程方式填写XFA PDF。我已经能够成功提取PDF的XML结构。但是,我使用AcroFields.Xfa.FillXfaForm(sourceXML)调用遇到了问题。

基本上发生的事情是:我正在使用整个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并提取出许多我想编辑的字段并按照这种方式进行操作?

非常感谢任何帮助。

亲切的问候。

2 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分: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。