在Sql Reporting Services 2005中优化大型报表的PDF导出

时间:2020-03-05 18:40:32  来源:igfitidea点击:

首先,我了解运行超大型/长期运行的报告是一个可怕的主意。我知道微软有一条经验法则,规定SSRS报告的执行时间不超过30秒。但是,由于外部力量(例如遵守州法律),有时庞大的报道是首选的邪恶之举。

在我的工作地点,我们有一个asp.net(2.0)应用程序,已从Crystal Reports迁移到SSRS。由于庞大的用户群和复杂的报告UI要求,我们提供了一组屏幕,这些屏幕可以接受用户输入的参数并创建要在夜间运行的时间表。由于该应用程序支持多个报告框架,因此我们不使用SSRS的计划/快照功能。系统中的所有报告均由计划的控制台应用程序生成,该应用程序采用用户输入的参数,并使用创建报告的相应报告解决方案生成报告。对于SSRS报告,控制台应用程序会生成SSRS报告,并通过SSRS Web服务API将其导出为PDF。

到目前为止,除了我们最近已将25,000页的报表从Crystal报表转换为SSRS之外,SSRS的处理要比Crystal容易得多。 SSRS服务器是一台64位2003服务器,具有32个运行SSRS 2005的内存。我们所有较小的报告都可以正常运行,但是对于这样的较大报告,我们遇到了麻烦。不幸的是,我们似乎无法通过Web服务API生成修订报告。在生成/导出大约30-35分钟内会发生以下错误:

异常消息:基础连接已关闭:接收时发生意外错误。

我相信我们之前都已经看过Web服务调用:

data = rs.Render(this.ReportPath, this.ExportFormat, null, deviceInfo,
   selectedParameters, null, null, out encoding, out mimeType, out usedParameters, 
   out warnings, out streamIds);

奇怪的是,如果使用报表管理器直接在报表服务器上运行该报表,则该报表将运行/渲染/导出。生成报告数据的proc运行大约5分钟。大约12分钟后,报告将以SSRS本机格式呈现在浏览器/查看器中。通过报表管理器中的浏览器/查看器导出为pdf需要额外的55分钟。这可以可靠地工作,并产生高达1.03gb的pdf。

以下是一些我想通过Web服务API来使报表正常工作的更明显的事情:

  • 在报表服务器上将HttpRuntime ExecutionTimeout值设置为3小时
  • 禁用的HTTP在报表服务器上保持活动
  • 增加了报表服务器上的脚本超时
  • 将报告设置为永不超时在服务器上
  • 在客户端呼叫上将报告超时设置为几个小时

从我尝试过的调整中,我很自在地说任何超时问题都已消除。

根据对错误消息的研究,我认为Web服务API默认情况下不会发送分块响应。这意味着它将尝试在一个响应中通过导线发送所有1.3gb的数据。在某个时候,IIS会丢掉毛巾。不幸的是,该API抽象了Web服务配置,因此我似乎找不到找到启用响应分块的方法。

  • 是否有人知道在不减少总页数的情况下减少/优化PDF的导出阶段或者PDF的大小?
  • 有没有办法为SSRS打开响应分块?
  • 还有其他人对它为什么在服务器上运行而不通过API运行有其他理论吗?

编辑:阅读kcrumley的文章后,我开始通过考虑文件大小/页面数来查看平均页面大小。有趣的是,在较小的报表上,数学公式可以计算得出,因此每页大约为5K。有趣的是,当报表变大时,此"平均值"会增加。例如,一份8000页的报告平均每页超过40K。很奇怪。我还将补充说,除了每个分组中的最后一页之外,还设置了每页的记录数,因此,在某些页面上的记录比另一页面多的情况下,情况并非如此。

解决方案

回答

Does anyone know of anyway to
  reduce/optimize the PDF export phase
  and or the size of the PDF without
  lowering the total page count?

我有一些想法和问题:
1.这是大量图形报告吗?如果不是,我们是否具有以文本开头但被SSRS PDF渲染器转换为图形的表(检查是否可以在PDF中选择文本)?每页41K可能多于或者应该多于41K,具体取决于报表的信息密集程度。但是在某些情况下,报表的布局存在一些小问题,例如表格渗入页面的页边空白,导致SSRS PDF渲染器"举起手来"并将表格渲染为图像而不是文本。显然,报告中的图形越少,文件大小就越小。
2.有没有一种方法可以轻松地将报告分成几部分?例如,如果是10个位置的报告,则在最终报告中,位置1之后是位置2等,我们是否可以独立于位置2部分运行位置1部分等?如果是这样,我们可以在收到全部10个子报表后,使用PDFSharp将它们合并为一个最终PDF。这会给页编号带来一些困难,但是没有什么是不可克服的。

3. Does anyone else have any other
  theories as to why this runs on the
  server but not through the API?

我的猜测是报告的绝对规模。我不记得有关什么是IIS设置以及特定于SSRS的所有信息,但是可能需要更新某些总体IIS设置(也许在Metabase.xml中),以允许大量数据通过。

我们可以通过获取一份工作报告并使用WAITFOR(假设将SQL Server用于DBMS)在存储过程中建立较长的等待时间,从而确定是否是时间问题。

本质上不是解决方案,而是想法。希望能帮助到你。

回答

显然,它是一份庞大的报告,实际上它比报告更接近1.3 GB数据库。

我们是否考虑过将其拆分为多个部分然后将它们组合在一起的方法? (使用几种不同方式之一来组合此站点上列出的PDF。)