如何填写 XFA pdf 文档的单个字段? [英] How to fill a single field of an XFA pdf document?
问题描述
我的 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屋!