c# - 如何填写 XFA pdf 文档的单个字段?
问题描述
我的 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 中打开以查看内容。
解决方案
一般问题
您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 看起来更简单,但通常这种外观具有欺骗性,您最终会因此而陷入麻烦。
特别是在手头的情况下,您已经有一个XmlNode
: xfa.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
to重命名,xpath
因为现在它不再包含空 XML 元素"<key />"
,而是包含 xpath "//key"
。
ist denn das, was da plötzlich so schnell auf mich zukommt?所以sehr,sehr schnell。所以 riesig 和 so flach und so rund。Das braucht einen riesigen Namen … wie …. 咕噜!
推荐阅读
- javascript - 在查看时如何为 CSS 动画制作动画?
- wordpress - 警告:输入中的意外字符:'' (ASCII=127) state=0
- java - 尝试运行 derby 时在 Eclipse 上“找不到或加载主类 org.apache.derby.tools.ij”
- c# - Atlassian.Net SDK 获取所有项目和冲刺
- python - 如何在索引数据框中用 0 替换 NaN 值
- string - 在 Active Directory 路径中转义 * 通配符
- c# - 比较 System.Threading.Tasks 的两个对象
- cordova - 如何在 vuejs + cordova 应用程序中使用 cordova 多图像选择器插件?谁能逐步告诉我?
- git - 如何查看 git push 历史日期,而不是提交日期
- java - 在 Java 中调用静态方法的正确方法是什么?