【问题标题】:Merging/filling pdf form file with xml data使用 xml 数据合并/填充 pdf 表单文件
【发布时间】:2011-02-06 08:15:15
【问题描述】:

假设我在网站上有一个 pdf 表单文件,由用户填写并提交给服务器。在服务器端(Asp.Net)我想将我收到的 xml 格式的数据与填充的空 pdf 表单合并并保存。

我发现有几种可能的方法:

  1. 使用 adobe acrobat 创建的 pdf 表单并使用 itextsharp 填写。
  2. 使用 adobe acrobat 创建的 pdf 表单并使用 FDF Toolkit .net 填充(内部似乎使用 itextsharp)
  3. 使用 pdfkt 填写表格。
  4. 使用 adobe livecycle 创建的 pdf 格式文件,并使用 Form Data Integration Service 合并数据

由于我对此类任务没有经验,您能否建议哪个选项更好/更容易并提供一些额外的提示?

提前谢谢你。

【问题讨论】:

    标签: asp.net xml pdf itextsharp livecycle


    【解决方案1】:

    由于您标记了此“LiveCycle”,我认为您在某处运行了 Adob​​e LiveCycle 安装(可选,可以将其安装在某处)。

    在这种情况下,我会选择 4 号(使用 Adobe LiveCycle Forms ES 模块进行修改)。从长远来看,其他三个无疑会产生兼容性问题。使用 LiveCycle 服务器(运行表单模块),您将能够处理任何 PDF,无论是旧的、新的、静态的、动态的、压缩的、基于 Acrobat 的还是基于 LiveCycle 的。 p>

    您应该能够进行设置,让表单将其数据发送到 LiveCycle 服务器,并使用该数据填充表单。然后可以将填写的内容存储在服务器的数据库中,或路由到 PDF 表单(或任何其他表单)中并流回客户端。

    使用 LiveCycle Designer 创建表单。

    quick-and-dirty-option 如下:将表单设置为 http-post(例如 xfdf,请参阅 Acrobat 了解更多信息)到您的 ASP 服务器并将其发布到服务器上(确保您的用户在打开表单之前不要下载表单,否则这将不起作用。表单必须在 Web 浏览器中打开)。然后像从网页中捕获 http-post 一样简单地捕获提交。或者,将填充保存到数据库中。然后将捕获的 xfdf 流填充发送回客户端(也可以在稍后阶段通过 http 链接调用)。 xfdf 流将包含用于填写它的表单的 URL。客户端 Web 浏览器将要求 Acrobat/Adobe 阅读器插件处理 xfdf 流,该插件将定位、下载并填充 xfdf 指向的表单。

    用户现在应该能够保存表单并填写 - 无需阅读器扩展!

    【讨论】:

    • @Christian - 我需要将 pdf 文件保存在服务器上,而不是在用户端。
    【解决方案2】:

    如果可能,我建议使用第 4 种方法,因为它会更干净。您将使用专门为您的要求量身定制的解决方案,但如果您没有此类解决方案的可用资源,我建议您使用第一个选项。

    第一个选项是我最近投入的。我发现实施起来相对容易。

    如果满足以下条件,选项 1 是可能的:

    1. 您可以控制 PDF 表单的开发。
    2. 您可以控制 xml 数据的格式
    3. 您可以忍受未压缩 (fastweb=false) 的 PDF 文件

    实现示例:

    1. 使用 Adob​​e Acrobat 生成 PDF 表单。提示:生成表单时使用 Adob​​e Native Fonts。对于您添加的每个不是本机字体的控件,它将导入使用的字体并在文件未压缩时使文件膨胀,据我所知,ITextSharp 目前不生成压缩的 PDF。

    2. 使用 ITextSharp 库将 XML 数据与 PDF 表单结合以生成填充文档。提示:要从 xml 手动填充 PDF 表单,您必须将 xml 值映射到 PDF 表单中的控件名称并按页面匹配它们,如下例所示。

      using (MemoryStream stream = GeneratePDF(m_FormsPath, oXmlData))
      {
            byte[] bytes = stream.ToArray();
            Response.ContentType = "application/pdf";
            Response.BinaryWrite(bytes);
            Response.End();
      }
      
      // <summary>
      // This method combines pdf forms with xml data
      // </summary>
      // <param name="m_FormName">pdf form file path</param>
      // <param name="oData">xml dataset</param>
      // <returns>memory stream containing the pdf data</returns>
      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("/form/page" + i + "/*"))
          {
              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;
      }
      
    3. 保存文件或将文件发布到您的 ASP.Net 页面的响应中

    【讨论】:

      【解决方案3】:

      您还可以使用 iTextSharp 将 xml 数据填充到启用 Reader Extension 的表单中。您需要正确设置两件事:

      1. 设置PdfReader.unethicalreading = true 以防止BadPasswordException。
      2. 在 PdfStamper 的构造函数中设置 附加模式,否则 Adobe Reader Extensions 签名会损坏,Adobe Reader 将显示以下消息:“此文档包含某些权限在 Adob​​e Reader 中启用特殊功能。文档自创建以来已更改,这些权利不再有效。请联系作者获取此文档的原始版本。"

      所以你需要做的就是:

      PdfReader.unethicalreading = true;
      using (var pdfReader = new PdfReader("form.pdf"))
      {
          using (var outputStream = new FileStream("filled.pdf", FileMode.Create, FileAccess.Write))
          {
              using (var stamper = new iTextSharp.text.pdf.PdfStamper(pdfReader, outputStream, '\0', true))
              {
                  stamper.AcroFields.Xfa.FillXfaForm("data.xml");
              }
          }
      }
      

      How to fill XFA form using iText?

      【讨论】:

        猜你喜欢
        • 2012-10-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-25
        相关资源
        最近更新 更多