Reporting Services 5: Extensions & Custom Report Item (上)

    在Reporting Services 4: Web Service中,我们介绍的是SSRS可编程性的一个方面Web Service,这篇随笔继续介绍RS可编程性的另一个方面—— Extensions,Microsoft的官方文档称之为“扩展插件”。

    说到Microsoft的官方文档,有点废话要说:我们知道,Oracle的产品很好,但是它被人诟病的地方是产品文档太烂,当然不是说没有中文文档,而是说它的文档(无论中文还是英文)不容易被阅读。至于Microsoft的官方文档,当然主要是指MSDN了, Microsoft英文网站上已经开始提供SQL Server 2005 Books Online (July 2006)”下载了,在这个页面上改变一下语言为简体中文,就变成了SQL Server 2005联机丛书(2006 年 4 月),感情我们中文文档要比英文文档落后仨月呀。当然了,这是玩笑话,我倒宁愿相信是Microsoft只是工作有点滞后而已,事实上,我装了4月的文档看了一下,东西还是都有的,只是有的没有翻译成中文而已。然而,当我尝试阅读这些英文文档的时候,发现有些东西说的不是很清楚,关联性比较差。当然了,这里面不排除中英文写作习惯的差异以及我的阅读能力的问题。至于前面扯到的Oracle文档的问题,源于最近读Microsoft的一些已经翻译成中文的文档总有一种以前读Oracle文档的错觉,往往不知所云,很是郁闷。

    在设计SSRS的结构时,Microsoft考虑到了可能出现的用户需求(这种需求来源于商业报表的复杂性),并为开发人员预留了充分的扩展空间,使得开发人员可以使用托管代码扩展SSRS的功能,而Extensions就是现有报表处理功能之外的被报表处理器调用以实现特定处理功能的.NET程序集。目前,Microsoft提供的SSRS Extensions主要有:数据处理扩展插件(Data Processing Extension)、传递扩展插件(Delivery Extension)、身份验证扩展插件(Security Extension)以及呈现扩展插件(Redering Extension)。为什么说“目前”呢,呵呵,这是因为我在浏览Microsoft的文档的时候发现:一开始的时候,Microsoft只提供了前两种扩展,后两种扩展插件是后来才出现的,这里面不排除是后两种扩展插件的文档是后来才出现的可能,当然也不排除Microsoft将来会推出其它的针对 SSRS的扩展插件的可能。


图1 SSRS架构

    上图是根据http://img.microsoft.com/sql/reporting/productinfo/rsarchitecture.gif修改的图,四个绿色背景鹅黄色高亮显示部分所指的就是Extensions的四种主要分类,它们分布在整个报表生命周期(报表
制作、报表管理、报表传输以及报表安全)的各个不同阶段。图中的“SSRS配置目录”在原文中是“SQL Server Catalog”,单从名称来看,这个是非常不容易理解的,另外很多可以找到的关于SSRS 的PPT都引用了这个图,可惜没有现场听过他们的讲座,不是很明白它的意思。不过,据我的猜想,“SQL Server Catalog”应该指的是SSRS的配置信息,另一种可以替换的名称是“Report Server Database”,具体点就是在安装、配置SSRS的时候在数据库引擎中生成的两个数据库 ReportServer和ReportServerTempDB,这里面存储着报表服务器使用的信息,包括报表定义、元数据、缓存报表、快照、相关的资源、安全设置、帐户信息、共享计划以及有关Extensions的信息等,具体的内容可以参考Management Studio中名为ReportServer的数据库。至于这一点,似乎也可以在图2中得到证实。


图2 SSRS架构关系图(来源:http://msdn2.microsoft.com/zh-cn/library/ms155792.aspx

    图2比图1更清晰地描绘了SSRS的架构,特别地标明了几种Extensions与其它SSRS组件之间的关系。至于其中的“报表处理扩展插件(Report Processing Extension)”比较特殊,将在下面提到。

    对于报表服务器来说,必须至少同时具备一个身份验证扩展插件、一个数据处理扩展插件和一个呈现扩展插件,而传递扩展插件是可选的。

    对于开发人员来说,在研究和使用SSRS中已有插件的同时,总是希望可以自己通过扩展插件来扩展SSRS的功能,下面就从“自定义”的角度阐述一下扩展插件的功能(即图1中红色黑体标志的“自定义”):

    1、数据处理扩展插件——商业报表的数据源很可能是多种多样的,并不局限于SSRS对数据源的现有支持。例如,组织很可能希望从某种固定格式的平面文件中获取数据,这个时候开发人员可以利用数据处理扩展插件完成针对这种特定平面文件的数据获取:打开到数据源的链接、分析查询并返回字段名称、传递参数、获取数据集等。

    2、传递扩展插件——如果组织希望以电子邮件或文件共享之外的方式向终端报表用户分发报表(或者这样说,如果终端报表用户希望使用电子邮件或文件共享之外的方式订阅报表),就需要使用传递扩展插件将报表以特定的格式向特定的设备进行传输。比如将报表传输到一个FTP服务器上或使用NNTP协议将报表发送到新闻组上等。

    3、呈现扩展插件——在SSRS中,报表可以以HTML、Excel、文本、XML、图像(BMP/EMF/GIF/JPEG/PNG/TIFF/WMF)以及PDF等文件格式呈现。呈现扩展插件可以将报表的布局和数据以特定文件格式输出以便将报表分发到不同的平台或设备上。另外,呈现扩展插件甚至可以将报表呈现为网页中的一个HTML表格片段,这样即使不使用IFrame控件也可以轻松将报表集成到自己的页面中。考虑到呈现扩展插件开发的复杂性,我们可以使用一个替代的方案:首先将报表呈现为一个XML文件,然后使用XSLT将其格式化为其它文件格式,例如,Excel的文件格式可以被看成是一个带有Excel特有标记(如<x:ExcelWorkbook>、<x:ExcelWorksheets>等)的MHTML文件,在这种情况下这种替代方案就是可行的。SSRS 2000在呈现时就认为Excel的文件格式是一个带有Excel特有标记的MHTML文件。

    4、身份验证扩展插件——身份验证事实上包含两层含义:授权和验证,目前SSRS使用的是基于Windows的身份验证。身份验证扩展插件可以使SSRS以自定义的方式向用户授权以及验证用户是否具有访问报表服务器上资源的权限。需要注意的是,RS在某一时点只能使用一种方式进行身份,即要么使用Windows安全模式,要么使用所有自定义安全模式中的一种。

    如果你安装了SQL Server示例,那么你可以在示例文件夹/Reporting Services/Extension Samples目录中找到FormsAuthentication、FsiDataExtension以及PrinterDelivery这三个示例分别对应身份验证扩展插件、数据处理扩展插件和报表传递扩展插件。至于呈现扩展插件,看看前面罗列的文件格式,常用的文件格式基本上都已经被Microsoft 扩展过了,所以Microsoft并没有提供这方面的示例,当然这里面还有一个原因就是呈现扩展插件的开发比较困难。我Google到了一篇关于 Reporting Services Extensions的文章How hard is it to write Reporting Services extensions?,作者Bryan认为,这四种Extensions的编程难度按照从易到难的顺序排列为:数据处理扩展插件<传递扩展插件<身份验证扩展插件<呈现扩展插件。

    好了,以上所列举的四种扩展插件由于经常同时出现,可以算作是狭义上的SSRS Extensions。事实上(包括从语义上),任何对SSRS进行功能性扩展的程序集都可以算作是SSRS Extensions,我们将之称为广义上的SSRS编程扩展,比如语义查询(Semantic Query)、报表模型的生成、事件处理等,甚至连在报表中通过引用外部程序集而使用的自定义代码也应该算在内。而接下来要详细介绍的 Custom Report Item是SSRS Extensions中最出彩的一个。

    在BIDS中设计RDL报表时,开发人员面对的控件有文本框、折线图、表格、矩阵、矩形、列表、图像、子报表、图表等九种。这些控件单独或组合起来基本上可以满足我们设计报表的需要,然而在实际应用中由于商业报表的复杂性,还是可能出现一些例外情况,例如有一个网友就曾问我如何在报表中添加雷达图,而图表控件又不支持雷达图这种图表类型。在这种情况下,当当当当,Custom Report Item就应运而生了。

    事实上,我对于Custom Report Item的兴趣源于之前看过的两个for Reporting Services的第三方产品:Barcode Professional for Microsoft SQL Server Reporting ServicesDundas Gauge for Reporting Services,前者是条形码,后者是仪表。Dundas大家应该都知道,这是业界非常有名的图表方案提供商,其实它们都是Microsoft的报表方案合作商,可以通过这个URLhttp://www.microsoft.com/sql/reporting/partners/component.asp上的企业链接了解更多关于SSRS编程扩展的信息。有了Custom Report Item,开发人员自己也可以实现和图3所示一样酷的报表了。


图3 Dundas Gauge for Reporting Services实现的报表(点击小图看大图)

    Custom Report Item,Microsoft称之为“自定义报表项”(只有这个汉语名称,除此之外目前没有汉语文档)。可以将自定义报表项理解为是对报表定义语言(RDL)的扩展,它允许开发人员通过开发新控件或延伸现有控件的功能来扩展现有的RDL

    如果您安装的SQL Server示例是最新版本的SQL Server 2005 Samples and Sample Databases (July 2006),那么在目录示例文件夹/Reporting Services/Extension Samples中会发现一个 PolygonsCustomReportItem的示例,这在旧版本的示例中是没有的。有趣的是在“添加或删除程序”中看到的旧版本号为9.00.1354,而新版本号是9.00.060710.00,时光倒流了,呵呵……


    自定义报表项由两个相对独立的部分组成:设计时组件和运行时组件。下面结合一个实例来介绍自定义报表项的开发,这个示例可以让报表设计人员在报表中以会计帐簿中显示金额的样式来显示报表中的金额数据。

    一、设计时组件

    在BIDS报表设计环境中使用的控件,和标准控件一样,设计时组件提供拖曳操作、控件属性、自定义菜单项和自定义属性编辑器等的定义,以实现报表设计人员与报表设计环境的交互,方便报表设计人员在报表中放置控件、设置控件属性等的操作。

    设计时组件继承自Microsoft.ReportDesigner.CustomReportItemDesigner类 ,并且需要定义一个CustomReportItem属性,如下面的代码所示——

代码1:设计时组件

    在添加上面的代码之前,需要创建一个名为AmoneyDesigner的C#类库,添加对 Microsoft.ReportingServices.Designer和Microsoft.ReportingServices.Interfaces的引用,这两个dll分别位于目录Y:/Program Files/Microsoft Visual Studio 8/Common7/IDE/PrivateAssemblies和X:/Program Files/Microsoft SQL Server/90/SDK/Assemblies中。

   代码2展示了控件的自定义属性的设置——

代码2:设计时组件的自定义属性

     代码2中的自定义属性的具体含义可以通过图4的示意帮助理解,不详细叙述。


图4 代码2中控件自定义属性的具体含义示意

    代码2中的GetCustomProperty()和SetCustomProperty()分别用于读取和设置自定义属性的值,它们是通过调用 CustomProperties这个包含了处理控件时使用的自定义属性的Dictionary来完成的。自定义属性存储在定义报表布局的.rdl文件中,.rdl文件是基于XML的(如代码3所示),所以自定义属性的值只能以一个字符串的形式被读取或设置,Microsoft的PolygonsCustomReportItem示例将控件的所有自定义属性都设置为string类型,这样的话会造成报表设计者在操作上的麻烦。例如,代码2中的NormalColor属性,如果设置为 string类型,那么在控件发布后属性浏览器中只能使用一个TextBox来编辑它的值,而报表设计人员很可能不会像开发人员那么熟练地操作针对颜色的一个字符串值;所以,代码2中使用System.Drawing.Color作为NormalColor属性的类型,这样,报表设计人员在属性浏览器中面对的就是一个下拉的颜色选择器而已,只是开发人员在获取或设置该属性时需要做相应的处理,如代码2中采用的方法是在一个表示Windows颜色值的字符串和一个GDI+ Color结构之间进行互换。另外,代码2中所示的自定义属性的名称前面都加了限定名AMoney,这是为了与其它控件相区别以避免重复。

代码3:RDL中自定义报表项的XML片断

    对自定义报表项的设计时组件的自定义属性进行设置以后,我们可以得到类似代码3的XML片断,就是说 CustomReportItemDesigner类的对象模型与基于XML的RDL文件之间产生了一种对应——CustomProperties属性与<CustomProperties>元素之间的对应。

    CustomProperties之外另一个自定义报表项的重要属性是CustomData,CustomData用于定义自定义报表项要使用的数据,毕竟一个完整意义上的报表不能只有布局而无数据。RDL中自定义报表项所使用的数据的分组、排序、筛选和聚合是通过DataSetName、 Filters、DataColumnGroupings、DataRowGroupings、DataRows和DataCell等子元素来指定的,而这些在自定义报表项的设计时组件中同样可以通过CustomReportItemDesigner类的对象模型来设定。

    需要注意的是,一旦为自定义报表项指定了CustomData属性,自定义报表项在报表中就会表现为一个“数据区域(Data Region)”,数据区域是数据绑定的报表项,用于显示来自数据集的多行数据。而本文的示例是一个用于会计金额显示的自定义报表项,它和现有的文本框控件是相似的,只是用于显示一个金额形式的具体数值,不需要也不能像列表、表格或矩阵这样的数据区域那样为其指定数据源,也就是说,数据区域的数据来自于一个二维表,而非数据区域报表项(例如本文的示例)的数据是一个具体的值。当需要显示一个数据集中的连续记录时,我们只需要将非数据区域报表项(例如本文的示例)嵌入到一个数据区域的详细信息中,而所有数据区域报表项在报表中的位置是受到一定限制的,如不可以出现在详细信息、页眉以及页脚中,需要指出的是,所有的自定义报表项也都不可以出现在页眉和页脚中,但是非数据区域自定义报表项可以出现在详细信息中。也许有人要问,那你这个示例是不是只能为其指定一个类似于123456.78这样的具体数值显示为会计金额的样式,而不能从报表的数据源中读取并显示数据呢?答案是,就像文本框控件一样,本文的示例可以通过为自定义属性 MoneyValue指定类似于代码3中的“=Sum(Fields!金额.Value)”的表达式来读取报表数据源中的数据;同时,我们知道,表格控件其实是由一系列文本框组成的,本文的示例也可以像文本框控件一样嵌入到表格控件的详细信息行中从而读取并显示表格控件绑定的数据集的连续记录中的数值型字段的值。而这一切都不需要任何额外的处理,因为在报表运行的时候会自动将报表定义中出现的任何表达式自动转化为该表达式经过计算后对应的具体数值;数据区域报表项则不同,需要逐行遍历DataCells集合并使用DataValues集合读取数据集中的数据并显示在报表上, Microsoft的PolygonsCustomReportItem就是一个数据区域自定义报表项,对CustomData的处理可以参考该示例。

    RDL中的XML元素可以参考Report Definition XML Elements。这部分文档(包括该链接所在树状目录的子链接)对自定义报表项开发的参考意义可以说是非常大的,从这些文档中我们可以知道:哪些XML元素在自定义报表项中是被支持的,哪些XML元素在是数据区域或非数据区域报表项所特有的,哪些XML元素是必有的而哪些元素又是可选的以及可以出现的次数等等。例如,<CustomData>是被自定义报表项 <CustomReportItem>所支持的,但是它在<CustomReportItem>元素中的出现是可选的,只有当<CustomReportItem>是数据区域时才出现(<CustomData>元素可以出现0次或1次),而一旦出现了<CustomData>元素,就必须伴随出现一次其子元素 <DataColumnGroupings>(<DataColumnGroupings>元素在<CustomData>元素出现时必须出现1次)。由于RDL元素与 CustomReportItemDesigner类的对象模型的对应关系,这对我们理解CustomReportItemDesigner类的对象模型也是很有帮助的,例如,我们可以推论出何时应该实例化一个CustomData并应该为其设定哪些必要的属性等等。

    好了,继续来看本文的示例。代码2中,我们看到,在设置完控件的属性后需要调用Invalidate()方法将控件在报表设计器中进行重绘,那么如何绘制图4中所示的报表设计器中的控件样式呢?我们只需要使用GDI+重写OnPaint事件就可以了:

代码4:在报表设计器中绘制控件外观

    每次更改控件的和样式相关的自定义属性时都会通过Invalidate()方法的调用触发代码4中的OnPaint事件,从而改变控件在报表设计环境中的外观(外观如图4所示)。

    下面的代码通过添加组件的设计时谓词(desinger verb)为设计时组件添加自定义的如图5所示右键菜单用于添加和减少组件所显示的单元个数:

代码5:为控件添加自定义右键菜单


图5 设计时组件的自定义右键菜单

    在报表设计器中,当我们向一个图表控件拖动字段时或者在一个已选定的图表控件上单击鼠标左键时,我们会发现图表控件本身的矩形区域之外出现了三个显示“将XX字段拖至此处”的矩形框,如图6所示,Microsft称之为“装饰(Adornment)”,装饰用来处理鼠标点击、大小调整、拖放操作等与用户交互的行为,这是.Net Framework 2.0中才有的概念,可以参考行为服务概述及该页面上的相关链接。


图6 图表控件的装饰

    代码6为本文的设计时组件添加一个简单的装饰(如图7所示),主要用于处理向控件拖放字段时与用户的交互。


图7 设计时组件的装饰

代码6:为设计时组件添加装饰

    由于篇幅的关系,AMoneyDesignWindow类的实现请参考本文后面提供的示例下载中的文件AMoneyDesignWindow.cs。

   

转自:http://www.cnblogs.com/waxdoll/archive/2006/08/22/483817.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值