使用xml数据合并/填充pdf表单文件

时间:2010-04-09 21:06:41

标签: asp.net xml pdf itextsharp livecycle

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

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

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

    由于我没有这种任务的经验,你能建议哪个选项会更好/更容易并提供一些额外的提示吗?

    提前谢谢。

3 个答案:

答案 0 :(得分:3)

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

第一个选项是我最近潜入的选项。我发现它实施起来相对轻松。

如果以下情况适用,则可以使用选项1:

  1. 您可以控制PDF表单的开发。
  2. 您可以控制格式化xml数据
  3. 您可以使用未压缩的(fastweb = false)PDF文件
  4. 实施示例:

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

    2. 使用ITextSharp Library将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页面的响应中

答案 1 :(得分:0)

由于你标记了这个'LiveCycle',我认为你在某个地方安装了Adobe LiveCycle(可选择可以在某处安装它)。

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

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

使用LiveCycle Designer创建表单。

快速和脏选项如下:将表单设置为http-post(例如xfdf,请参阅Acrobat以获取更多信息)到ASP服务器并将其发布到服务器上(确保您的用户在打开表单之前不会下载表单,否则这将无效。表单必须在Web浏览器中打开)。然后,只需捕获提交内容,就像从网页捕获http-post一样。 (可选)将填充保存到数据库。然后将捕获的xfdf流填充发送回客户端(也可以在稍后阶段通过http-link调用)。 xfdf流将包含用于填充它的表单的URL。客户端Web浏览器将要求Acrobat / Adob​​e reader插件处理xfdf流,插件将找到,下载并填充xfdf指向的表单。

用户现在应该可以保存表单并填写 - 不需要Reader Extension!

答案 2 :(得分:0)

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

  1. 设置PdfReader.unethicalreading = true以阻止 BadPasswordException。
  2. 在PdfStamper的构造函数中设置追加模式,否则 Adob​​e Reader Extensions 签名将被破坏,Adobe Reader将显示以下消息:&#34 ;本文档包含在Adobe Reader中启用特殊功能的某些权限。该文档自创建以来已更改,并且这些权限不再有效。请联系作者以获取本文档的原始版本。&#34;
  3. 所以你需要做的就是:

    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?