【问题标题】:Merging Memory Streams to create a http PDF response in c#合并内存流以在 c# 中创建 http PDF 响应
【发布时间】:2011-10-10 08:38:05
【问题描述】:

我正在尝试将 2 个水晶报告合并到单个 pdf 文件中,并且我正在使用 Itextsharp v5.1.1。但它说文件无法打开。它可能已损坏。没有构建错误。但是pdf格式不正确,无法打开。这是我选择完成此操作的顺序。

  1. 将 Crystal 报表以 pdf 格式导出到 MemoryStream1
  2. 将第二个报告导出到 MemoryStream2。
  3. 合并内存流
  4. 以 PDF 格式将流发送到 Http 输出响应。

这是订单中每个步骤的代码。

   /// Get the Dataset from Stored Procedure for the CSSource Report
   dsCS = CSData.GetUSSourceXML(ds_input);
   /// Create the Report of type CSsource
   rptCS = ReportFactory.GetReport(typeof(CSsource));
   rptCS .SetDataSource(dsCS);
   /// Set the Parameters to the CS report
   rptCS .ParameterFields["Parameterid"].CurrentValues.Clear();
   rptCS .SetParameterValue("Parameterid", PID);
   //// Serialize the Object as PDF                    
   msCS=(MemoryStream)rptCS .ExportToStream(ExportFormatType.PortableDocFormat);

对于第 2 步

   /// Get the Dataset from Stored Procedure for the Aden Report
   dsAd = CSData.GetAdden(ds_input);
   /// Create the Report of type Aden
   rptAd = ReportFactory.GetReport(typeof(Aden));
   rptAd.SetDataSource(dsAd );
   /// Set the Parameters to the Aden report
   rptAd.ParameterFields["Parameterid"].CurrentValues.Clear();
   rptAd.SetParameterValue("Parameterid", PID);
   //// Serialize the Object as PDF                    
   msAD = (MemoryStream)rptAd.ExportToStream(ExportFormatType.PortableDocFormat);

第三步

  System.Collections.Generic.List<byte[]> sourceFiles = new List<byte[]>();
  sourceFiles.Add(msCS.ToArray());
  sourceFiles.Add(msAD.ToArray());
  PdfMerger mpdfs = new PdfMerger();
  /// ms is the Memory stream to which both the streams are added
  ms=mpdfs.MergeFiles(sourceFiles);

MergeFiles方法如下

 public MemoryStream MergeFiles(Generic.List<byte[]> sourceFiles)
    {
        Document document = new Document();
        MemoryStream output = new MemoryStream();

        try
        {
            // Initialize pdf writer
            PdfWriter writer = PdfWriter.GetInstance(document, output);
            //writer.PageEvent = new PdfPageEvents();

            // Open document to write
            document.Open();
            PdfContentByte content = writer.DirectContent;

            // Iterate through all pdf documents
            for (int fileCounter = 0; fileCounter < sourceFiles.Count; 
                   fileCounter++)
            {
                // Create pdf reader
                PdfReader reader = new PdfReader(sourceFiles[fileCounter]);
                int numberOfPages = reader.NumberOfPages;

                // Iterate through all pages
                for (int currentPageIndex = 1; currentPageIndex <=
                                   numberOfPages; currentPageIndex++)
                {
                    // Determine page size for the current page
                    document.SetPageSize(
                       reader.GetPageSizeWithRotation(currentPageIndex));

                    // Create page
                    document.NewPage();
                    PdfImportedPage importedPage =
                      writer.GetImportedPage(reader, currentPageIndex);


                    // Determine page orientation
                    int pageOrientation = 
                      reader.GetPageRotation(currentPageIndex);
                    if ((pageOrientation == 90) || (pageOrientation == 270))
                    {
                     content.AddTemplate(importedPage, 0, -1f, 1f, 0, 0,
                     reader.GetPageSizeWithRotation(currentPageIndex).Height);
                    }
                    else
                    {
                    content.AddTemplate(importedPage, 1f, 0, 0, 1f, 0, 0);
                    }
                }
            }
        }
        catch (Exception exception)
        {
        throw new Exception("There has an unexpected exception" +
        " occured during the pdf merging process.", exception);
        }
        finally
        {
           // document.Close();
        }
        return output;
    }

将内存流序列化为 PDF 的步骤 4

  // ms is the memory stream which is to be converted to PDF
  Response.Clear();
        Response.ClearContent();
        Response.ClearHeaders();
        Response.ContentType = "application/pdf";
        Response.Charset = string.Empty;
        Response.AddHeader("Content-Disposition", 
        "attachment; filename=" + 
        "Application of " + FullName.Trim() + ".pdf");
        //Write the file directly to the HTTP content output stream.
        Response.OutputStream.Write(ms.ToArray(), 0, 
               Convert.ToInt32(ms.Length));
        Response.OutputStream.Flush();
        Response.OutputStream.Close();
        rptCS.Close();
        rptCS.Dispose();
        rptAd.Close();
        rptAd.Dispose();

感谢所有帮助我解决此问题的开发人员。 这是紧急的,因为它必须在一两天内投入生产。 请回复。

钱达南。

【问题讨论】:

  • 你检查每个pdf本身是否正常吗?
  • 是的,他们正在单独工作,合并功能被注释掉。我可以看到每个报告。

标签: c# .net pdf crystal-reports itextsharp


【解决方案1】:

这是一种简单的合并方法,可将 PDF 文件复制到一个 PDF 中。我在合并 pdf 时经常使用这种方法。希望对您有所帮助。

    public MemoryStream MergePdfForms(List<byte[]> files)
    {
        if (files.Count > 1)
        {
            PdfReader pdfFile;
            Document doc;
            PdfWriter pCopy;
            MemoryStream msOutput = new MemoryStream();

            pdfFile = new PdfReader(files[0]);

            doc = new Document();
            pCopy = new PdfSmartCopy(doc, msOutput);

            doc.Open();

            for (int k = 0; k < files.Count; k++)
            {
                pdfFile = new PdfReader(files[k]);
                for (int i = 1; i < pdfFile.NumberOfPages + 1; i++)
                {
                    ((PdfSmartCopy)pCopy).AddPage(pCopy.GetImportedPage(pdfFile, i));
                }
                pCopy.FreeReader(pdfFile);
            }

            pdfFile.Close();
            pCopy.Close();
            doc.Close();

            return msOutput;
        }
        else if (files.Count == 1)
        {
            return new MemoryStream(files[0]);
        }

        return null;
    }

第 4 步尝试:

        rptCS.Close();
        rptCS.Dispose();
        rptAd.Close();
        rptAd.Dispose();

        Response.Clear();
        Response.ContentType = "application/pdf";
        Response.AddHeader("Content-Disposition", 
    "attachment; filename=" + 
    "Application of " + FullName.Trim() + ".pdf");
        Response.BinaryWrite(ms.ToArray());
        ApplicationInstance.CompleteRequest();

【讨论】:

  • 乔纳森,感谢您的回复。我使用了上面的代码,但我仍然认为这没有帮助。我遇到的错误是“无法打开封闭的流”。然后我在上面的函数中注释了3行代码如下。 //pdfFile.Close();//pCopy.Close();//doc.Close();然后没有运行时错误,然后我可以保存文件。但是当我打开它时,它像往常一样是空白的并且已损坏。您使用的是哪个版本的 Itextsharp?我正在使用最新的 5.1.1 版本。我可以尝试将您的版本与您的代码一起使用。非常感谢。
  • @Chandanan 我使用 itextsharp 5.1.0,这不应该是您的代码的问题。我认为您可能对第 4 步有疑问。请参阅我的编辑。
  • 乔纳森,我能得到这份工作!!!谢谢伙计,我所做的只是稍微改变了顺序。只需重新排序第 4 步并将这 4 行放在底部即可。 rptCS.Close(); rptCS.Dispose(); rptAd.Close(); rptAd.Dispose();非常感谢。 :)
  • 这是救命稻草。谢谢。
猜你喜欢
  • 1970-01-01
  • 2011-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-30
  • 2012-12-14
  • 2017-02-23
  • 2014-12-12
相关资源
最近更新 更多