您的位置:首页 > 其它

Reporting Services 5: Extensions & Custom Report Item

2006-08-22 23:34 162 查看
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的扩展插件的可能。

namespace Waxdoll.ReportingServices
public string GetCustomProperty(string propertyname)

public void SetCustomProperty(string propertyname, string value)

[Browsable(true), Category("Appearance"), Description("普通线的颜色")]
public Color NormalColor

//FractionColor略

//KiloColor略

[Browsable(true), Category("Appearance"), Description("分割线的粗细"), DefaultValue(1)]
public int LineBorderWidth

//LineSpacing略

[Browsable(true), Category("Data")]
public string MoneyValue
<CustomReportItem Name="aMoney1">
<Left>3.5cm</Left>
<Top>2.25cm</Top>
<Type>AMoney</Type>
<Width>9cm</Width>
<Height>0.75cm</Height>
<CustomProperties>
<CustomProperty>
<Name>AMoney:FractionColor</Name>
<Value>4194432</Value>
</CustomProperty>
<CustomProperty>
<Name>AMoney:KiloColor</Name>
<Value>8421440</Value>
</CustomProperty>
<CustomProperty>
<Name>AMoney:NormalColor</Name>
<Value>0</Value>
</CustomProperty>
<CustomProperty>
<Name>AMoney:LineBorderWidth</Name>
<Value>2</Value>
</CustomProperty>
<CustomProperty>
<Name>AMoney:LineSpacing</Name>
<Value>15</Value>
</CustomProperty>
<CustomProperty>
<Name>AMoney:MoneyValue</Name>
<Value>=Sum(Fields!金额.Value)</Value>
</CustomProperty>
</CustomProperties>
</CustomReportItem>
对自定义报表项的设计时组件的自定义属性进行设置以后,我们可以得到类似代码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事件就可以了:

private void DrawSepLine(Graphics pGraphics, Color pColor, int pLoop)

public override void OnPaint (PaintEventArgs e)
private IComponentChangeService changeService;

public IComponentChangeService ChangeService()

private DesignerVerbCollection verbs;

public override DesignerVerbCollection Verbs

private void OnPlusCellCount(object sender, EventArgs e)

private void OnMinusCellCount(object sender, EventArgs e)
public override Adornment Adornment

public override void OnDragEnter (DragEventArgs e)
private void cmbMoneyValue_SelectedIndexChanged(object sender, EventArgs e)

<?xml version="1.0" encoding="utf- 16" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition"
xmlns:rdl="http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition">
<xsl:output omit-xml-declaration="no"/>
<xsl:template match="/rdl:Textbox">
<CustomReportItem>
<Type>AMoney</Type>
<Top><xsl:value-of select="rdl:Top"/></Top>
<Left><xsl:value-of select="rdl:Left"/></Left>
<Height><xsl:value-of select="rdl:Height"/></Height>
<Width><xsl:value-of select="rdl:Width"/></Width>
<CustomProperties>
<CustomProperty>
<Name>AMoney:FractionColor</Name>
<Value>255</Value>
</CustomProperty>
<CustomProperty>
<Name>AMoney:KiloColor</Name>
<Value>32768</Value>
</CustomProperty>
<CustomProperty>
<Name>AMoney:NormalColor</Name>
<Value>13882323</Value>
</CustomProperty>
<CustomProperty>
<Name>AMoney:LineBorderWidth</Name>
<Value>1</Value>
</CustomProperty>
<CustomProperty>
<Name>AMoney:LineSpacing</Name>
<Value>14</Value>
</CustomProperty>
<CustomProperty>
<Name>AMoney:MoneyValue</Name>
<Value><xsl:value- of select="rdl:Value"/></Value>
</CustomProperty>
</CustomProperties>
</CustomReportItem>
</xsl:template>
</xsl:stylesheet>
这个XSLT文件是比较简单的,主要功能是取得文本框控件中可以用到的属性值并在合适的位置指定给会计金额显示控件,需要将TextboxConverte.xslt文件的生成操作设置为“嵌入的资源”。有了XSLT文件,我们还需要一个用于实际转换操作的类 AMoneyConverter,该类从接口Microsoft.ReportDesigner.Design.IReportItemConverter继承,并需要实现Convert()方法,具体代码限于篇幅原因请参考本文提供的下载中的文件AMoneyConverter.cs。

好了,一个功能完备的自定义报表项的设计时组件的实现就介绍完了,图11展示了设计时组件的架构。

namespace Waxdoll.ReportingServices
<ReportItems>
<ReportItem Name="AMoney" Type="Waxdoll.ReportingServices.AMoneyCRI, AMoneyCRI"/>
</ReportItems>
步骤3中,rssrvpolicy.config是报表服务器的安全配置文件,为了使报表服务器具有访问自定义报表项的运行时组件,我们需要在其中添加以下配置信息:

<CodeGroup
class="UnionCodeGroup"
version="1"
PermissionSetName="FullTrust"
Description="This code group grants AMoneyCRI.dll FUllTrust permission. ">
<IMembershipCondition
class="UrlMembershipCondition"
version="1"
Url="C:\Program Files\Microsoft SQL Server\MSSQL.3 \Reporting Services\ReportServer\bin\AMoneyCRI.dll" />
</CodeGroup>
另外,示例中的另外一个配置文件RSReportDesigner.config用于存储有关可用于报表设计器的扩展插件的设置,我们在其中添加了如下配置信息分别用于告知报表设计器我们添加了何种自定义报表项,该报表项使用何种设计器以及报表设计器中文本框控件通过什么向该自定义报表项进行转换。

<ReportItems>
<ReportItem Name="AMoney" Type="Waxdoll.ReportingServices.AMoneyCRI, AMoneyCRI"/>
</ReportItems>
<ReportItemDesigner>
<ReportItem Name="AMoney" Type="Waxdoll.ReportingServices.AMoneyDesigner, AMoneyDesigner" />
</ReportItemDesigner>
<ReportItemConverter>
<Converter Source="Textbox" Target="AMoney" Type="Waxdoll.ReportingServices.AMoneyConverter, AMoneyDesigner" />
</ReportItemConverter>
步骤4、5中的两个批处理文件分别用于复制修改后的配置文件以及解决方案生成的dll文件和pdb文件到指定的目录中。

好了,配置部署完毕,来看一下,自定义报表项的运行情况(测试Demo)。



图13 包含自定义报表项的报表的运行情况

好了,到目前为止,一切都结束了。这篇超长随笔的目的之一是为了让大家更清楚地了解SSRS的功能,其实功能是无限扩展的,这是任何轻量级报表工具所无法比拟的;另外一个目的无非是抛砖引玉,我相信,随着对报表设计的需要,一定会有非常好的报表扩展插件和自定义报表项被我们中国人所开发出来,因为中国的报表难啊!

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: