转自: http://www.51cto.com/art/200509/3145.htm
简介
本文介绍了一种WEB报表设计工具的实现思路和解决办法,该工具可以同数据库连接,让用户自己设计报表,报表的数据从数据库中获取,用户修改后的数据可以存回到数据库中。该工具可以实现任意形式(规整、不规整)的报表设计;不仅可以作为最终产品提交给用户使用,对于开发人员来说,也可以作为报表和数据库的设计工具来开发自己的产品。一个目的:让开发人员(至少是本人)不再做“报表苦力”。
前言与问题的提出
本人在C/S结构和B/S结构的软件开发过程中,碰到大量的设计报表的工作。用户有大量各式各样的报表需要实现,并且在系统验收后用户还会有一些报表需要实现。在开发C/S结构报表时使用PB,EXCEL,FORMULA ONE等工具埋头画表,在开发B/S机构的报表时使用ASP,XML/XSL等一个格一个格产生表;好半天完成了报表的样式设计,以为可以歇口气了,但还不行,还需要设计数据库,设计产生报表的方法函数,还要设计修改报表的接口、保存数据的函数;每一张报表都得开发人员亲自完成;好不容易提交用户测试了,用户又说:某某表的格式不对、某某表的公式不对、某某表的大小不对、帮忙增加几份新表……搞得人昏头涨脑,刚刚才有的一点成就感、一丝轻松又被叹气、唉声给冲跑了……要是能让用户自己去做这些污七八糟的事就好了!
正好接到一个金融系统的WEB办公系统项目,要实现的报表就有厚厚的一大摞,这还只是初步的需求,干脆,就设计一个“报表设计工具”,希望能解放以后的报表工作;当然,是在WEB上实现。
做报表设计工具,我以前做C/S结构的系统时就做过,也实现了(用PB6),用户用的也挺好。但是有缺点:一是不好移植在WEB上使用,二是只能显示报表,不能修改报表中的数据,当然更不能增加数据了。在WEB上又该如何实现呢?
实现的方式
要做WEB报表设计工具,必须先要知道报表什么东西?是如何产生和实现的?先理一理思路。
报表是什么?这个好说,就是把一些数据放在固定格式的固定位置上的表格。既然是表格,那么就有“表”有“格”,先要一个“格”一个 “格” 地“拼”出一“行”或一“列”来,再要一“行(列)”一“行(列)”地“拼”出一个“表”来。
虽然同样是由格子“拼”出来的,但有的表就好画,有的不好画,如下图1和图2所示:
图一
图二
明显地图1所示的报表比图2所示的报表要好“画”,我们将图1类型的表称作“规整报表”,而将图2类型的报表称作“不规整报表”。
说了半天废话,那么报表到底是如何产生和实现的呢?本人认为不外乎两种方式:“画”和“填”。
“画表”就是产生一格的同时也将数据按格式放在格子内,就是格式数据同时产生,这样整个表格画完了,表中的数据也有了,报表就生成了。这种方式适合于用来产生规整的报表,这样才可以逐行或逐列的画出该报表。这种方式的优点是产生报表快(成批处理数据)、处理程序简单(一个循环语句就可以了)。
“填表”与“画表”完全不同,他是必须先有表格格式,然后将指定的数据填在指定的表格位置中就可以了。这种方式既适合于用来产生不规整的报表,也适用于产生规整报表。这种方式的优点当然就是适用范围广,但缺点也有,就是速度慢,因为它要先获取表样,然后一个一个地取出数据,再一个一个地填在格中。
那么应该采取哪种实现方式呢?有两种解决方案:
1.分开处理:让用户在设计报表时确定报表是否规整(这是很简单的事),如果规整就让该报表采用“画表”方式产生,否则采用“填表”方式产生。
2.统一处理:全部采用“填表”方式产生。
本人觉得现在计算机的速度仍然在飞快的提高,硬件的“快”可以消除软件的“慢”,但主要是为了简化软件的设计和处理,采用了第二种实现方式:填表。
决定了实现的方式,开始考虑一些细节和技术上的事情了:要实现这个WEB报表设计工具,需要考虑哪些方面的事情,需要解决一些什么问题呢?
需要解决的问题
现在要考虑如何实现了。刚开始,初略一想,不就解决这几个问题吗:
1.如何画表即如何产生表样?必须是在浏览器内实现哟!
——简单:使用DHTML就行,结合使用XML/XSL。
2.如何保存表样?
——简单:都存在数据库的TEXT字段中
3.如何与数据库连接?
——简单:专门定义一个属性来与表示
4.如何显示数据?
——简单:使用DHTML技术、结合XML/XSL就可以实现
5.如何修改数据?
——简单:检测事件不就可以了吗!
6.如何保存数据?
——简单:写在数据库中就行。
仔细一想,才发现这里面问题多多:
7.怎么画表?用什么画?特别是必须在浏览器内实现。
8.如何设计表格样式?如粗体、下划线、斜体、小数字数、合并表格、删除表格等等样式设计操作。
9.表样如何保存?以什么格式保存?存在哪儿?
10.数据显示的位置如何定义?怎样定义?定义的结果如何保存?存在哪儿?又如何填数据?
11.单个数据显示的格式如何定义?怎样定义?定义的结果如何保存?存在哪儿?
12.报表如何与数据库连接?如何获取报表数据?获取数据的条件如何定义?怎样定义?定义的结果如何保存?存在哪儿?
13.用户要新增一张报表,又没有现成的数据库表对应,该如何让用户来设计数据库?数据库又该如何设计?
14.用户如何知道数据库定义的含义?如何知道某个格应该取数据库表中的哪个字段、哪个记录?
15.如何知道用户修改(增加)了报表数据?该数据如何与数据库表中的字段对应?如何才知道哪些格中的数据合起来是数据库表中的一条完整记录?又怎样才能知道用户输入的数据足够组成一条完整记录?怎样保存这些修改(增加)的数据呢?
16.有些根本不需要单独建立数据库表来保存的数据,又该如何保存?
17.报表的数据平衡关系设计?又如何定义?定义的结果如何保存?存在哪儿?
18.自动计算公式如何实现?又如何定义?定义的结果如何保存?存在哪儿?
19.如何从其它报表中提取数据来产生新报表?如何定义?定义的结果如何保存?存在哪儿?
20.如何定义报表的汇总(由分支机构的数据产生总机构的数据)?定义的结果如何保存?存在哪儿?
21.如何实现数据的上报----即数据格式的转换?转换程序如何设计?如何保存?存在哪儿?
……
越想问题越多,就越觉得麻烦,干脆放弃算了——苦力就做苦力吧,象本人这种手脚慢的人,也许设计完这个工具的时间,一大堆报表早就做完了。
回头看看为设计这个报表工具写的笔记和收集的资料,心有不甘;再掂掂报表的份量,太重又太多——难道老做苦力吗?不行!为自己的将来现在麻烦一点也值!可是这么多的问题需要解决,千头万绪一团糟,该如何开头呢?关键的问题是什么?
问题的关键
看看窗外的风景,等到静下心来,再看看这些罗列的问题,一个问题一个问题逐个进行衡量和比较,才发现首先要解决的问题就是“表样设计工具”该如何实现。因为报表的设计、显示、修改、保存等全部操作都是在该工具环境中实现的,数据库的连接、表样的保存等等工作都得围绕该工具的表现形式和接口形式来实现和调整。
既然找到了工作的头绪,那么开始设计吧!不要忙,“工具”的设计方案还没有定呢!
几种方案的比较
要在WEB上实现表样的设计有很多种方案可供选择:
1.使用XML/XSL/DHTML/HTML技术来实现
2.利用IE的WebBrowser ActiveX 控件来实现
3.自己写ActiveX控件
4.自己写Java Applet来实现
5.借用现成的第三方控件实现
那么哪种方案对本人来讲是比较好的呢?
先来了解各个方案的特点,将结果列表如下:
编号 | 方案名称 | 方案优点 | 方案缺点 |
1 | 使用XML/XSL/DHTML/HTML技术来实现 | 1. 可以自己定制 2. 对浏览器要求低 3. 表格格式易于实现 4. 数据格式转换容易实现 | 1. 开发周期长 2. 所有的功能都要开发 3. 计算公式不易实现 4. 对不规整表格不易实现 |
2 | 利用IE的WebBrowser ActiveX 控件来实现 | 1. 开发较快 2. 可以自己定制功能 3. 表格格式易于实现 | 1. 数据格式转换不易实现 2. 计算公式不易实现 3. 所有的功能都要开发 4. 对不规整表格不易实现 |
3 | 自己写ActiveX控件 | 1. 可以自己定制 2. 表格格式易于实现 3. 数据易于控制 4. 数据格式转换易于实现 5. 计算公式易于实现 | 1. 开发周期长 2. 所有的功能都要开发 3. 格式转换麻烦 |
4 | 自己写Java Applet实现 | 1. 可以自己定制 2. 对浏览器要求低 3. 表格格式易于实现 4. 数据易于控制 5. 计算公式易于实现 | 1. 开发周期长 2. 所有的功能都要开发 3. 格式转换麻烦 |
5 | 利用现成的第三方控件实现 | 1. 开发起来最快 2. 需要的功能大部分都有 | 1. 可能需要购买费用 2. 功能会受限制 |
表1
而筛选方案的原则是:
1.能满足工作要求
2.开发周期短
3.开发成本低
4.易于在WEB上发布使用
如果能够获取免费的第三方软件,无疑是第5种方案最好。找找看,有没有。还真找到了,就是Microsoft Office Web Components 中的SheetSpace控件,虽然不是免费的(必须要MS Office2000+支持),但用户都有使用MS Office,不仅开发成本降了,用户操作也习惯,就选他了——Microsoft Office Web Components中的SheetSpace控件。
解决的办法
既然关键的问题解决了,其它的就都好办了,下面整理后列举了相关问题的解决办法:
1.如何画表即如何产生表样?必须是在浏览器内实现哟!
—— 在Microsoft Office Web Components中的SheetSpace控件内设计表样,或者在MS EXCEL内设计好表样,再将其导入到Microsoft Office Web Components中的SheetSpace控件中显示出来;设计一个导入MS EXCEL的程序。数据显示格式、分页、固定表头、字体大小、颜色等等都在设计在表样中。
2.如何保存表样?以什么格式保存?存在哪儿?
——将Microsoft Office Web Components中的SheetSpace控件的结果存在数据库的TEXT字段中。表样的格式是 MS EXCEL 的HTML格式,由Microsoft Office Web Components中的SheetSpace控件可以直接获取。
3.如何与数据库连接?
——专门定义一个字段属性来表示该报表对应的数据库表(table)
4.如何显示数据?
——将报表数据从数据库中提取后以XML的格式保存在客户端,在Microsoft Office Web Components中的SheetSpace控件内显示,将获取的报表数据填在指定的单元格内。
5.如何知道用户修改(增加)了报表数据?该数据如何与数据库表中的字段对应?如何才知道哪些格中的数据合起来是数据库表中的一条完整记录?又怎样才能知道用户输入的数据足够组成一条完整记录?
——检测Microsoft Office Web Components中的SheetSpace控件的change事件,将目前单元格的值与原始数据比较,不相同则修改原始数据,并置修改标志。该数据与数据库字段的对应关系根据公式解释得来。这样也就可以知道哪些格中的数据合起来是数据库表中的一条完整记录。对于增加的数据,专门设计一个输入工具,来提示用户需要输入哪些数据才是完整的。
6.如何保存数据?
——对于XML中有修改(增加)标志的数据向服务器提交,服务器处理该数据再修改数据库中对应的数据。
7.如何设计表格样式?如粗体、下划线、斜体、小数字数、合并表格、删除表格等等样式设计操作。单个数据显示的格式如何定义?怎样定义?定义的结果如何保存?存在哪儿?
——Microsoft Office Web Components中的SheetSpace控件提供了这些操作函数,将这些函数以菜单的形式表现在页面上,提供用户操作的手段。用户操作产生的结果保存在表样中,在表样保存的时候一起保存在数据库中。
8.数据显示的位置如何定义?怎样定义?定义的结果如何保存?存在哪儿?又如何填数据?
——设计一个公式设计和解释器,将要显示的数据以公式的形式保存在表样中,该公式所在的位置就是数据要显示的位置,该公式所在单元格的格式就是数据的显示格式(如字体、颜色等等)。该公式同表样保存在一起。在显示数据的时候,根据公式来获取数据,并将其填入单元格中。
9.如何获取报表数据?获取数据的条件如何定义?怎样定义?定义的结果如何保存?存在哪儿?
——每份报表都定义“查询条件”属性,由该属性来获取一份完整的报表数据内容。该查询条件直接对应了数据库的字段;该属性同报表表样一起保存在数据库中。
10.用户要新增一张报表,又没有现成的数据库表对应,该如何让用户来设计数据库?数据库又该如何设计?
——设计一个在WEB页面上设计数据库的工具,让用户根据自己的实际需要来设计数据库结构。
11.用户如何知道数据库定义的含义?如何知道某个格应该取数据库表中的哪个字段、哪个记录?
——由于提供了数据库的设计工具,用该工具设计的数据库结构要求必须填写该字段的标题,即对该字段的含义说明;在用户定义公式的时候,显示的不是枯燥的英文字段名称,而是该字段的标题,便于用户理解。
12.有些根本不需要单独建立数据库表来保存的数据,又该如何保存?
——将不需要单独建数据库的报表我们区分开来,全部存放在一个公共的表(table)中,该表(table)中的数据既包含了报表样式又包含了报表数据。
13.报表的数据平衡关系设计?又如何定义?定义的结果如何保存?存在哪儿?
——报表的数据平衡关系完全用EXCEL的计算公式来实现。该公式同表样保存在一起。Microsoft Office Web Components中的SheetSpace控件可以支持绝大部分的MS EXCEL的公式。公式的用法和语法同MS EXCEL完全相同。
14.自动计算公式如何实现?又如何定义?定义的结果如何保存?存在哪儿?
——使用MS EXCEL的计算公式来实现,如sum,avg等等,该公式同表样保存在一起。
15.如何从其它报表中提取数据来产生新报表?如何定义?定义的结果如何保存?存在哪儿?
——报表具有一个属性叫做“取数程序”,用来从其他的数据库表(table)中提取数据插入本报表对应的数据库表 (table) 中。
16.如何定义报表的汇总(由分支机构的数据产生总机构的数据)?定义的结果如何保存?存在哪儿?
——报表具有一个属性叫做“汇总程序”,用来从下级机构的报表中汇总数据产生本机构的报表数据。
17.如何实现数据的上报----即数据格式的转换?转换程序如何设计?如何保存?存在哪儿?
——上报数据其实就是数据格式的转换,通过使用XSL可以十分方便的设计出来。该XSL转换程序以文本文件的形式保存在一个指定的目录中,文件的名称与报表一一对应。要产生上报数据的时候,将报表数据执行该转换后产生成一个文本文件,保存在客户端机器的用户指定位置上即可。
一份报表的完整定义保存在数据中,该数据库表的结构为:
序号 | 字段名 | 标题 | 数据类型 | 允许空 | 关键词 | 备注 |
1 | id | 报表编号 | int | no | yes |
|
2 | title | 报表名称 | varchar(100) | no | no |
|
3 | dbtable | 对应数据库表 | varchar(100) | no | no | 对应数据库表的名称 |
4 | style | 报表样式 | text | yes | no |
|
5 | style2 | 编译样式 | text | yes | no | 编译后的报表样式 |
6 | address | 公式地址 | text | yes | no | 公式地址,用,分隔 |
7 | query | 查询字段 | varchar(400) | yes | no | 字段--标题对,多个用|号分割 |
8 | orders | 排序字段 | varchar(400) | yes | no | 排序字段,多个用|号分割 |
9 | program | 汇总程序 | text | yes | no |
|
10 | program2 | 取数程序 | text | yes | no |
|
11 | program3 | 其它程序1 | text | yes | no |
|
12 | program4 | 其它程序2 | text | yes | no |
|
13 | createdate | 创建时间 | smalldatetime | yes | no |
|
14 | flags | 标志 | char(10) | yes | no | 保留未用 |
15 | status | 状态 | int | yes | no | 0:无效,1:有效 |
16 | DAC | 数据校验码 | varchar(20) | yes | no |
|
17 | appendix | 附加说明 | varchar(200) | yes | no |
|
表2:报表定义结构
为了操作的方便,又增加了批量处理的功能,让用户可以批量提取数据、汇总数据,简化用户的操作。
报表的全部处理流程就是这样的:
1.设计数据库定义
2.设计报表样式
3.插入取数公式
4.设置查询条件
5.设计汇总程序
6.设计取数程序
7.查询报表
8.汇总报表
9.批量汇总报表
10.提取报表数据
11.批量提取报表数据
12.生成上报文件
设计效果
好了,单枪匹马苦战一个多月,编码工作终于全部完成了,设计数据库的界面如图3所示,设计报表的界面如图4所示。
图三
图四
给用户试用,效果还不错,几十份各式各样的报表全部轻松解决。皇天不负“苦”心人。按照这种方式,本人又用一周的时间设计出了一个图表设计工具,用户反应也很好。图表设计界面如图4所示。
总结
本文讨论了一种行之有效的WEB报表设计工具的实现思想,并将实现。对于需要大量设计报表的用户,特别是报表格式和数量经常变化的用户,使用将非常方便。对于开发人员,也可以减少大量的工作。