主要说说关于SSRS的安装、部署和配置问题。
Reporting Services作为SQL Server的一个组件,自然是要伴随SQL Server一起安装了。目前SQL Server 的诸多版本,只有Enterprise和Development版本有着对SSRS的完全支持,Standard版本提供了大部分支持,具有高级功能的Express版只支持一些最基本的功能(不含设计器)。因此,在企业部署的时候应该选用Enterprise版,作为开发者应选择Development版。
在安装SQL Server的过程中选中Reporting Services的相关组件,或者更改一个SQL Server的安装以添加SSRS都是可行的。
注意上面说的是服务器端的安装。SQL Server 2005 Development Edition的组件分为服务器和工作站两个部分。在安装完服务器端的相关组件后,还需要在进行开发的机器(可以就在服务器上,也可以是另外的工作站)安装工作站组件。其中的Business Intelligence Development Studio必须安装,这是一个Visual Studio 2005的扩展,如果机器已经安装过VS2005,那它就会直接将BI的开发模板集成进 VS中,如果没有装过,那它则会自动替你安装一个VS2005外壳(没有C#、VWD等组件)。
服务器端配置SSRS有两种方法,一是通过SQL Server Management Studio,登录到Server进行操作;二是通过web访问服务器的Report Manage页面,比如http://IP/Reports。两种方法在功能上略有差别,具体操作过程可以查看相关文档。
这一部分来讨论一下SSRS的一些基本功能,即报表的建立、发布和引用。
报表设计环境就是那个Business Intelligence Development Studio,以下简称BI。如果项目是在VS2005下进行的,那么就非常方便了,因为可以在一个Solution里像添加普通Project一样来添加BI的工程。事实上我们也是这么做的。
在正式开始利用BI开发SSRS之前,强烈建议大家把随机附带的Book Online里的相关教程全部手动完成一遍。
总的来说,一个报表的设计可以归纳为下面的步骤:
设计完报表之后,就要将其发布到Reporting Services服务中,以供调用。我们可以把这个发布称作deploy。
经过实际应用,发现可以有下面三种方法来进行报表的发布
我们设计报表是在BI中进行的,可以利用它来一次性将整个报表工程deploy到服务器上。大致步骤如下:
完了之后会显示http://localhost/ReportServer这个页面,在这个页面中显示的就是该报表服务器上所有的ReportFolder,而报表则会按照deploy时的设置,分别保存在这些folder内。进入Folder之后,点击报表即可查看,系统已经为我们生成了一个带有ReportViewer的aspx页面。
下面这两种方法均是用来管理报表服务器,发布报表只是它们的一部分功能。
使用Report Manager的大致步骤如下:
这样就OK了,之后也可以在ReportServer页面下查看内容。
在SQL Server的配置中,这个工具无疑是最强大的。在登录SSMS的时候,选择Server Type为Reporting Services,然后指定Server的名称,以及登录方式。登录成功后,在Home目录下就是我们在Report Manager中看到的内容,后面的操作大同小异,就不浪费文字了。
建立、发布报表的最终目的还是为了在程序中引用它们,在此我们选择的是最简单的方法——使用ReportViewer控件。
WinForm下的ReportViewer控件,位于Microsoft.Reporting.WinForms命名空间下,在VS2005中默认会出现在ToolBar中,直接将其拖放进窗体即可对其操作。
一般来说,所有报表都必须设置的参数有以下几个:
对于实际应用,采用代码来控制ReportViewer要比设计时设置属性更加常用,下面就是一个简短的例子,概括了这样一个过程:
this.reportViewer1.ServerReport.ReportPath = "/Test/Report1"; List<ReportParameter> parameters = new List<ReportParameter>(); parameters.Add(new ReportParameter("params",textQueryString.Text)); this.reportViewer1.ServerReport.SetParameters(parameters); this.reportViewer1.ShowParameterPrompts = false; this.reportViewer1.RefreshReport();
在上面的过程中,先是设置ReportPath(ReportServerUrl在本示例中已经指定,实际上应该通过App.config的设置字符串来设置)。然后创建报表参数列表(这个params的名称是在设计报表的时候设置的报表参数,在SQL语句中通过@params进行引用),进而调用ServerReport的SetParameters方法,将参数传递给报表。紧接着,将报表的ShowParameterPrompts属性设为false,即不在ReportViewer的头部显示参数输入提示。最后执行RefreshReport()方法,刷新报表页面。
微软的统一性工作无疑是相当出色的,Web下的ReportViewer在使用起来与WinForm下完全相同,唯一不同的就是控件位于Microsoft.Reporting.WebForms下,而诸如ReportParameter等类也改为此命名空间之下。在代码控制报表方面,不需要进行改动即可移植。
在项目中,我们是采用VWG来作为程序的框架的。Gizmox开发团队也为ReportViewer设计了相应版本,控件位于Gizmox.WebGUI.Reporting命名空间下,但要注意,它的属性诸如ReportParameter、ProcessingMode等仍然是位于Microsoft.Reporting.WebForms下的,这一点不要搞错。
还记得前面提到过的http://ServerUrl/ReportServer吗?SSRS已经为我们准备了一个用来查看报表的方法,即通过URL访问,比如要查看在localhost/ReportServer服务器中,位于Test下的Report1报表,可以直接在浏览器中输入 http://localhost/ReportServer?Test/Report1,SSRS会自动调用一个系统内置的页面来显示它。在这个带参数的URL后面,我们可以通过附加URL参数的方法来对报表进行控制。比如上面的那个例子,在ASP.NET中可以使用Response.Write()向页面写入下面的代码来弹出窗口显示报表:
"<script language=\"JavaScript\"> window.open('http://localhost/ReportServer?Test/Report1¶ms=" + textQueryString.Text + "&rc:Parameters=false&rs:Command=Render'; </script>"
其中URL参数的构造方法请参阅MSDN相关文档。
上面说的都是常规应用,但实际上一个报表从提出需求到最后部署,绝大部分都不是会了那个示例就能做的,中间会遇到各种各样的问题。在这一部分中,我以问答的形式,将开发过程中遇到的问题以及解决方法分门类地列举出来,并且不断更新。
A:这是由于IIS下ReportServer虚拟目录的访问权限没有设置正确。解决问题的方法有三种:
A:其实我也不知道为什么。。。解决的方法是不用debug方式,直接在浏览器访问站点,就OK了。至于其原因,呼唤高人来解释~~~
A:当然可以,这都不行那SSRS也太圡了。。在这里需要用到报表语句。用过Excel吧,单元格的值如果用“=”开头,那后面就可以跟表达式,报表语句也一样。一个最简单的例子,比如像我现在想用参数传递一整条WHERE子句,就这么做:
注意这里的where后面有个空格,尤其是在构造SQL语句的时候,一定要特别注意空格的使用。
A:-_-|| 当然会出错,SQL语句中的where后面没有条件,语法不正确啊。。像这种情况,你得在表达式语句里做一个判断,看是否传入的参数为空。上面那个例子,就可以改为:
="select * from table1" + IIF(Parameters!WhereString.Value<>"", " where " + Parameters!WhereString.Value, "")
这里的IIF是报表语句的一种,属于Program Flow语句。至于更博大精深的用法,参阅文档~~
A:这还是要用到报表语句。进入Layout视图,在任意一个文本框右键点击然后选Expression,就是前面有个“fx”图标的那个,就能看到表达式编辑器。在左下的那个框 中列出的就是报表语句的类别,看到Globals了吗?点击一下,右边就会有一些关于报表本身的常量,那个PageNumber和TotalPages就是这里要用的。前面用到的Parameters和 IIF在这里也都能找到。灵活应用这些元素可以极大丰富报表的表现力。
哦,忘了说一点,PageNumber和TotalPages这两个量都只能在页眉或者页脚处才可使用,所以在用它们之前需要在Layout视图中,菜单Report->Page Header(或Page Footer),开启 页眉或页脚,然后在里面引用。
A:cft...你的眼睛欺骗了你。设计界面的那个页面边界其实跟你的纸张页面完全没有关系,SSRS也没有提供整页居中的功能,所以你必须一点点地微调你的页面布局。
首先我建议在菜单Report->Report Properties->Layout选项卡中,将左右Margin都改为0。然后回到设计界面,通过手动指定控件的Locate属性的方法,来确定左侧边界的大小。比如现在的纸张是A4大小(21cm*29.7cm),我的正文表格总宽度设置为17.75cm,剩下的3.25cm是左右页边距总和,按理说应该各分配1.625cm,但考虑到表格里的表格线也是有宽度的(我设的是1pt),因此将左页边距设为1.6cm,也就是把控件摆放在距离设计页面左侧1.6cm的位置,再说的明白点就是把靠左的各控件的Locate属性中的Left元素的值设为1.6cm(好多定语啊。。我不是故意的。。)。
进行预览的时候建议用ReportViewer的导出功能导出为pdf查看,也可以打印到pdf、xps,要是你再土豪一点,直接打印到纸上看是最好。这个微调是个痛苦的过程。
经过这一段时间的开发经历,个人感觉SSRS还是非常好用的,与SQL Server的无缝集成,layout的灵活多变以及报表语言的强大功能,加上微软产品的亲和性,带来的是清爽的使用体验。不过SSRS的执行效率并不高,尤其是SQL 2005版的SSRS在建立DataSet的时候还只能用SQL语句来查询,实现复杂的业务逻辑还不是很方便。并且在动态列显示以及动态页面设置还有待提高。