苹果的梦想...

享受自己的小快乐
关于Crystal Reports XI应用随笔

我使用的版本是11,这里之所以提一下版本是因为有些问题会因为版本的不同解决的方式也不是一样的。现在网上关于CR问题的解决方式大部分没有写版本号,这样可能导致有些对象或属性方法找来找去就是找不到,本人就曾遇到过这种问题。有点郁闷。。。
CR有两种构成方式一种是使用CR自身的Server,将做好的报表发布到Server上使用。Server会提供一整套的登录,权限的解决方案。其本上可以做到完全与系统脱离的独立报表系统,应该是应用在一些大的企业,反正本人没有用过。
我的应用是在ASP.NET下使用CrystaReportViewer控件在Webform上将做好的报表完整的展示出来。
首先设计报表,这里我一直不是很明白为什么设计的时候所需要的数据源必须要连接数据库才能获得,这样真是很麻烦。没有办法必须要从创建数据源开始,CR提供了非常丰富的数据库连接。其他的如ODBC,OLE DB等我就不说了,我使用的是ADO.NET(XML)没有什么理由总觉的在.NET下使用可能会“专业”一些,让各位见笑了。

ADO.NET(XML)可以识别三种文件格式,分别是XML,DLL,XSD(.net 数据集对象文件),我试了后两种遗憾的是DLL方式没有成功,报表不显示任何数据,并且没有出错信息。大体上是这样的我写一个类其中的一个方法是返回DataSet对象,然后编译成DLL文件在连接管理中引用。

有心的朋友可以试一下。然后就是XSD(.net 数据集对象文件)方式,需要在.NET中创建数据集对象。实际上这个数据集对象只是在设计的时候做为数据源向报表上添加需要显示的字段,在设计完成之后就可以删除了,但是这不是必须的,因为我在程序中会动态生成一个DataSet做报表的数据源为其提供数据。

说到这里需要提一下,CR的数据获取有两种方式”push”,”pull”。简单的理解”push”方式就是报表上所显示的数据需要外部程序通过dataset的方式提供给报表,然后进行显示。我就是使用这种方式,因为这种方式比较灵活,对于不是很熟悉CR内部函数的人是一个不错的选择。还有就是”pull”此种方式可以做到报表与程序之间只存在简单的调用与被调用关系,所有数据的获取以及计算均在CR内部完成。同样要求对CR有相当的认识程度。
关于CrystaReportViewer控件在安装.NET的过程有CrystaReport安装选项,只要选择安装就会在控件箱中自动显示出来。
if (reportDataSet == null || reportDataSet.Tables.Count == 0 || reportDataSet.Tables[0].Rows.Count == 0)
return;
// 设置设置报表的工具栏,以及各种工具按钮是否可用(这里版本9与11的设置方式有些不同)
// set toolbar for crystal report viewer
crystalReportViewer.HasCrystalLogo = false;
crystalReportViewer.HasSearchButton = false;
crystalReportViewer.HasToggleGroupTreeButton = false;
crystalReportViewer.HasViewList = true;
crystalReportViewer.HasExportButton = false;
// 设置打印模式,分为两种方式PDF,直接打印
rystalReportViewer.PrintMode = PrintMode.ActiveX;
string reportPath = Server.MapPath(string.Format(PropertyUtils.REPPATH, reportName));
// reportName是报表名称
ReportDocument doc = new ReportDocument();
doc.Load(reportPath);
doc.SetDataSource(reportDataSet);
//这是登录数据库所需要的参数信息,如果不设置在启动页面的时候会显示让用户输入数据库登录信息,登录之后才会显示报表。
doc.SetDatabaseLogon(PropertyUtils.USER, PropertyUtils.PASSWORD, PropertyUtils.SERVER, PropertyUtils.DATABASE);
crystalReportViewer.ReportSource = doc;
完成以上工作后,如果不出意外报表就可以显示了。
但是你会发现在点击工具栏上任意按钮后报表不见了,页面变成空白了。这真是让人郁闷的事情,原来CR在响应按钮事件需要刷新页面,要重走page_load,这样只需要将显示报表的代码写入page_load事件中就可以,但是如果报表是需要点击按钮或有条件触发那么就只能在page_load事件中再加些代码
If(IsPostBack){…//显示报表.}
至于为什么要重新刷页面我也不清楚,针对这个问题我只有这种解决方式了。如果有更好的解决办法可以学习一下。
还 有最重要的一项就是打印,如果不需要打印我想也不需要用CR做什么报表了。我总觉的CR在WEB应用打印上做的不好,除非你不用工具栏上的打印功能自己写打印功能。CR打印分两种试,一种是在点打印的时候将数据保存成PDF格式文件,然后用户再打开文件进行打印,我想用户根本不会接收这种方式的。另一种就是直接将数据传到打印机直接打印。但是恶心的地方是如果客户端需要以这种方式进行打印的时候是需要下载安装一个客户端打印插件“PrintControl.cab”,否则你仍然是不能进行打印。真是不太了解BO是怎么考虑的,还好我们可以把插件下载后放与程序一起部署到服务器上,然后当用户第一次打印的时候,通过设置客户端浏览器的安全级别可以让插件自动下载安装,并完成打印。
需要在WEB配置文件进行以下配置 :
<sectionGroup name="businessObjects">
              <sectionGroup name="crystalReports">
                   <section name="printControl" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, Custom=null"/>
              </sectionGroup>
         </sectionGroup>
     </configSections>
     <businessObjects>
         <crystalReports>
              <printControl>
                   <add key="url" value="http://localhost/Reports/PrintControl.cab"/>
              </printControl>
         </crystalReports>
     </businessObjects>
下载printcontrol.cab从:http://support.businessobjects.com/CRforVS2005/PrintControl.cab#
注意这是针对VS2005的,其他版本是否可用不清楚。
打印的问题也解决了,运行报表显示一切正常,开始打印但问题又出来了,报表上所有中文部分全打成方框了。
而 中文部分是从数据库中查出的,检查报表原来CR详细区的显示标签没有设置成中文字符集。从网上的资料上看到有说可以设置WEB配置文件中字符集,我没有试过,个人觉得这只是用来解决页面显示的问题,而打印功能是CR以及CrystalReportViewer自己提供的所以应该不会跟设置配置文件有关系吧。
这样似乎整个过程已经完成了,但是再我连接点击N次工具栏上的前后翻页按钮后程序终于崩溃了。
The maximum report processing jobs limit configured by your system administrator has been reached.
于是开始仔细检查程序看看是否有写的不妥的地方,但没有发现不合理的地方。查资料后终于弄清楚原来出错原因还是在CR上。
发现水晶报表会在注册表中注册,并限制了打印数量为75,更改以下注册表内容:
HKEY_LOCAL_MACHINE\Software\Business Objects\Suite 11.0\Report Application Server\ImProcServer\PrintJobLimit
将PrintJobLimit改为-1,然后重启动计算机后,问题解决。
希望能对遇到相同问题朋友一些帮助。

posted on 2009-04-23 21:22  Redkey  阅读(614)  评论(0)    收藏  举报