我的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中将其打开以查看内容。
答案 0 :(得分: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 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
重命名为xpath
,因为现在预计它不再包含空的XML元素"<key />"
,而是xpath "//key"
是ist denn das,daplötzlich是schnell auf mich zukommt吗?谢尔,谢尔·施奈尔。所以riesig和so flach和so rund。 Das braucht einen riesigen Namen…wie…。 und!