pdf - 在不破坏使用权的情况下填写 XFA
问题描述
我有一个 XFA 表单,我可以通过提取 XML 修改并回写来成功填写该表单。如果您拥有完整的 Adobe Acrobat,则效果很好,但使用 Adobe Reader 会失败。我已经看到关于同一件事的各种问题的答案,但它们是前一段时间的,所以更新 Adobe Reader 可读的 XFA 可能不再可行?我在下面使用此代码,并且像 iText 示例中一样使用了 append 的 StampingProperties,但仍然失败。我正在使用 iText 7.1.15。
//open file and write to temp one
PdfDocument pdf = new(new PdfReader(FileToProcess), new PdfWriter(NewPDF), new StampingProperties().UseAppendMode());
PdfAcroForm form = PdfAcroForm.GetAcroForm(pdf, true);
XfaForm xfa = form.GetXfaForm();
XElement node = xfa.GetDatasetsNode();
IEnumerable<XNode> list = node.Nodes();
foreach (XNode item in list)
{
if (item is XElement element && "data".Equals(element.Name.LocalName))
{
node = element;
break;
}
}
XmlWriterSettings settings = new() { Indent = true };
using XmlWriter writer = XmlWriter.Create(XMLOutput, settings);
{
node.WriteTo(writer);
writer.Flush();
writer.Close();
}
//We now how to strip an extra xfa line if updating
if(update)
{
string TempXML= CSTrackerHelper.MakePath($"{AppContext.BaseDirectory}Temp", $"{Guid.NewGuid()}.XML");
StreamReader fsin = new(XMLOutput);
StreamWriter fsout = new(TempXML);
string linedata = string.Empty;
int cnt = 0;
while (!fsin.EndOfStream)
{
if (cnt != 3 && linedata != string.Empty)
{
fsout.WriteLine(linedata);
}
linedata = fsin.ReadLine();
cnt++;
}
fsout.Close();
fsin.Close();
XMLOutput = TempXML;
}
xlogger.Info("Populating pdf fields");
//Now loop through our field data and update the XML
XmlDocument xmldoc = new();
xmldoc.Load(XMLOutput);
XmlNamespaceManager xmlnsManager = new(xmldoc.NameTable);
xmlnsManager.AddNamespace("xfa", @"http://www.xfa.org/schema/xfa-data/1.0/");
string[] FieldValues;
string[] MultiNodes;
foreach (KeyValuePair<string, DocumentFieldData> v in DocumentData.FieldData)
{
if (!string.IsNullOrEmpty(v.Value.Field))
{
FieldValues = v.Value.Field.Contains(";") ? v.Value.Field.Split(';') : (new string[] { v.Value.Field });
foreach (string FValue in FieldValues)
{
XmlNodeList aNodes;
if (FValue.Contains("{"))
{
aNodes = xmldoc.SelectNodes(FValue.Substring(0, FValue.LastIndexOf("{")), xmlnsManager);
if (aNodes.Count > 1)
{
//We have a multinode
MultiNodes = FValue.Split('{');
int NodeIndex = int.Parse(MultiNodes[1].Replace("}", ""));
aNodes[NodeIndex].InnerText = v.Value.Data;
}
}
else
{
aNodes = xmldoc.SelectNodes(FValue, xmlnsManager);
if (aNodes.Count >= 1)
{
aNodes[0].InnerText = v.Value.Data;
}
}
}
}
}
xmldoc.Save(XMLOutput);
//Now we've updated the XML apply it to the pdf
xfa.FillXfaForm(new FileStream(XMLOutput, FileMode.Open, FileAccess.Read));
xfa.Write(pdf);
pdf.Close();
仅供参考,我也尝试直接设置一个字段,结果也相同。
PdfReader preader = new PdfReader(source);
PdfDocument pdfDoc=new PdfDocument(preader, new PdfWriter(dest), new StampingProperties().UseAppendMode());
PdfAcroForm pdfForm = PdfAcroForm.GetAcroForm(pdfDoc, true);
XfaForm xform = pdfForm.GetXfaForm();
xform.SetXfaFieldValue("VRM[0].CoverPage[0].Wrap2[0].Table[0].CSID[0]", "Test");
xform.Write(pdfForm);
pdfDoc.Close();
如果有人有任何想法,将不胜感激。干杯
解决方案
推荐阅读
- docker - Cassandra 的 cqlsh 无法连接到任何服务器:最后一个错误:[SSL] 内部错误 (_ssl.c:727)")
- javascript - 在浏览器(网络)中查看 Firebase 云消息传递注册令牌时出现问题
- c# - 为没有身份的 .net 核心创建定制的第 3 方授权
- python - Selenuim,如何更改 webdriver.Remote 中的 $cdc_ 变量
- answer-set-programming - 确定两个派系是否不同
- c# - C# Excel 编程获取特定范围并创建 .csv 文件
- sql - 仅当 A、B 分组超过限制时,Oracle 才获取 A、B、C、D 列的列表- 需要查询帮助
- kubernetes - Kubernetes Auth Type 在 Airflow 中不能用作 VaultBackend
- python - 从服务器上的 PC 使用 Selenium Webdriver 调用 Python 脚本
- sql - Postgres 列“值”不存在