摘 要 以制上证指数行情表为实例,讲解VC++.NET显示报表、打印报表、打印预览及页面设置的基本编程方法及实现过程。
关键词 VC++.NET;图形编程;报表编程;报表分页;打印;打印预览;页面设置
报表编程与图形编程在方法上完全相同,都使用GDI+。相对上一讲,本讲侧重于讲解输出显示文本的格式化,以及报表(图形)打印、打印预览和页面设置。
本讲仍然采用前两讲的应用程序实例,通过绘制股价表讲解VC++.NET报表编程的基本方法及实现过程。
一、报表
报表是数据的一种格式化表示,由文本、图形按需要排列组成。在Windows下编程,文本也被看作图形。与图形编程一样,报表编程也使用GDI+。相对于图形编程,报表编程
侧重对文本格式化。
⒈ 什么是报表
在工作或生活中,报表随处可见,人人都很熟悉。
报表离不开数据。作为报表设计人员,看待报表的视角常常是数据库。从数据库的角度看,报表是数据的格式化表示,是数据基本的输出形式。报表与标签不同,标签在一个页面上只输出一条记录的数据,其典型例子是名片;而报表则在一个页面上按同一格式排列多条记录的数据。
一个报表,从纵向分布看,可以包含若干部分,标准术语叫报表节。报表节是报表开发人员在报表设计实践中对报表结构的高度概括。
报表节通常包括:报表页眉、页眉、细节、报表页脚和页脚等,如图1所示。

图1 报表的页面布局
报表节及其输出显示结果如表1所示。
表1 报表节及其输出显示结果
报表节 |
输出显示结果 |
报表页眉 |
在“报表页眉”中的内容只在报表开头输出显示一次。 |
页眉 |
在“页眉”中的内容输出显示在每个新页的开始位置。 |
细节 |
在“细节”中的内容随每条新记录输出显示。 |
报表页脚 |
在“报表页脚”中的内容只在报表的结束位置输出显示一次。 |
页脚 |
在“页脚”中的内容输出显示在每页的底部。 |
表1是对报表组成的一般概括和总结。对于一个特定的报表,并不一定包含全部的报表节。
⒉ 报告设计
绘制报表,目前已有一些现成的报表工具软件可供选用,例如Crystal Reports。
使用报表工具,可以使设计报表格式变得非常简单,还可以省去对控制打印机的编程工作。但是也有许多不利之处:
(1)由于工具是面向一般报表的,因此工具本身庞大,占用系统资源较多,运行效率自然较低。
(2)使用工具设计报表虽然简单,但是熟悉工具并不容易,需要花费较多的时间。这也是报表工具不能普及的主要原因。
(3)使用工具成本较高。购买一个报表工具软件,少则数万元,多则数十万元。
自己动手编制报表,不仅可以避开上述不利之处,用非常小的成本随心所欲地编制自己所需要的、高效运行的报表,而且还可以从较低层了解报表的编程方法,这对于丰富编程经验、同时更深入地理解报表工具软件,无疑是一个很好的途径。
⒊制作方法
在上一讲已经介绍过,Windows是图形操作系统。在Windows中,所有内容都被图形化了。在Windows下编程,文本也被看作图形。因此,在VC++ .NET中,制表与绘图在设计方法上完全相同,也采用GDI+。
当然,相对于绘图,制表也有其特殊性。报表是数据的格式化表示,在报表页面中,既有数据字符的格式化排列,也有各种图形对报表的修饰。同时,如果数据是字符,在页面中还可能被折断成多行显示。
在报表编程中,最常见的图形是直线、矩形,使用最多的方法是Graphics 对象的DrawLine(绘线条)、DrawRectangle(绘空心矩形)和FillRectangle(绘实心矩形)方法。而绘制文本,则使用Graphics 对象的DrawString方法。这些方法,在第二讲中已有介绍。但是,对于DrawString方法,在报表编程中还要深入应用,这里再作进一步讲解。
DrawString方法提供了一组重载,共有6种,如表2所示。
表2 DrawString方法重载列表
名称 |
说明 |
Graphics.DrawString (String, Font, Brush, PointF) |
在指定位置并且用指定的 Brush 和 Font 对象绘制指定的文本字符串。 |
Graphics.DrawString (String, Font, Brush, RectangleF) |
在指定矩形并且用指定的 Brush 和 Font 对象绘制指定的文本字符串。
由 .NET Compact Framework 支持。 |
Graphics.DrawString (String, Font, Brush, PointF, StringFormat) |
使用指定 StringFormat 的格式化属性,用指定的 Brush 和 Font 对象在指定的位置绘制指定的文本字符串。 |
Graphics.DrawString (String, Font, Brush, RectangleF, StringFormat)
|
使用指定 StringFormat 的格式化属性,用指定的 Brush 和 Font 对象在指定的矩形绘制指定的文本字符串。
由 .NET Compact Framework 支持。 |
Graphics.DrawString (String, Font, Brush, Single, Single) |
在指定位置并且用指定的 Brush 和 Font 对象绘制指定的文本字符串。
由 .NET Compact Framework 支持。 |
Graphics.DrawString (String, Font, Brush, Single, Single, StringFormat) |
使用指定 StringFormat 的格式化属性,用指定的 Brush 和 Font 对象在指定的位置绘制指定的文本字符串。
由 .NET Compact Framework 支持。 |
编程经验告诉我们,报表编程中最繁琐的工作是设计报表格式。下面来分析一下在设计报表格式时将会面对的主要问题。
(1)文本的输出位置和范围
在报表页面中排列任何文本,都需要确定文本的输出位置。
此外,当记录中的某一个字段可能字符数较多,在报表页面显示时不仅需要确定文本的输出位置,还要限制文本的布局范围。
解决这两个问题,可以使用表2中带有RectangleF参数的DrawString方法的重载。
RectangleF结构表示一个矩形的位置和大小。有两种重载,如表3所示。
表3 RectangleF结构重载列表
名称 |
说明 |
RectangleF (PointF, SizeF) |
用指定的位置和大小初始化 RectangleF 类的新实例。 |
RectangleF (Single, Single, Single, Single) |
用指定的位置和大小初始化 RectangleF 类的新实例。
由 .NET Compact Framework 支持。 |
(2)格式化文本
在报表页面中显示文本时,常常需要对文本进行格式化,例如行距、对齐方式和文字方向。
可以使用表2中带有StringFormat参数的DrawString方法的重载格式化文本。
StringFormat 类指定所绘制文本的格式化属性。它的构造函数有4种重载,在绘制报表时,常使用带有StringFormatFlags 参数的StringFormat重载。
StringFormatFlags是一个枚举,其成员对制表特别有用。StringFormatFlags枚举的所有成员如表4所示。
表4 StringFormatFlags枚举成员列表
成员名称 |
说明 |
DirectionRightToLeft |
按从右向左的顺序显示文本。 |
DirectionVertical |
文本垂直对齐。 |
DisplayFormatControl |
控制字符(如从左到右标记)随具有代表性的标志符号一起显示在输出中。 |
FitBlackBox |
允许部分字符延伸该字符串的布局矩形。默认情况下,将重新定位字符以避免任何延伸。 |
LineLimit |
在格式化的矩形中只布置整行。默认情况下,这种布置要继续到文本的结尾为止,或者到由于剪辑而不再有可见的行为止,看哪一种情况先发生。注意,此默认设置允许不是行高整数倍的格式化矩形将最后一行部分地遮住。若要确保看到的都是整行,请指定此值,并仔细地提供格式化矩形,使其高度至少为一个行高。 |
MeasureTrailingSpaces |
包括每一行结尾处的尾随空格。在默认情况下,MeasureString 方法返回的边框都将排除每一行结尾处的空格。设置此标记以便在测定时将空格包括进去。 |
NoClip |
允许显示标志符号的伸出部分和延伸到边框外的未换行文本。在默认情况下,延伸到边框外侧的所有文本和标志符号部分都被剪裁。 |
NoFontFallback |
对于请求的字体中不支持的字符,禁用回退到可选字体。缺失的任何字符都用缺失标志符号的字体显示,通常是一个空的方块。 |
NoWrap |
在矩形内设置格式时,禁用文本换行功能。当传递的是点而不是矩形时,或者指定的矩形行长为零时,已隐含此标记。 |
(3)测量格式化字符串的宽和高
在设计报表时,常常需要预先知道所绘制的格式化字符串的宽和高。例如,在报表页面中,由于记录的某个字段字符数较多且不固定,在报表细节中要使上下记录的各列宽度一致,往往将字段限制在一个布局矩形中折断成多行显示输出。但是,由于字段字符数不固定,行数也不固定,其显示输出的字符串的高也不固定。为了确定下一记录在输出显示时的纵坐标,必须测量当前记录在报表细节中占用的最大高度。
可以使用Graphics类的MeasureString 方法来解决这个问题。MeasureString 方法返回 SizeF 结构,其Height属性表示所汇字符串的高,Width属性表示所汇字符串的宽。
MeasureString 方法有多种重载,使用其中带有SizeF、StringFormat参数的重载,即可获取限制在布局矩形中显示输出的文本的实际高度:
Graphics.MeasureString (String, Font, SizeF, StringFormat)
|