【问题标题】:How to combine several Crystal reports in one PDF如何在一个 PDF 中合并多个 Crystal 报表
【发布时间】:2016-10-24 18:12:27
【问题描述】:

我需要生成 5 个 Crystal 报表并将它们合并到一个 PDF 文件中。最初我想用这 5 个报告创建一个报告作为子报告,然后将其输出为 PDF。但是,这是行不通的,因为这些报表中的每一个都已经有子报表,并且不支持子报表中的报表。

我想我需要在幕后将每个报告输出为 PDF,然后使用 iTextSharp 之类的东西来组合这些报告。我找到了一些例子,但没有一个真正适用于我的情况。我将不胜感激此任务的任何代码示例。

谢谢。

【问题讨论】:

    标签: c# pdf crystal-reports


    【解决方案1】:

    如果您要将它们手动组合成一个 PDF,我会使用 PDFSam 免费版。

    但是,如果您想使用 Crystal Reports 来实现,为什么不使用子报表并将它们全部合并为一个呢?

    https://youtu.be/xxwWFAtGSIM?t=1m06s

    【讨论】:

    • 谢谢。我在帖子中提到过,我的每个报表都已经有子报表,水晶报表不支持子报表内的子报表。
    【解决方案2】:

    您可以编写自己的应用程序将两个报告导出为 PDF,然后使用其中一个开源项目将它们合并为 1 个 pdf。比如这个:https://sourceforge.net/projects/pdfmerge/

    您还可以获得可以为您执行此操作的现有应用程序之一。这个是免费的http://www.r-tag.com/Pages/CommunityEdition.aspx

    【讨论】:

      【解决方案3】:

      工作示例 [ c# ,使用 vs 2015 cm]- [根据您的观点.....没有更多文件 .in 服务器]

      1) Crystalreports 添加到名为“CrystalReport1.rpt , CrystalReport2.rpt”的示例项目[简单设计]

      2) 所需文件:(合并流)itext lib:https://www.nuget.org/packages/iTextSharp(命令 :: Install-Package iTextSharp -Version 5.5.11)

      3) 必需的命名空间

      using System;
      using System.IO;
      using System.Collections.Generic;
      
      using CrystalDecisions.CrystalReports.Engine;
      using CrystalDecisions.Shared;
      
      using iTextSharp.text;
      using iTextSharp.text.pdf;
      Step  1:  Reference code 
      
              //reploace this event to your related event .......
              protected void Page_Load(object sender, EventArgs e)
              {
                  //hold the more than one report outputs [bytes]
                  List<byte[]> files = new List<byte[]>();
      
                  //for testing purpose LOOP used,
                  //u can change as per your requirement and your report name
                  for (int i = 1; i <= 2; i++) {
      
                      ReportDocument crdReport1 = new ReportDocument();
      
                      //put your related report names.....
                      crdReport1.Load(Server.MapPath(string.Format("CrystalReport{0}.rpt", i)));
      
                      Stream stream1 = crdReport1.ExportToStream(ExportFormatType.PortableDocFormat);
      
                      //prepare the "bytes" from "stream"               
                      files.Add(PrepareBytes(stream1));
                      //finally the result added to LIST
                  }
      
                  Response.Clear();
                  Response.Buffer = true;
                  Response.ContentType = "application/pdf";     
      
                  //merge the all reports & show the reports            
                  Response.BinaryWrite(MergeReports(files).ToArray());
      
                  Response.End();        
              }
      

      第 2 步:参考代码(学分 ::https://stackoverflow.com/a/221941

      //准备报告字节

       private byte[] PrepareBytes(Stream stream)
          {          
              using (MemoryStream ms = new MemoryStream())
              {
                  byte[] buffer = new byte[stream.Length];
                  int read;
                  while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
                  {
                      ms.Write(buffer, 0, read);
                  }
                 return ms.ToArray();
              }           
          }
      

      第 3 步:参考代码(学分 :: https://stackoverflow.com/a/6780582

      //合并报表

      private MemoryStream MergeReports(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;
          }
      

      所以,您可以更改步骤中的逻辑:1(根据您的报告)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-06-21
        • 1970-01-01
        • 2013-03-03
        • 2018-03-11
        • 2018-06-11
        • 1970-01-01
        • 2011-02-12
        相关资源
        最近更新 更多