代码之家  ›  专栏  ›  技术社区  ›  Giorgi

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

  •  6
  • Giorgi  · 技术社区  · 16 年前

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

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

    1. 使用adobe acrobat创建的pdf表单并用itextsharp填充它。
    2. 使用adobe acrobat创建的pdf表单并用fdf toolkit.net填充它(它似乎在内部使用itextsharp)
    3. 填写表格需支付美元。
    4. 使用adobe livecycle创建的pdf表单文件并使用 Form Data Integration Service

    由于我对这类任务没有经验,你能建议哪种选择更好/更容易,并给出一些额外的建议吗?

    提前谢谢你。

    3 回复  |  直到 11 年前
        1
  •  3
  •   Jonathan    16 年前

    如果可能的话,我建议使用第四种方法,因为这样会更干净。你将使用专门为你要求做的事情量身定做的解决方案,但如果你没有这样一个解决方案的可用资源,我建议使用第一个选项。

    第一个选择是我最近涉足的领域。我发现实施起来相对没有痛苦。

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

    1. 您可以控制pdf表单的开发。
    2. 您可以控制XML数据的格式
    3. 你可以忍受没有压缩的(fastweb=false)pdf文件

    实施示例:

    1. 使用Adobe Acrobat生成PDF表单。提示:生成表单时使用Adobe原生字体。对于您添加的每个不是本机字体的控件,它将导入使用的字体,并在未压缩时膨胀文件,据我所知,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页的响应

        2
  •  0
  •   o-o    16 年前

    既然你标记了这个“livecycle”,我想你已经在某个地方安装了adobelivecycle(可选的, 可以 安装在某处)。

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

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

    使用livecycle设计器创建表单。

    快速脏选项如下:将表单设置为http post(例如xfdf,请参阅acrobat以获取更多信息)并将其发布到asp服务器上(确保用户在打开表单之前不要下载表单,否则这将不起作用)。表单必须在Web浏览器中打开)。然后简单地捕获提交的内容,就像从web页面捕获http帖子一样。(可选)将填充保存到数据库。然后将捕获的xfdf流填充发送回客户端(也可以在稍后通过http链接调用)。xfdf流将包含用于填写它的表单的url。客户端Web浏览器将要求Acrobat/Adobe Reader插件处理XFDF流,插件将定位、下载并填充XFDF指向的表单。

    用户现在应该可以保存表单了,并且它是填充的-不需要读卡器扩展!

        3
  •  0
  •   Community Mohan Dere    9 年前

    你也可以使用 伊斯特克利普 将XML数据填充到 读卡器扩展 启用的窗体。有两件事你需要正确设置:

    1. 集合 PdfReader.unethicalreading = true 预防 密码异常。
    2. 集合 附加模式 在pdfstamper的构造函数中,否则 Adobe Reader扩展 签名被破坏,Adobe Reader将显示以下消息: “本文档包含在Adobe 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?