合并内存流以在c#中创建http PDF响应

时间:2011-07-21 15:36:21

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

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

  1. 以pdf格式将Crystal报表导出到MemoryStream1
  2. 将第二个报告导出到MemoryStream2。
  3. 合并内存流
  4. 将流发送到Http输出响应为PDF。
  5. 以下是订单中每个步骤的代码。

       /// 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);
    

    对于第3步

      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;
        }
    

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

      // 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();
    

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

    Chandanan。

1 个答案:

答案 0 :(得分:9)

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

    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();