itextsharp / MCV使用字节将多个表单合并为一个PDF

时间:2012-11-17 21:42:20

标签: c# asp.net-mvc itextsharp

您好我的applion是MVC3 c#,我使用itextsharp为预先分散的表单生成PDF文件。在这个应用程序中,我有不同的形式。要生成我使用的表单:

public ActionResult TestPDF(long learnerID = 211, long courseID = 11)
{
    var caseList = _studyCaseSvc.ListStudyCases().Where(x => x.Course_ID == courseID);
    try
    {
        MemoryStream memoryStream = new MemoryStream();
        PdfConcatenate whole = new PdfConcatenate(memoryStream);
        foreach (var ca in caseList)
        {
            byte[] part = null;
            if (ca.CaseType == "CTA")
            {
                part = GenerateEvaluationCAT_PDF(learnerID, ca.ID);
            }
            else if (ca.CaseType == "CTAH")
            {
                part = GenerateEvaluationCATH_PDF(learnerID, ca.ID);
            }
            else
            {
                part = null;
            }
            if (part != null)
            {
                PdfReader partReader = new PdfReader(part);
                whole.AddPages(partReader);
                partReader.Close();
            }
        }

        whole.Close();
        byte[] byteInfo = memoryStream.ToArray();
        SendPdfToBrowser(byteInfo);
    }
    catch (Exception ex)
    {
    }
    return null;
}

我收到此错误:已添加具有相同键的项目。该错误发生在AddPages。所以我开发了这个更简单的测试:

private void merge()
    {
        try
        {
            FileStream output = new FileStream("p3.pdf", FileMode.Create);
            PdfConcatenate pdfConcatenate = new PdfConcatenate(output, true);

            PdfReader r1 = new PdfReader("p2.pdf");

            MemoryStream memoryStream = new MemoryStream();
            PdfStamper pdfStamper = new PdfStamper(r1, memoryStream);

            pdfStamper.FormFlattening = true;
            pdfStamper.Close();
            PdfReader r2 = new PdfReader(memoryStream.ToArray());

            //pdfConcatenate.AddPages(tempReader);

            pdfConcatenate.Open();
            int n = r1.NumberOfPages;
            for (int i = 1; i <= n; i++)
            {
                PdfImportedPage imp = pdfConcatenate.Writer.GetImportedPage(r1, i);
                pdfConcatenate.Writer.AddPage(imp);
            }
            pdfConcatenate.Writer.FreeReader(r1);

            pdfStamper.Close();
            r1.Close();
            pdfConcatenate.Close();
        }
        catch (Exception ex)
        {
        }
    }

同样的错误。

1 个答案:

答案 0 :(得分:1)

嗯,问题在于你可以通过简单连接将多个PDF文件合并为一个误解。对于PDF来说这是错误的(就像大多数二进制文件格式错误一样)。

因此,您应该更新您的GenerateAllEvaluation_PDF方法以使PdfConcatenate实例而不是您的字节数组整体,参见http://api.itextpdf.com/itext/com/itextpdf/text/pdf/PdfConcatenate.html,打开PdfReader中GenerateEvaluationCATH_PDF方法返回的每个字节数组,将这些读取器的所有页面添加到PdfConcatenate,最后返回该类生成的字节。

编辑(我更喜欢Java而不是C#,因此原谅了小错误)

PdfConcatenate whole = new PdfConcatenate(...);
foreach (var ca in caseList)
{
    byte[] part = null;
    if (ca.CaseType == "CTA")
    {
        part = GenerateEvaluationCAT_PDF(learnerID, ca.ID);
    }
    else if (ca.CaseType == "CTAH")
    {
        part = GenerateEvaluationCATH_PDF(learnerID, ca.ID);
    }
    else
    {
        part = ???;
    }
    PdfReader partReader = new PdfReader(part);
    whole.AddPages(partReader);
    partReader.Close();
}

PdfConcatenate可以用MemoryStream构造,你可以从中检索最后的字节[]。

PS PdfConcatenate可能不是iTextSharp版本4.x的一部分,但它只是PdfCopy和PdfSmartCopy的便利包装器。因此,您可以简单地看一下iTextSharp(毕竟是OSS)的来源并受到启发:PdfConcatenate.cs