如何填写 XFA pdf 文档的单个字段? [英] How to fill a single field of an XFA pdf document?

查看:34
本文介绍了如何填写 XFA pdf 文档的单个字段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

My Pdf contains an XFA form with an empty field. I tried filling it by manipulating the XML then applying SetXfa() with ITextSharp, but the PDF does not change. Here is my method :

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 已正确修改,我检查过.这是正确的方法吗?你知道接下来要尝试什么吗?感谢您的帮助!

The XML is correctly modified, I checked. Is this the correct way ? Do you have any idea what to try next ? Thank you for your help !

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

XML file : https://drive.google.com/file/d/1EbZJM6TjZ5tXQ0Dxa6IeUDz3QgJuxsBi/view?usp=sharing Please let me know if there's any issue with the download, and open it in Acrobat to see the content.

推荐答案

一般问题

您的 PdfStamper 写入的流是 MemoryStream ms

PdfStamper stamper = new PdfStamper(reader, ms);

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

and you completely ignore its contents after closing the stamper, i.e. finishing the stamping

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

return;

因此,您的更改将丢失.

Thus, your changes are lost.

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

Instead you can return the manipulated PDF as byte array to the caller, simply declare the method return type as byte[]

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

并返回内存流内容

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

return ms.ToArray();

特定的 XML 更改问题

无论何时您想要操作 XML 文件,不要手动操作,请使用 XML API,例如DOM;每隔一段时间就会出现这样一种情况,其中手动构建 XML 看起来更简单,但通常这种外观具有欺骗性,您最终会因为这样做而陷入困境.

Specific XML changing issues

Whenever you want to manipulate a XML file, don't do it manually, use a XML API, e.g. DOM; every once in a while a situation pops up in which building XML manually appears simpler but usually that appearance is deceptive, you eventually get into trouble for doing so.

特别是在您手头已有一个 XmlNode:xfa.DatasetsNode 的情况下.您可以简单地使用给定的名称设置其所有子项,如下所示:

In particular in the case at hand you already have a XmlNode: xfa.DatasetsNode. You can simply set all its children with a given name like this:

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

sets the "Ablehnungsgrund/Hinweis" field value to "Gruuuuuuund".

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

Beware, the second parameter has been renamed from key to xpath because now it is not expected to contain an empty XML element "<key />" anymore but instead an xpath "//key".

是不是 denn das,da plötzlich 是 schnell auf mich zukommt 吗?所以sehr,sehr schnell.所以 riesig 和 so flach und so rund.Das braucht einen riesigen Namen … wie ….咕噜!

这篇关于如何填写 XFA pdf 文档的单个字段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆