首页 文章

如何填写XFA pdf文档的单个字段?

提问于
浏览
0

我的Pdf包含一个带空字段的XFA表单 . 我尝试通过操作XML然后将SetXfa()应用于ITextSharp来填充它,但PDF不会更改 . 这是我的方法:

static void EditFieldXFA(string path, string key, string value)
{
    iTextSharp.text.pdf.PdfReader reader = new iTextSharp.text.pdf.PdfReader(path);
    using (MemoryStream ms = new MemoryStream())
    {
        PdfStamper stamper = new PdfStamper(reader, ms);
        AcroFields form = stamper.AcroFields;
        XfaForm xfa = form.Xfa;
        var a = xfa.DatasetsNode.InnerXml;
        if (a.Contains(key))
        {
            // The empty XML looks like <key />, and a filled XML looks like <key>value</key>, so we edit the field
            string keyClose = key.Replace(" /", "").Replace("<", "</");
            var newXml = a.Replace(key, key.Replace(" /", "") + value + keyClose);
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(newXml);
            // xfa.FillXfaForm(XmlReader.Create(new StringReader(newXml)));
            xfa.DomDocument = doc;
            xfa.Changed = true;
            XfaForm.SetXfa(xfa, stamper.Reader, stamper.Writer);

            stamper.Close();
            reader.Close();

            return;
        }
        else
        {
            Console.Write("Error : No " + key + " field detected. Please check that it is empty. Press enter to exit the process.");
            Console.Read();
            Environment.Exit(2);
        }
    }
}

正确修改了XML,我查了一下 . 这是正确的方法吗?你知道下一步该尝试什么吗?谢谢您的帮助 !

XML文件:https://drive.google.com/file/d/1EbZJM6TjZ5tXQ0Dxa6IeUDz3QgJuxsBi/view?usp=sharing如果下载有任何问题,请告诉我,并在Acrobat中打开它以查看内容 .

1 回答

  • 0

    一般问题

    您的 PdfStamper 写入的流是 MemoryStream ms

    PdfStamper stamper = new PdfStamper(reader, ms);
    

    并且在关闭压模之后完全忽略其内容,即完成冲压

    stamper.Close();
    reader.Close();
    
    return;
    

    因此,您的更改将丢失 .

    相反,您可以将操作的PDF作为字节数组返回给调用者,只需将方法返回类型声明为 byte[]

    static byte[] EditFieldXFA(string path, string key, string value)
    

    并返回内存流内容

    stamper.Close();
    reader.Close();
    
    return ms.ToArray();
    

    特定的XML更改问题

    每当你想操纵一个XML文件时, don't do it manually, use a XML API ,例如DOM;每隔一段时间出现一个情况,其中构建XML手动显得更简单,但通常这种外观具有欺骗性,你最终会因此而陷入麻烦 .

    特别是在手头的情况下,你已经有一个 XmlNodexfa.DatasetsNode . 您只需使用给定名称设置其所有子项,如下所示:

    static byte[] EditFieldXFAImproved(string path, string xpath, string value)
    {
        iTextSharp.text.pdf.PdfReader reader = new iTextSharp.text.pdf.PdfReader(path);
        using (MemoryStream ms = new MemoryStream())
        {
            PdfStamper stamper = new PdfStamper(reader, ms);
            AcroFields form = stamper.AcroFields;
            XfaForm xfa = form.Xfa;
            XmlNode a = xfa.DatasetsNode;
            XmlNodeList hits = a.SelectNodes(xpath);
            foreach(XmlNode hit in hits)
            {
                if (hit.NodeType == XmlNodeType.Element)
                {
                    hit.InnerText = value;
                }
            }
            xfa.Changed = true;
            stamper.Close();
            reader.Close();
    
            return ms.ToArray();
        }
    }
    

    例如

    byte[] result = EditFieldXFAImproved(@"53116504000001 (3).pdf", "//Grund", "Gruuuuuuund");
    File.WriteAllBytes(@"53116504000001 (3)-filled.pdf", result);
    

    将"Ablehnungsgrund/Hinweis"字段值设置为"Gruuuuuuund" .

    请注意,第二个参数已从 key 重命名为 xpath ,因为现在它不再包含空XML元素 "<key />" ,而是xpath "//key" .


    ist denn das,是plplötzlich所以schnell auf mich zukommt? sehr,sehr schnell . 所以riesig和如此flach und und rund . Das braucht einen riesigen Namen ... wie ....... Grund的!

相关问题