首页 > 解决方案 > 在不破坏使用权的情况下填写 XFA

问题描述

我有一个 XFA 表单,我可以通过提取 XML 修改并回写来成功填写该表单。如果您拥有完整的 Adob​​e Acrobat,则效果很好,但使用 Adob​​e Reader 会失败。我已经看到关于同一件事的各种问题的答案,但它们是前一段时间的,所以更新 Adob​​e 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();

如果有人有任何想法,将不胜感激。干杯

标签: pdfitext7adobe-readerxfa

解决方案


推荐阅读