好的,我必须使用C#以编程方式填写XFA PDF。我已经能够成功提取PDF的XML结构。但是,我使用AcroFields.Xfa.FillXfaForm(sourceXML)调用遇到了问题。
基本上发生的事情是:我正在使用整个XML树,编辑XML中的字段,然后尝试使用新XML编辑表单字段。我最终删除了所有AcroForm字段的PDF,没有添加新的输入。但是,当我解析这个编辑过的PDF并提取XML树时,我发现我的编辑内容已被保留。
此特定XFA PDF的安全设置允许编辑表单字段但是我被迫使用PdfReader.unethicalreading = true;我目前的设置(这就是我相信表单字段被剥离的原因)。我相信XFA PDF将我的XML编辑作为对文档格式的完整编辑。
到目前为止,这是我的代码:
命名空间ConsoleApplication2 { 课程 {
static void Main(string[] args)
{
System.IO.StreamWriter file = new System.IO.StreamWriter(@"E:\XMLOutPut\outPutTest.xml");
file.WriteLine(ReadFileNames());
file.Close();
using (FileStream existingPdf = new FileStream(@"E:\ORIGINAL.pdf", FileMode.Open))
{
using (PdfReader pdfReader = new PdfReader(existingPdf))
{
using (FileStream sourceXML = new FileStream(@"E:\XMLOutPut\outPutTest.xml", FileMode.Open))
{
using (FileStream targetPdf = new FileStream(@"E:\ORIGINAL.pdf", FileMode.Open))
{
PdfReader.unethicalreading = true;
PdfStamper stamper = new PdfStamper(pdfReader, targetPdf,'\0', true);
stamper.AcroFields.Xfa.FillXfaForm(sourceXML);
stamper.Close();
}
}
}
}
}
public static string ReadFileNames()
{
string SRC = @"E:\ORIGINAL.pdf";
using (PdfReader reader = new PdfReader(SRC))
{
return ReadXFA(reader);
}
}
public static string ReadXFA(PdfReader reader)
{
XfaForm xfa = new XfaForm(reader);
XmlDocument document = xfa.DomDocument;
reader.Close();
if (!string.IsNullOrEmpty(document.DocumentElement.NamespaceURI))
{
document.DocumentElement.SetAttribute("xmlns", "");
XmlDocument newDoc = new XmlDocument();
newDoc.LoadXml(document.OuterXml);
document = newDoc;
}
var sb = new StringBuilder(4000);
var Xsettings = new XmlWriterSettings() { Indent = true };
using (var wrtier = XmlWriter.Create(sb, Xsettings))
{
document.WriteTo(wrtier);
}
return sb.ToString();
}
}
}
我开始相信我必须以某种方式遍历XML并提取出许多我想编辑的字段并按照这种方式进行操作?
非常感谢任何帮助。
亲切的问候。
答案 0 :(得分:3)
目前使用iText无法实现。您需要从文件中提取XFA(您可以使用iText执行此操作),然后遍历XFA结构以进行编辑,您必须使用其他工具进行编辑,然后重新编辑将XFA插入PDF,这可以使用iText完成。
答案 1 :(得分:0)
static void Main(string[] args)
{
using (FileStream existingPdf = new FileStream(SRC, FileMode.Open))
using (PdfReader pdfReader = new PdfReader(existingPdf))
using (FileStream targetPdf = new FileStream(Target, FileMode.Create))
{
PdfReader.unethicalreading = true;
using (PdfStamper stamper = new PdfStamper(pdfReader, targetPdf, '\0', true))
{
XfaForm form = new XfaForm(pdfReader);
XDocument xdoc = form.DomDocument.ToXDocument();
var nodeElements = from nodeElement in xdoc.Descendants("form1").Descendants("A1")
select nodeElement;
foreach (XElement singleNodeElement in nodeElements)
{
if (singleNodeElement.Name == "A1")
{
singleNodeElement.Value = "LOLGG";
}
}
XmlDocument xmlDoc = xdoc.ToXmlDocument();
XmlNamespaceManager namespaces = new XmlNamespaceManager(xmlDoc.NameTable);
namespaces.AddNamespace("xfa", "http://www.xfa.org/schema/xfa-data/1.0/");
XmlNode baseNode = xmlDoc.SelectSingleNode("//xfa:datasets", namespaces);
stamper.AcroFields.Xfa.FillXfaForm(baseNode);
}
}
}
}
public static class DocumentExtensions
{
public static XmlDocument ToXmlDocument(this XDocument xDocument)
{
var xmlDocument = new XmlDocument();
using (var xmlReader = xDocument.CreateReader())
{
xmlDocument.Load(xmlReader);
}
return xmlDocument;
}
public static XDocument ToXDocument(this XmlDocument xmlDocument)
{
using (var nodeReader = new XmlNodeReader(xmlDocument))
{
nodeReader.MoveToContent();
return XDocument.Load(nodeReader);
}
}
}
Alrighty大家所以除了Linq和Xml.Linq之外,还可以使用iText进行此操作,如上面的代码示例所示。
为了实现这一点,我们必须使用XMLDocument并将其转换为XDocument,然后使用Linq遍历节点。一旦我们能够获得正确的节点,我们就必须添加一个命名空间来正确识别前缀。然后,我们不得不将XDoc格式转换回XMLDoc格式,以便使用iText中的FillXfaForm。