0

我需要实现一种方法,将 PDF 中的字段与 Adob​​e 生命周期中创建的表单合并。我将收到模板 PDF 和用于填充 PDF 的 XML,并且需要返回新填充的文件。xml 是这样的:

 <?xml version="1.0" encoding="UTF-8"?>
<form1>
    <ReportDescription>
      <body xmlns="http://www.w3.org/1999/xhtml" xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">
              <p><span style="font:Arial bold 12px">Name of the document</span></p>
          </body>
    </ReportDescription>
    <ReportCode>XX-000</ReportCode>
   <Contents>
      <UserData>
              <UserName>Ego ille</UserName>
              <UserPhone>Si manu vacuas</UserPhone>
              <UserNIF>999999999</UserNIF>
      </UserData>
   </Contents>
</form1>

所以,我有以下内容:

private MemoryStream GeneratePDF(string m_FormName, XmlDocument oData)
        {
            PdfReader pdfTemplate;
            PdfStamper stamper;
            PdfReader tempPDF;
            Document doc;
            MemoryStream msTemp;
            PdfWriter pCopy;
            MemoryStream msOutput = new MemoryStream();

            pdfTemplate = new PdfReader(m_FormName);

            doc = new Document();
            pCopy = new PdfCopy(doc, msOutput);

            pCopy.AddViewerPreference(PdfName.PICKTRAYBYPDFSIZE, new PdfBoolean(true));
            pCopy.AddViewerPreference(PdfName.PRINTSCALING, PdfName.NONE);

            doc.Open();

            for (int i = 1; i < pdfTemplate.NumberOfPages + 1; i++)
            {
                msTemp = new MemoryStream();
                pdfTemplate = new PdfReader(m_FormName);

                stamper = new PdfStamper(pdfTemplate, msTemp);

                // map xml values to pdf form controls (element name = control name)
                foreach (XmlElement oElem in oData.SelectNodes("/form1/*"))
                {
                    stamper.AcroFields.SetField(oElem.Name, oElem.InnerText);
                }

                stamper.FormFlattening = true;
                stamper.Close();
                tempPDF = new PdfReader(msTemp.ToArray());
                ((PdfCopy)pCopy).AddPage(pCopy.GetImportedPage(tempPDF, i));
                pCopy.FreeReader(tempPDF);

            }
            doc.Close();

            return msOutput;
        }
4

1 回答 1

0

您的问题有些误导:您谈到合并使用 Adob​​e LiveCycle 创建的表单。但是,当我查看您的代码时,我发现您实际上是在寻求合并普通 PDF。请允许我解释一下。

使用 Adob​​e LiveCycle 创建的表单可以生成两种类型的 PDF 文件。

  1. 包含 PDF 语法(AcroForm 技术)和 XML(XML 表单架构,又名 XFA)形式的表单的混合 PDF 文件。
  2. PDF 文件只不过是 XML 的容器。

可以使用核心 iText 库填写混合 PDF 文件。这在我的书的第 8 章中进行了解释。如果您将这样的表单展平,您将丢弃 XML 并保留 PDF 语法。从那一刻起,您就拥有了普通的 PDF 文件。

纯 XFA 表格可以用XFA Worker填写。XFA Worker 是一个建立在 iText 之上的闭源产品。它解析 PDF 容器内的 XML 并将此类 PDF 转换为普通 PDF。

根据您的问题,尚不清楚您在谈论哪种类型的 Adob​​e LiveCycle 表单,但由于您发布了有关它的问题,因此可以安全地假设您遇到了问题。查看您的代码,您假设您正在处理混合表单,如果该代码不起作用,我们反过来可以假设该表单是纯 XFA 表单。

一旦您成功填写并展平表单,您确实可以使用PdfCopy,尽管根据表单的性质,您可能更喜欢使用PdfSmartCopy(假设您正在合并同一模板的不同实例)。

这个答案基于很多假设。这解释了反对票和评论。

例如:假设您确实要求合并两个 XFA 表单(在 XML 语法的两个 PDF 容器的意义上),那么您的问题是无法回答的。只能合并展开的表单。

于 2013-12-26T08:34:30.040 回答