本文包含了Microsoft® SQL Server™报表服务报表设计的技巧和最佳实践。本文提供一些基本的设计问题和一些报表服务的功能。
关于这篇文档
从使用数据控件,到使用什么格式,到如何分发报表,报表制作者面对着很多种选择。Microsoft® SQL Server™ 报表服务提供了丰富的报表设计和格式的支持,从基于纸介质表格报表到带有图片和钻取功能的交互式报表
这篇文档包括了报表制作和设计中的指导、建议和技巧。本文档的目的在于解释一般性的问题并对初学者提供指导建议。报表服务联机丛书提供了报表的制作和设计的丰富资源,并且详细的描述了报表的设置和可用功能及参数。
本文适用于初学者和有一些经验的报表制作者。报表制作的初学者也可以从报表设计章节中得到帮助。
其他信息来源
本文不包含全部的报表服务的信息。如果希望获取详细的产品信息,请查看产品文档和在http://www.microsoft.com/sql/reporting/ 中可用的在线资源。
产品版本
虽然本文基于Microsoft t® SQL Server™ 2005报表服务,报表设计的相关信息也适用于早期版本的报表服务。
简介
Microsoft® SQL Server™ 报表服务是一种完整的报表工具。在使用报表服务中,你可以设计和发布多种样式的报表,从简单表格到带有图形和交互式连接的在线自由表单。报表服务可以将报表渲染成用户指定的多种格式,包括HTML、PDF、Excel和图像格式。
对于各种设置和选择对于报表制作者在选择报表布局是需要解决的问题。这篇文章提供了一些指导方针是用户在做选择是更加容易并解答了一些常见的问题。
制作工具和RDL
报表服务提供了多种制作报表的方法。SQL Server 和Microsoft® Visual Studio® 2005 都包括了图形化的报表设计工具。SQL Server 2005报表服务提供了Report Builder工具帮助业务人员设计报表。也有其他的开发工具可以创建报表服务的报表格式。
无论我们使用哪一种制作环境,所有的报表定义都是用报表定义语言(RDL)格式存储,RDL是一种公开的XML定义报表的格式。这样可以直接编写RDL或者创建自定义工具生成相应格式。报表制作者可以使用图形化的制作工具编辑已存在的RDL文件。
在样例中展示特殊的技术时,文章提取了实现该功能的部分RDL。
在报表服务的网站上http://www.microsoft.com/sql/reporting/可以获取完整的RDL规范。
报表设计概念
本节描述了影响报表设计和布局的关键因素。如果你是刚刚接触报表服务,这里的内容会对你有帮助。所有的这些话题在SQL Server 联机丛书中都有详尽的描述。
在设计报表服务中的报表时,你定义了数据并制定在页面上的排列。尽管这个过程听起来很基础,报表服务还是提供了下列特性:
◆支持4种不同的数据区域:列表,表格,矩阵和图表。
◆提供了例如文本框,图片,连接,矩形和子报表等一些列控件。
◆用户可以通过参数,条件过滤,用户端排序,钻取和文档结构图来实现交互功能。
◆报表可以被渲染成各种格式,包括HTML,Excel,PDF,图像,XML和逗号分隔符 (CSV) 。
你做的关于每一个关键区域的决策都会影响最重的显示效果和报表功能。接下来的章节将提供影响设计和布局效果的因素。
数据区域
在我们的报表中我们第一个选择就是选择数据区域类型。报表服务提供了下列数据区域类型:
◆表格
表格通过一行接一行的方式表现数据。列是固定的你无法扩展,但是行可以向下展开。因此,当表格增长时,它将数据向下展开。你也可以在表格内将数据分组。
◆矩阵
A矩阵或者叫交叉表类似于表格,但是行和列都是可以扩展并填充数据的。矩阵可以向外和向下增加其他报表对象。你可以在矩阵中在行和列中嵌套分组。
◆列表
列表适用于创建表单的自由表单数据区域。你可以通过嵌套列表来分组数据。
◆图表
图表是数据的图形表达方式。报表服务提供了多种图表的格式。
你选择的数据区域可能依赖于你使用的数据类型、你希望报表的外观和如何展现报表。例如,要以Microsoft® Excel®形式呈递的报表使用表格比使用列表更适合。
报表项的位置和尺寸
报表有3个主要的区域组成:页眉,页脚和正文。报表服务支持将报表中任意放置报表项。数据区域可以和其它区域并行或通过分组来嵌套。
当设计报表时,理解当报表项增长时如何处理是非常重要的。报表项可以水平或垂直的增长,依赖于重复的片断,内容的尺寸和诸如字体等报表渲染的因素。
当报表项增长时,例如一个表格,它会生成很多相关的报表项。这些报表项会在同一个父容器中。有如下2种方法来控制报表项的移动:
◆每个报表项为了维护与上边报表项间的最小距离会向下移动。
◆每个报表项为了维护与左侧报表项间的最小距离会向右移动。
如果一个报表项增长,它会扩展包含它的容器的边界,容器会适应所包容的报表项变化尺寸。
如果报表项和其他的报表项重叠,报表定义中的ZIndex元素决定哪个元素在顶层。ZIndex值高的报表项会置于上层。
这些是一些你可以用来控制报表项的增长和移动方法的技术。如果需要使用矩形和报表项的分组的信息,请参考本文后面“实用的报表设计技巧”部分。
分页
对于场报表来说关键问题在于如何控制页面的分割。页面通过2个因素控制分割:
◆页面尺寸
◆用户指定对象前后页面分割
页面尺寸
为了控制页面的尺寸,可以通过下列指导设置页面的高度和宽度属性:
◆可以通过报表的PageHeight和PageWidth属性设置渲染后的物理页面格式。
◆例如HTML这样的交互式渲染格式不能渲染物理页面分割。而使用 InteractiveHeight 和 InteractiveWidth 属性创建逻辑的页面分割。
◆有一些渲染格式,例如Excel,不支持页面尺寸。对于这些报表,你将不得不使用页面分割符将报表分割成多个页面。
注意,如果报表的自身宽度比页面宽度大,报表将在水平方向上交叉于多个页面。
页面分割
你可以在矩形,表格,矩阵,列表,图表和分组中的开始或结尾处添加分页符。报表服务会尝试将所有报表项和数据分组保持在同一个页面上。
可以使用报表项中的PageBreakAtEnd和PageBreakAtStart属性指定在报表项之前或之后插入分页符。
子报表
子报表是在报表项中指向另外一个报表。任何报表可以被用于一个子报表,并且你可以设置父报表将要传递到子报表的参数。
但是用子报表时你要注意下列前提:
◆子报表无法和父报表共享数据。报表服务器为分割的报表处理每一个子报表实例,但是这会影响性能。
◆子报表的页眉和页脚会被忽略。
子报表在下列环境中十分有用:
◆当你需要在一个数据区域中从不同数据源嵌套分组。
◆当报表有多个一对多关系的部分。
◆当你需要在多个父报表中重用子报表。
◆当你需要在其他报表内部嵌入一个标准的,独立的报表。
如果报表共享数据,类似表格,矩阵,列表和图表这样的数据区域提供了与子报表同样的功能。然而,它们提供更好的性能。数据区域在并行的布局中提供了比子报表更好的工作方式。
表达式和函数
报表制作者可以在报表中使用表达式数据的外观,更改报表项的属性或控制数据的获取。本文的技巧章节提供了一些使用表达式的设计样例。
你可以在表达式中使用Microsoft® Visual Basic®函数。在表1中显示了一些常用的函数。
表1
Visual Basic 函数 | 结果 |
Today() | 返回当前日期。 |
DateAdd() | 基于单一参数提供一段日期。 |
Year() | 显示指定日期中的年份。使用它分组日期或做为一系列日期的标签。 |
Month() | 显示日期中的月份 |
Format() | 格式化字符串。可以用于格式化日起和数字。 |
Right(), Left(), and InStr() | 返回截取后字符串中的一部分。 |
Iif | 依照评估的表达式,返回2个值中的1个。为了返回3个值中的1个,你可以嵌套Iif函数。 |
你可以通过引用适当的装配件在表达式中使用.NET函数。你也可以使用自定义的装配件。如果需要此方面更详细的信息,请查看报表服务联机丛书中”Using Customer Assemblies with Reports”部分。
聚合函数和范围
报表服务提供了许多聚合函数可以在报表中创建总和或其他聚合。
每个汇总函数支持一个定义汇总范围的范围参数。范围可以通过分组名称,数据集或数据区域来指定。数据区域或分组必须直接或间接包含聚合函数指定的报表项。
如果你忽略了范围,聚合范围是报表项所在的分组或数据区域中最里面的分组。
表2中显示了报表服务支持的聚合函数:
表2
函数 | 描述 |
Avg | 从指定表达式中返回所有非空值的平均值。 |
Count | 返回指定表达式中值的数量。 |
CountDistinct | 返回指定表达式中所有不同值的数量。 |
CountRows | 返回指定范围中行的数量。 |
First | 从指定表达式中返回第一个值。 |
Last | 从指定表达式中返回最后一个值。 |
Max | 从指定表达式中返回所有非空值中的最大值。 |
Min | 从指定表达式中返回所有非空值中的最小值。 |
StDev | 从指定表达式中返回所有非空值中的标准差。 |
StDevP | 从指定表达式中返回所有非空值中的总体标准差。 |
Sum | 从指定表达式中返回所值的总和。 |
Var | 从指定表达式中返回所有非空值中的方差。 |
VarP | 从指定表达式中返回所有非空值中的总体方差。 |
报表服务提供函数来支持运行时的汇总。图3中显示了相关的函数。
表 3
函数 | 功能 |
RowNumber | 在指定范围内返回运行时产生所有行的数量。当于数据区域中使用文本框时,显示在表达式显示部分每个文本框实例的行数。用于指定表格行数或提供分页符。在RowNumber(Nothing)中,关键字Nothing指定了在最外侧数据区域中从第一行开始计数。 |
RunningValue | 使用指定函数从指定表达式中返回运行时的聚合。 |
报表服务提供了下列导航范围函数。表4中显示了这些函数。
表4
函数 | 描述 |
InScope | 判断当前报表项实例是否在指定的范围中。它使用数据集,分组或数据区域的名称做为参数并返回布尔值。 |
Level | 在递归层次中返回当前级别的深度。 |
Previous | 返回之前的行。 |
报表渲染时的考虑
报表服务器提供了一套磨人的渲染扩展。你可以从报表服务中删除扩展或添加自定义扩展支持新的渲染格式。
默认的渲染扩展包括了HTML,Excel,逗号分隔符(CSV),XML,图像和PDF。
注意: 默认渲染扩展在报表服务中可以用于渲染报表。使用SQL Server 2005报表查看器控件在本地生成的报表可以支持HTML报表渲染,但是不需要访问其他的扩展。
你选择的渲染扩展会影响报表的布局。例如,不是所有的渲染扩展支持强制的页面分隔符或者页面分隔符应用于页面尺寸设置。表5中汇总一些差异。
表5
渲染扩展 | 基于报表项或分组分页 | 页面尺寸 |
HTML | 可以 | 使用InteractiveHeight属性 |
Excel | 可以 | 不可以 |
CSV | 不可以 | 不可以 |
XML | 不可以 | 不可以 |
Image | 可以 | 可以 |
可以 | 可以 | |
GDI (Window 表单) | 可以 | 使用InteractiveHeight属性 |
如果你在设计报表之前你知道报表会被如何渲染,你可以针对目标格式优化报表布局。否则,以应该对各种可能的渲染扩展测试你的报表并找到和解决各式上的问题或异常。
接下来的部分包含了使用Excel,图像,PDF和HTML渲染扩展的一些建议。
Excel
报表服务支持将报表渲染为Microsoft® Excel® 1997及以后版本。如果你计划将报表渲染为Excel,你应该知道一些Excel渲染扩展的特殊属性。例如:
◆在报表中每一个报表页面将变为一个Excel的工作表。Excel不支持页高和页宽的概念,所以只有显式定义的分页符才能将页面分割。
◆报表服务不支持指定工作表名称。
◆渲染扩展构建报表外的表格结构。
◆不支持个别单元中的背景图片。
◆Excel除列表外的嵌套容器。
◆图表被渲染成图片,而不是Excel中的图表。
◆矩形被渲染成单元格组。如果举行包含其他报表项,矩形将变为单元格区域,矩形的边框和背景色将应用于表格区域。
◆子报表将被作为矩形在同父报表中的工作表中渲染。
在指定Excel报表中使用表格代替列表
表格使用固定的列宽。这很好的满足Excel报表中的表格格式。当渲染为Excel时,报表中的报表项会像我们期望一样排列。
与表格相比,列表是一种自由表单的风格。列表中的报表项将被放置在工作表中像对于在报表中的位置。这样会导致意想不到的结果。如果你的报表中使用了列表,要确认渲染成Excel的结果是可以接受的。
即使使用表格,如果在你的报表中页眉跨越多个列,Excel渲染扩展可能合并单元格或引入新的列。这样会在Excel电子表格中影响数据的排序和操作。如果你计划将报表渲染为Excel,请设法确认报表项排列能将单元格合并减到最小。
长报表的最大页数
为了预防生成Excel产生错误,你应该注意冗长报表的页数。报表中的每页都会变成Excel中的一个工作表。然而,每一个工作簿中为了限制对内存的使用,会有一个最大的工作表数量。如果报表页面超过了这个限制,Excel会生成一个错误。
渲染为Excel时的颜色差异
支持一套预定义的颜色。当你渲染报表时,Excel渲染扩展将报表中的颜色应设成Excel支持颜色中最接近的颜色。
图像
图像渲染扩展可以将报表渲染成位图或图元文件。默认情况下,它将数据渲染成TIFF格式。然而他也可以生成被GDI+支持的任何格式,包括BMP,EMF,GIF,JPEG和PNG。
在报表服务器中图像渲染处理在一个虚拟的页面中进行,并在这个页面创建图像。结果,在任何客户端上,基于图像的报表在字体和布局上看起来都是一样的。
当你使用TIFF文件时,你可以查看多页面报表。然而,其他的图像格式为将为每一个报表页面生成一个图像文件。
图像渲染也支持页面高度,页面宽度和页边距。任何报表中包含的页眉和页脚都会在报表边界内被渲染。
使用图像渲染为所有的客户端创建同样的报表
如果你希望在所有客户端看到同样的报表,你应该使用图像渲染。特别是当报表渲染时,HTML报表使用客户端子体和浏览器设置。这意味着当客户端使用不同的浏览器时报表的布局会有所不同。因为图像文件在报表服务器上格式化,它们渲染成的图片在任何客户端上的显示都是一样的。
在报表服务器上安装适当的字体
你应该确认在报表服务器上安装的正确的字体。这是因为报表实际上是在报表服务器上渲染,它使用了在报表服务器上所安装的字体。
便携文档格式
便携文档格式(PDF)渲染扩展创建的报表可以使用Adobe Acrobat readers打开查看。在很多方面上,PDF扩展类似于图片扩展,除了下列重要的差异:
◆在PDF报表中字体没有被嵌入到报表中。
◆文档结构图被渲染成PDF书签。
◆你可以在设备选项中指定页面的宽度高度、边距和PDF的分辨率。
◆渲染扩展创建的PDF1.3版本的文件和Adobe Acrobat 4.0机器以后版本兼容。
◆PDF渲染扩展不支持 RepeatWith属性。
在客户机中安装适当的字体
PDF扩展无法在报表中嵌入字体。为了正确的查看报表的字体,你不仅需要在报表服务器上确认安装该字体,也要确认该字体在查看报表的客户端中正确安装了。另外字体替代现象很有可能发生。
HTML
HTML扩展可以生成与Microsoft® Internet Explorer,Mozilla Firefox及Apple Safari兼容的HTML 4.0页面。
HTML渲染和其他的渲染有以下的不同:
◆HTML渲染扩展在HTML中生成了一个包含所有报表控件项的表格。控件项将保持在报表布局时的位置。
◆位置和大小使用毫米(mm)为单位表示。渲染的最小单位是0.2毫米。
◆HTML不支持对象的重叠。这样导致当报表显示时布局被改变了。
◆在HTML报表中,子报表被渲染在DIV标签中。
客户端变化
当在客户端显示时,HTML报表使用浏览器的特性来设置。另外字体的变化,其他的浏览器设置可以做相应的处理改变。如果你想恰到好处的控制在所有客户端上的布局,考虑使用图像渲染扩展。
不同浏览器的差异
SQL Server 2005报表服务包括了对于不同浏览器的支持例如Microsoft Internet Explorer, Mozilla Firefox 和Apple Safari。尽管大多数的报表的特性在这些浏览器上都是被支持的,你也应该在相应浏览器上测试确认其满足你的需求。
实用的报表设计技巧
本节提供了使用表达式来巧妙处理报表格式和布局的技巧和技术。
使用矩形保持对象的紧凑
在报表服务中矩形可以被用于图形元素或者对象的容器。做为对象容器,它可以是在一个页面上的对象保持适当的距离并控制对象项目移动式的位置。
为了保持多个对象在同一个页面中,可以将对象放在一个矩形内。你通过设置矩形的PageBreakAtStart或PageBreakAtEnd属性在矩形的前后添加分页符。
使用矩形控制报表项的增加位置移动
在同一个矩形中的控件相互间是同等的并且当控件增长或移动时通过统一的规则在页面中排布。例如:
◆报表项通过通过各自的矩形来推动和置换。
◆报表项不能和矩形外报表项推动或置换,因为他们不在一个级别上。
◆如果需要,矩形可以增长来适应所包含的控件。
当处理会扩展的对象时,你可以利用这个逻辑的功能。例如:
◆如果你为你的报表扩展预留出一些空白的空间,可以将表格和相应的空白空间放止于同一个矩形。当表格增长,它会被置于预留好的空白空间中。
◆如果你防止矩阵扩展出页面的右侧边缘,可以将矩阵和一些空白放入同一个矩形中。
避免空白页
有时当你将报表输出到例如PDF或打印机这样的物理页面是,你可能会看到有空白页面。通常,当报表正文超过纸面尺寸是会发生这种情况。
为了确认所有的内容适合于单一的纸张,正文加上页边的空白应该小于预定义好的纸面宽度。文本框和其他的报表项可以导致正文宽度超过纸面宽度,即使当超出部分的内容不可见。另外,报表项水平的增长(矩阵数据区域和图片自动设置为Autosize或Fit)可以导致正文宽度的增长。
使用分页提高大报表的性能
如果不去为一个返回大量数据的报表设置页面大小或分页符,一些报表格式将会尝试将报表渲染成单页。
例如,Excel没有默认的固定页面宽度。所以,如果你有一个很大的报表,Excel将尝试将其渲染成一个工作表。通常,使用分页符可提高用户访问报表时的性能,因为当渲染报表剩余部分时,用户可以查看报表的第一页。
使用筛选器代替查询参数
报表服务有几种方法动态的过滤报表内容:
◆当返回丛数据源获取数据时使用查询参数过滤数据。
◆应用于数据集或报表区域的报表筛选器,限制在报表中显示的数据。
使用筛选器获取所有的数据,但是只有和用户相关的数据被显示。这也许比在数据源中过滤数据的效率要低。然而,这样可以使我们只获取一次数据并将数据存储在快照中来服务于不同的用户请求。换句话说,当我们使用查询参数,每一个新的参数查询你都要访问数据源。筛选器可以使我们执行快照并获取所有参数的结果。
在表格中添加轮换条
也许你需要创建带有隔行渐变形式的表格或矩阵的报表。 这种栏从视觉上可以更好地在一个页面上跟踪不同的行。
为了更好的模拟用在生成大量报表的高速数据打印机中的老式绿条纸 你可以轮换条设置为绿色。
为了完成这个效果,可以使用Iif函数基于行数的奇偶性有条件指派背景色。例如:
=iif(RowNumber(Nothing) Mod 2,"PaleGreen","White")
在RDL文件中的描述应该类似于如下代码:
<TableCell>
<ReportItems>
<Textbox Name="SalesOrderID">
<Style>
<PaddingLeft>2pt</PaddingLeft>
<Format>d</Format>
<BackgroundColor>=iif(RowNumber(Nothing) Mod 2,"#c0ffc0","White")
</BackgroundColor>
<TextAlign>Right</TextAlign>
<PaddingBottom>2pt</PaddingBottom>
<PaddingTop>2pt</PaddingTop>
<PaddingRight>2pt</PaddingRight>
</Style>
<ZIndex>4</ZIndex>
<rd:DefaultName>SalesOrderID</rd:DefaultName>
<CanGrow>true</CanGrow>
<Value>=Fields!SalesOrderID.Value</Value>
</Textbox>
</ReportItems>
</TableCell>
在一个报表中的表格中在指定行后添加分页符
你可以使用Ceiling 函数在表格中将行分组,并在每个分组后插入分页符。
Ceiling函数返回不小于输入参数的最小值。例如,每隔30行添加一个分页符,你应该使用下列表达式分组:
=Ceiling(RowNumber(Nothing)/30)
在RDL中描述分组应该类似于下列描述:
<TableGroups>
<TableGroup>
<Grouping Name="PageGroup">
<GroupExpressions>
<GroupExpression>=Ceiling(RowNumber(Nothing)/30)</GroupExpression>
</GroupExpressions>
<PageBreakAtEnd>true</PageBreakAtEnd>
</Grouping>
</TableGroup>
</TableGroups>
在页眉和页脚中添加全局变量值
在表6中显示了Globals对象的成员,这些可以在报表的表达式中使用。
表6
名称 | 类型 | 描述 |
PageNumber | Integer | 当前页数。仅在报表的页眉和页脚中使用。 |
TotalPages | Integer | 报表的总页数。仅在报表的页眉和页脚中使用。 |
ExecutionTime | DateTime | 报表开始执行得日期和时间。 |
ReportFolder | String | 包含报表的文件夹的路径,例如salesreportsudgeting 或c:salesudget |
ReportName | String | 报表的名称,例如 currentbudget. |
你可以在报表的页眉或页脚中使用表达式显示报表名称和执行时间。时间通过.NET提供的短日期格式。例如:
=Globals.ReportName & ", dated " & Format(Globals.ExecutionTime, "d")
同样也可以利用文本框将报表的当前页数和总页数显示在页眉:
=Globals.PageNumber & " of " & Globals.TotalPages
在页眉中显示报表项
在长报表中你可能会希望在页眉中添加报表正文中的文字。例如,一个姓名地址录在页眉重要显示当页中出现的第一个和最后一个名字。
为了实现这个功能,你可以在页眉上添加一个文本框,并使用First函数。为了在页面上显示第一次出现的LastName值,表达式应该类似于如下所示:
=First (ReportItems!LastName.Value)
同样的,使用表达式函数Last 可以提供在页面上显示LastName 文本框的最后一个值 。例如
=Last (ReportItems!LastName.Value)
创建带有条件格式的钻取连接
报表服务可以通过拥护和报表的交互在报表中隐藏或显示报表项。
你可以使用这种功能在报表中创建钻取连接。例如,通过点击某个区域,用户可以从汇总视图中钻取数据的详细信息。
接下来,为包含该分组的文本框创建触发开关项。然后当用户点击该文本框,隐含的数据变成可见的或数据不显示。
结论
Microsoft SQL Server 2005 报表服务提供了多种报表设计的选择。本文提供了一些常规的指导方针和报表设计技巧,但是只涉及了部分该产品的功能。为了获取更多的设计信息和产品功能,请参考SQL Server 2005 联机丛书。