微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在不破坏使用权限的情况下填写 XFA

如何解决在不破坏使用权限的情况下填写 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();

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。