【问题标题】:How to fill a single field of an XFA pdf document?如何填写 XFA pdf 文档的单个字段?
【发布时间】:2019-05-11 08:23:34
【问题描述】:

我的 Pdf 包含一个带有空白字段的 XFA 表单。我尝试通过操作 XML 然后使用 ITextSharp 应用 SetXfa() 来填充它,但 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 中打开查看内容。

【问题讨论】:

  • 您不必删除问题的former version 并重新创建它;这只会让你的问题更难找到。

标签: c# pdf itext adobe


【解决方案1】:

一般问题

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 文件时,不要手动操作,使用 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 元素 "&lt;key /&gt;",而是 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 ….咕噜!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-21
    • 2020-03-15
    • 1970-01-01
    相关资源
    最近更新 更多