基于自定义模板的通用报表设计
作者:金百东
来源:《计算机时代》2009年第10期
摘要:提出了一种实现通用报表的新思想:将Excel文件转化生成自定义模板文件,模板文件包括报表的静态及动态两部分内容,静态部分主要封装了表格结构信息,动态部分主要封装了SQL语句以及与静态部分相关联信息,模板文件可以存入服务器数据库中;客户端通过通用打印组件完成报表的输出。
关键词:通用报表;自定义模板;Excel文件;通用打印组件
引言
目前,通用报表组件有两种常用开发方法:①利用第三方组件技术。
第三方组件如水晶报表或国内的CELL系统软件等,这些系统均包含可视化的报表生成器,可以用它们方便地生成报表模板文件,打印输出则由系统提供的标准打印组件通过解释模板文件来完成。
这种方法的优点是:编程量很少,一般来说只需要知道如何调用标准打印组件接口和这些接口所需要的参数就可以了。
但是如果计算机配置较低的话,打印响应速度稍慢。
另外报表系统软件价格较高。
②完全重新开发,开发内容包括报表生成器及报表打印组件等。
这种方法的优点是系统响应速度快,容易扩充。
但是功能很难超越水晶报表等成熟软件,而且开发费时费力。
本文提出的实现通用报表的方法巧妙地继承了上述两种方法的优点,又弥补了它们的不足。
所用开发平台是Visual C++6.0,数据库是sQL Server 2000。
1实现通用报表需解决的问题
通用报表开发的基本思路几乎都是一致的:即采用模板技术,先生成空模板文件,再用程序把数据填充到模板上。
模板文件主要包含以下两部分内容:
静态部分对大多数企事业单位的报表来说,每种业务对应的报表形式是固定的,如行数、列数、文字说明部分、边框特征等,这些都属于静态框架描述部分。
应用程序通过这些描述可以画出表格的结构。
动态部分描述如何把数据库相应内容或其它数据动态地填充到空表格上。
相比较而言,构造报表中的表格以及文字说明是比较烦琐的。
对表格边框来说,有的是粗线,有的是细线,有的有边框,有的无边框或部分有边框,有的是合并单元格;对文字说明来说,字体名称、大小、对齐方式等等也是有多种变化的。
动态填充部分的描述相对容易一些,一般来说只要把单元格位置与相应的SQL语句关联起来就可以了。
2通用报表设计思想
通用报表程序一般包括两部分:报表生成器程序、打印组件程序。
报表生成器完成报表模板的静态及动态设计,生成模板文件;打印组件程序负责解析该模板,完成打印输出。
本文所述通用报表设计的关键步骤如下:①充分利用Office软件中Excel强大的报表功能,首先在Excel中绘制出表格形状,即静态框架部分的内容;再通过加批注方式加入动态填充部分的内容,之后保存此Excel模板文件。
②用程序通过一定的方式解析此Excel模板文件,转换成自定义格式的新的模板文件。
③把获得的自定义格式模板文件数据以二进制方式导入数据库中。
也就是说,数据库中有一个报表描述表,仅含两个字段,第一个是报表名称,作为关键字;第二个字段是对应的模板数据。
④客户端应用程序通过报表名称,调用打印组件程序,获取服务器端对应的报表描述表中的自定义模板数据,通过解析该数据,完成报表的输出。
该方法的优点在于:一是充分利用了Excel制表功能,省去了静态框架部分的设计;二是自定义模板的文件格式是自定义的,因此可以在程序中灵活控制。
3通用报表关键技术实现方法
3.1静态部分的实现
3.1.1实现原理
实现静态部分的关键在于如何抽象表格的问题。
笔者把表格抽象成单元格,屏蔽了表头、表体、表尾的差异,把它们均当做一个个的单元格来处理。
这种处理方式与Excel系统软件的处理相似,因此可以借助Excel文件生成自定义格式的静态框架描述部分的内容。
绘制一个表格,前提条件是要获得表1中各变量的数值。
根据表中1、2两项,可以知道表格的具体大小及每个单元格的具体位置。
每个单元格边框、字体、对齐方式、范围等属性是由表中3、4两项决定的,非合并单元格仅含一个单元格,合并单元格包含至少两个单元格。
画表格就是画一个个单元格的过程。
3.1.2单元格属性参数的获得
从Excel文件中获得表1中单元格属性的各参数值,常用方法有以下两种。
(1)利用Excel读写组件
此组件是由北京用友华表软件公司研制的,包含了大量的解析Excel文件的接口函数,可以读取Excel文件,方便地获取各参数值。
这种方法方便、快捷、稳定性也比较好。
(2)利用COM技术
系统文件Exce19.olb满足COM编程规范,通过用#import Exce19.olb语句可以导出与Excel应用程序通讯的所有OLE自动化接口类及相关函数,从中可以找到表1中内容所需的接口函数。
3.2动态部分的实现
3.2.1实现原理
在Excel中单元格加批注,加入动态数据导入表格的全部描述,选择的单元格一般是第一个单元格,之后,用程序把批注内容转换为自定义格式的模板文件的动态填充部分。
应用程序获得批注内容的方法仍采用3.1.2中描述的方法:利用Excel读写组件或利用COM技术。
之所以用Excel软件中的批注功能,是因为它不会影响Excel模板文件的报表外观,只有鼠标移到加批注的单元格时,批注的内容才会以单独的窗口显示出来。
3.2.2实观类型
从上文描述知道:当把报表抽象成单元格时,则画报表就变得容易多了,因为静态框架描述部分的内容结构是确定的,但动态填充部分仍要分成表头、表体、表尾三部分分别处理:
(1)表头、表体均对应一条SQL语句
表头一般是非正规表格,动态描述部分应为:标志位+表头单元格填充坐标组+对应SQL 语句。
表体是正规的二维表格,描述内容应为:标志位+单元格填充起始坐标+对应SQL语句,当然还应该把一页填充的记录数加进去。
标志位的作用是判断报表的类型,以下同。
(2)表体对应一条SQL语句
描述结构为:标志位+单元格填充起始坐标+对应SQL语句+每页记录数。
(3)空表格
描述结构为空,仅有—个标志位。
(4)表格数据是人为添入的
描述结构为:标志位+单元格填充位置坐标组+储存填充单元格信息的字符串数组。
以上是四种常用的表内动态数据导入方法,可以根据需要加以扩充。
3.2.3应用方法
一般来说,在Excel批注功能中输入的是文本内容,最好采用标准的INI文件格式,以3.2.2表内数据导入方法(2)为例,相应的INI文件格式如表2所示。
可以利用VC系统提供的GetPdvateProfileString函数得到动态数据导入所需的各属性数值,非常方便。
但是由于起始时仅是在内存中获得了自定义模板数据中动态填充部分的内容,所以还必须先在客户端生成标准INI格式的临时文件,获取信息后,再把它删除。
3.3通用报表打印组件类层次
无论报表多么复杂,本文所述通用报表静态部分都是基于于单元格的,因此在基类中完成的功能是:根据静态部分的内容画出空表格。
而动态部分可以有多种类型,则对应着多个派生类,完成的功能是:从动态部分描述的内容中获取动态填充的初始化信息,如填充起始位置,SQL语句等,从而完成填充的全过程。
4结束语。