这一篇是关于 SQL Server 2005 Reporting Services 四篇文章中最后一篇:
Part 1 ,提供了创建基本报表的指南
Part 2 ,介绍了创建动态报表用到的 SSRS 核心特性和功能
Part 3 ,完全介绍了嵌入到 SSRS 中的图表控件
这里,在 Part 4 ,我们把精力放在报表定义语言( RDL )上。 RDL 的定义在 MSDN2 给的很好,所以我在引用一下:
" A report definition contains data retrieval and layout information for a report. Report Definition Language (RDL) is an XML representation of this report definition ."
我们将查看一个典型 RDL 文件的组成部分,讨论下怎样使用 RDL 知识优化和自定义报表。然后我们会了解一下报表设计器工具,这是随着 SSRS 而来的一个全新的即席报表工具。作为一个报表开发者,你可以创建一个终端用户可以使用的你提供的报表定义工具。怎么?有点迷惑?一会儿你就会了解。
为了试验我的例子,你得安装好了 SQL2005 , SSRS , VS2005. 如果对这个有疑问,可以转回 Part 1 去查看。然后请下载相关源代码文件。
现在在 VS2005 新建一个 BI SSRS 项目。选择工程 - 添加已有项,添加上共享数据源( ReportDB.rds )和报表定义文件, FirstReportMan.rdl.
报表定义语言
报表定义语言是一种为了定义报表基于 XML 的架构。而且从 VS2005 报表设计器生成的 SSRS2005 报表本质上就是 XML 。每个报表都有表头,表尾和主题。架构定义了:
l 报表布局 -RDL 文件中的主题部分定义了列在报表中的所有对象,包括字段,图片和表格。
l 各个数据集,数据集对应的数据源一集数据连接信息(当不适用数据源时)。
l 数据集中的字段信息。
l 报表中使用的所有参数。
您可以在这里看到对 RDL 的整体描述:
http://www.microsoft.com/sql/technologies/reporting/rdlspec.mspx
剖析一个典型的 RDL 文件
熟悉 RDL 文件最简单的方法就是深入分析一个典型的 RDL 文件。
让我们看一下下载的项目中的那个 FirstReportMan.rdl 文件,打开 Visual Studio ,打开这个文件。在解决方案资源管理器上右击 FirstReportMan.rdl ,选择查看代码选项,这样就会以 XML 的形式打开这个报表文件。整个 XML 内容在文件之中,但这里我们只看一下主要的部分。
文档元素
我们首先来看一下文档元素:
<?xml version="1.0" encoding="utf-8"?>
<Report xmlns="http://schemas.microsoft.com/sqlserver/reporting/
2005/01/reportdefinition"
xmlns:rd="http://schemas.microsoft.com/SQLServer/
reporting/reportdesigner">
文档元素被称作是报表——这很正常。它引用了两个 XML 命名空间:
- http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition
- http://schemas.microsoft.com/SQLServer/reporting/reportdesigner
数据源
在 RDL 文件中,紧接着命名空间引用的就是数据源。在这个元素中,你可以为你的报表定义单个或多个数据源。
<DataSources>
<DataSource Name="ReportsDB">
<DataSourceReference>ReportsDB</DataSourceReference>
<rd:DataSourceID>b75a1ec2-03ed-4562-921e-28ca4150b215</rd:DataSourceID>
</DataSource>
</DataSources>
可以看出,数据源标记引用了我们的共享数据源 ReportDB 。而且还为数据源提供了一个 GUID 。如果没有使用共享数据源,结果应该是这个样子:
<DataSource Name="ReportingDemo">
<rd:DataSourceID>f34d206b-ca72-4ca6-9d5c-4151cd7eadc3</rd:DataSourceID>
<ConnectionProperties>
<DataProvider>SQL</DataProvider>
<ConnectString>Data Source=SKYNET05"SKYNETSQL2005;Initial z
Catalog=ReportingDemo</ConnectString>
</ConnectionProperties>
</DataSource>
边距
奇怪的是,紧接着数据源定义的是报表边距。不过请记住这是 XML ,所以标记的顺序无关,甚至不同报表拥有着不同的标记顺序。你还可能看到别的标记,比如说 GUID 散落在报表各个角落。
<BottomMargin>1in</BottomMargin>
<RightMargin>1in</RightMargin>
<rd:ReportID>b3751a5a-3ac4-4b97-bdc2-cea456baad26</rd:ReportID>
<LeftMargin>1in</LeftMargin>
<Width>5.625in</Width>
<InteractiveHeight>11in</InteractiveHeight>
<Language>en-US</Language>
<TopMargin>1in</TopMargin>
报表参数
报表参数是下一个重要的部分。每一个报表参数都有名字,数据类型和标签。标签用来作为用户输入的提示。每个参数还有一个 ValidValue 部分。 ValidValue 部分可以作为下拉列表框里的内容。
<ReportParameters>
<ReportParameter Name="ReportTitle">
<DataType>String</DataType>
<AllowBlank>true</AllowBlank>
<Prompt>Report Title</Prompt>
<ValidValues>
<ParameterValues>
<ParameterValue>
<Value>My First Report</Value>
<Label>Title1</Label>
</ParameterValue>
<ParameterValue>
<Value>Customer Report</Value>
<Label>Title2</Label>
</ParameterValue>
</ParameterValues>
</ValidValues>
</ReportParameter>
<ReportParameter Name="ReportingUserID">
<DataType>String</DataType>
<Prompt>ReportingUserID</Prompt>
</ReportParameter>
</ReportParameters>
在这个 RDL 文件里有两个参数, ReportTitle 和 ReportUserID 。 ReportTitle 参数是一个 string 类型的,它有两个有效值, MyFirstReport 和 CustomReport 。对应着两个标签, Title1 和 Title2. 如果用户选择了 Title1 ,那么报表将显示 MyFirstReport. ReportUserID 也是一个 string 类型的参数,只不过没有定义有效值。
主体
接下来是报表的主体部分。主要有两个标记, Height 和 ReportItems 。
<Body>
<ReportItems>
…
</ReportItems>
<Height>0.875in</Height>
</Body>
高度属性定义了报表主体的高度。而这里真正重要的是 ReportItems 元素。 RDL 文件中所有报表对象都在这里。仔细观察就会发现在 ReportItems 元素下面有一个表格定义和两个文本框定义。每个都定义了大小和位置。在表格里有这些定义:
首先看一下表格 :MyFirstTable 。在表格定义的细节部分,我们定义了各个部分,如果有排序或者分组,那么就定义在 <grouping> 和 <sorting> 里面。这里我们只展示一下 FirstName :
<Table Name="MyFirstTable">
<DataSetName>ReportData</DataSetName>
<Top>0.375in</Top>
<ZIndex>2</ZIndex>
<Details>
<TableRows>
<TableRow>
<TableCells>
<TableCell>
<ReportItems>
<Textbox Name="FirstName_1">
<rd:DefaultName>FirstName_1</rd:DefaultName>
<ZIndex>4</ZIndex>
<Style>
<PaddingLeft>2pt</PaddingLeft>
<PaddingBottom>2pt</PaddingBottom>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
</Style>
<CanGrow>true</CanGrow>
<Value>=Fields!FirstName.Value</Value>
</Textbox>
</ReportItems>
</TableCell>
现在来看一下表格的表头部分,我们在这里定一个表头的各个字段,对应于表格各个列:
<TableCell>
<ReportItems>
<Textbox Name="FirstName">
<rd:DefaultName>FirstName</rd:DefaultName>
<ZIndex>9</ZIndex>
<Style>
<PaddingLeft>2pt</PaddingLeft>
<PaddingBottom>2pt</PaddingBottom>
<FontWeight>700</FontWeight>
<BackgroundColor>LightSeaGreen</BackgroundColor>
<Color>WhiteSmoke</Color>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
</Style>
<CanGrow>true</CanGrow>
<Value>First Name</Value>
</Textbox>
</ReportItems>
</TableCell>
最后我们定义了 TableColumn 元素,包含了各个列信息 :
<TableColumn>
<Width>1.25in</Width>
</TableColumn>
PageHeader
看完主题部分之后,我们来到了 PageHeader 部分,就像主题部分一样,这里面也有 ReportItems 元素,同样展示了各个元素。这里也有关于是不是在报表首页和末页显示表头信息的元素。
<PageHeader>
<ReportItems>
<Textbox Name="ReportTitle">
<rd:DefaultName>ReportTitle</rd:DefaultName>
<Width>3.25in</Width>
<Style>
<PaddingLeft>2pt</PaddingLeft>
<PaddingBottom>2pt</PaddingBottom>
<FontWeight>700</FontWeight>
<FontSize>16pt</FontSize>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
</Style>
<CanGrow>true</CanGrow>
<Value>=Parameters!ReportTitle.Value</Value>
</ReportItems>
<Height>0.375in</Height>
<PrintOnLastPage>true</PrintOnLastPage>
<PrintOnFirstPage>true</PrintOnFirstPage>
</PageHeader>
In our page header, we just have a single texbox, called ReportTtitle
数据集
数据集是下一个部分,每个数据集元素对应于报表中的数据集。每一个数据集又一个带有命令类型的查询定义,直接连接到数据源。下面就是字段,每个字段都有字段名称和类型,所以我们的数据集有如下定义:
<DataSet Name="ReportData">
<Query>
<CommandType>StoredProcedure</CommandType>
<CommandText>spr_CustomerSelectAll</CommandText>
<DataSourceName>ReportsDB</DataSourceName>
</Query>
<Fields>
<Field Name="CustomerID">
<rd:TypeName>System.Int32</rd:TypeName>
<DataField>CustomerID</DataField>
</Field>
最后是代码元素。这一部分就是我们嵌入报表的自定义功能的代码。
<Code>Public Function GetColor(ByVal status as String) as String
IF status = "100" Then
Return "White"
End IF
IF status = "101" Then
Return "Yellow"
End IF
IF status = "102" Then
Return "Tomato"
End IF
End Function
</Code>
书写自己的 RDL 文件
现在我们明白了在前段报表设计器发挥作用是后台做了什么事。理解了这些我们就可以在需要的时候写自己的 RDL 报表了。我发现在 2005 中写的代码要比 2000 少多了。然而,懂得 RDL 能在别的方面发挥大的作用。你可以不非得用 Visual Studio 来进行设计,你可以用自己的报表设计工具了。
使用 Report Builder
Report Builder 是 SSRS 的一个轻量级的补充,开发人员可以利用这个开发一个基于 web 的一键式部署工具。这个工具允许用户通过事先定义好的字段和功能函数来定义自己的报表。用户可以使用拖拽的方法创建自定义报表。在不用给予用户太多数据库操作的权限的情况下,这是个不错的选择。
定义报表
在这个练习中我们将建造一个报表定义。首先创建一个报表模型项目。然后可以看到其中有三个文件夹:
1. 数据源
2. 数据源视图
3. 报表模型
添加数据源
跟 RS 中其他地方一样,可以通过数据源向导构建。
添加数据源视图
数据源视图允许开发人员在构建报表的时候使用哪些数据表。也可以进行关联设置,这样报表就会知道该怎么进行连接操作。表格关联可以使用外键或者名称匹配架构。如果使用名称匹配架构,表格连接操作就会使用相同名称的字段或者主键。
添加报表模型
报表模型使用了数据源视图以及其包含的部分,所以用户可以利用这些元素来创建报表。报表模型也可以选择单个的字段信息。
使用 Report Builder 创建报表
我们可以在 windows 应用上打开 ReportBuilder ,然后通过拖拽操作就可以创建报表。用户可以决定要显示的字段信息和报表格式。
在建立报表之前得先安装好。 Netframework2.0.
导航到 http://localhost/Reports/ .
可以看到有个按钮式 ReportBuilder ,单击,第一次加载可能比较慢,然后选择模型,就可以进行报表构建工作了。
结论
希望这一系列会对 SSRS 方面有所帮助。