6

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

正如我发现的那样,有几种可能的方法:

  1. 使用 adobe acrobat 创建的 pdf 表单并用 itextsharp 填充。
  2. 使用 adobe acrobat 创建的 pdf 表单并用 FDF Toolkit .net 填充它(这似乎在内部使用 itextsharp)
  3. 美元 pdfkt 填写表格。
  4. 使用 adobe livecycle 创建的 pdf 表单文件,并使用表单数据集成服务合并数据

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

先感谢您。

4

3 回答 3

3

如果可能的话,我建议使用第 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 页面的响应中

于 2010-04-19T19:57:28.227 回答
0

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

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

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

使用 LiveCycle Designer 创建表单。

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

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

于 2010-04-16T14:31:16.310 回答
0

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

  1. 设置PdfReader.unethicalreading = true以防止BadPasswordException。
  2. 在 PdfStamper 的构造函数中设置附加模式,否则 Adob​​e 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");
        }
    }
}

请参阅如何使用 iText 填写 XFA 表单?

于 2014-12-13T12:09:38.023 回答