首页 文章

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

提问于
浏览
0

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

基本上发生的是:我正在使用整个XML树,编辑XML中的字段,然后尝试使用新的XML编辑表单字段 . 我最终删除了所有AcroForm字段的PDF,没有添加新的输入 . 但是,当我解析这个编辑过的PDF并提取XML树时,我发现我的编辑内容已被保留 .

此特定XFA PDF的安全设置允许编辑表单字段但是我被迫使用PdfReader.unethicalreading = true;我目前的设置(这就是我相信表单字段被剥离的原因) . 我相信XFA PDF将我的XML编辑作为一个完整的编辑文档本身的格式 .

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

namespace ConsoleApplication2 {class Program {

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 回答

  • 3

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

  • 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 .

相关问题