-1

我有一个 W9 PDF 文档,我正在为每个按钮单击的单个记录填充数据。现在客户想要创建一个文档,其中每条记录都是文档中的一个页面。下面是我们为每位员工创建 PDF 的代码。

    protected void lnkFillFields_Click(object sender, EventArgs e)
    {
        using (Library.Data.PDFData data = new Library.Data.PDFData())
        {
            try
            {   
                Document document = new Document();
                PdfCopy writer = new PdfCopy(document, Response.OutputStream);
                document.Open();

                foreach (EmployeeData emp in data.sp_select_employee_data())
                {
                    //Creates a PDF from a byte array
                    PdfReader reader =
                        new PdfReader((Byte[])data.sp_select_doc(16).Tables[0].Rows[0]["doc"]);

                    //Creates a "stamper" object used to populate interactive fields
                    MemoryStream ms = new MemoryStream();
                    PdfStamper stamper = new PdfStamper(reader, ms);

                    try
                    {
                        //MUST HAVE HERE BEFORE STREAMING!!!
                        //This line populates the interactive fields with your data.
                        //  false = Keeps the fields as editable
                        //  true  = Turns all of the editable fields to their read-only equivalent
                        stamper.FormFlattening = false;

                        //fill in PDF here

                        stamper.Close();
                        reader.Close();

                        MergePDFs(writer, ms);
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }

                }

                document.Close();

                //Stream the file to the user
                Response.ContentType = "application/pdf";
                Response.BufferOutput = true;
                Response.AppendHeader("Content-Disposition", "attachment; filename=W9"+ "_Complete.pdf");
                Response.Flush();
                Response.End();
            }
            catch (Exception ex)
            {
                throw ex;
            }

        }
    }

插入页面不是要走的路。相反,合并文档本质上是我们想要的。因此,我们提出了这个方法:

更新 下面是我们想出的方法,它成功地将新的 PDF 拼接到前一个 PDF 上。

    private static void MergePDFs(PdfCopy writer, MemoryStream ms)
    {
        PdfReader populated_reader = new PdfReader(ms.ToArray());
        //Add this pdf to the combined writer
        int n = populated_reader.NumberOfPages;
        for (int i = 1; i <= n; i++)
        {
            PdfImportedPage page = writer.GetImportedPage(populated_reader, i);
            writer.AddPage(page);
        }
    }

我们需要做的是在内存中创建所有这些,然后将其吐出给用户以供下载。

4

1 回答 1

1

在这里查看 kuujinbo 的教程,将 PDF 组合/拼接在一起。

在你这样做之前,你显然还需要生成 PDF。您可能很想尝试一次完成所有操作,这会奏效,但会更难调试。相反,我建议进行两次传递,第一次创建单个文档,第二次合并它们。您的第一遍可以暂时将它们写入磁盘或内存。您的代码(和 kuujinbo 的)实际上直接写入Response流,这也是完全有效的,但也更难调试,特别是如果您将所有内容包装在一个巨大的try/catch.

您要加入的 PDF 的数量和生成的频率应该决定您临时存储第一遍第二遍的位置。如果您只做一打或两个并且它们不是巨大的,我会坚持使用 aMemoryStream并使用其上的.ToArray()字节数据。

如果您有更多的 PDF,或者它们相当大,或者此例程经常被调用,或者您有 RAM 限制,您可能最好先将它们保存到一个唯一的文件夹,拼接它们,然后删除该文件夹。

于 2013-09-23T18:21:34.860 回答