摘 要:本文阐述一种利用asp实现web数据统计、报表的基本思路和实现方法,同时提供一种巧妙调用word打印报表的解决方案。
关键词: asp,数据统计,报表,打印,word
1、 引言
随着internet的飞速发展,基于web开发的业务应用系统越来越多,如办公自动化、电子商务和管理信息系统(mis)等。这些web业务应用系统经常涉及到数据的统计、报表和打印。asp在实施动态交互和生成动态页面方面具有很大的优势,但在处理复杂数据统计、报表和打印时却遇到不小的麻烦。本文阐述一种利用asp实现web数据统计、报表的基本思路和实现方法,同时提供一种巧妙调用word打印报表的解决方案。
2、 应用实例
假设有一家公司利用网络mis系统对公司员工进行管理,必然会涉及到各部门的员工统计。为了简单起见,假设最终的统计报表如下:
公司员工统计表
部门
合计
员工姓名
市场部
2
张三
李四
研发部
3
王五
赵六
刘七
员工合计
5
与传统单机mis系统相比,在网络mis系统中使用asp实现以上数据统计、报表和打印会遇到以下问题:
(1) 数据统计时需要按部门进行分类统计,同时要记下各部门员工的具体名单。
(2) 报表生成时需按具体要求动态绘制几行几列表格,同时在适当的地方保持空白。
(3) 表格打印可以简单地按网页打印,但效果不好,而且不容易控制。
3、 实现方法简述
基于web的业务应用一般采用三层结构,客户端是普通的web浏览器,中间业务逻辑应用层存放于web服务器上,由web服务器上的数据库接口访问后台数据库。利用asp实现web数据统计、报表和打印的过程如图所示:
浏览器
html
vbscript
统计
报表
word
对象
web服务器
业务逻辑实现
数据库
访问接口
数
据
库
word本地打印
(1) 客户端向web服务器发送数据统计请求。
(2) web服务器执行sql语句,从后台数据库取得统计数据,在页面上动态生成报表。
(3) 在客户端运行脚本,使用vbscript脚本函数createobject在本地创建word的document对象的实例,也就是在客户端创建word文档,设定表格属性,然后将页面上的报表数据填入本地word表格,最后保存文档,执行本地word打印。
4、 实现过程分析
(1)数据库连接
首先建立数据库(data.mdb),简单的员工资料表(personnel)结构如下:
personnel:department,文本;name,文本;
然后建立一个odbc数据源(dsn),利用dsn指向odbc数据库。
(2)程序代码分析(在此只分析统计报表程序tongji.asp)
<%
sql = "select department,count(department) from personnel group by department" //将记录按部门分类统计
set cnn = server.createobject("adodb.connection") //连接数据库
cnn.open "data"
set rs = server.createobject("adodb.recordset")
rs.cursortype = 3
rs.locktype = 3
rs.open sql, cnn
if rs.eof then //如果没有记录就结束
response.end
end if
%>
<html>
//以下显示表格标题和输出表头
<p align="center"><b><font size="4">公司员工统计表</font></b></p>
<div align="center">
<table id="data" border="1" width="606" height="53" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111"> //注意:此处标明表格的id为data
<tr>
<td width="93" height="24">
<p align="center"><font size="2">部门</font></td>
<td width="78" height="24">
<p align="center"><font size="2">合计</font></td>
<td width="413" height="24">
<p align="center"><font size="2">员工姓名</font></td>
</tr>
<%
hj=0 //设置变量,总人数合计初始值为0
//以下while循环按部门依次完成统计和报表
while (not rs.eof)
departmenttmp=rs("department") //设置临时变量,保存当前部门名称
sqlstr="select * from personnel where department="&departmenttmp&"" //找出当前部门的所有员工
set conn = server.createobject("adodb.connection") //再次连接数据库
conn.open "data"
set rss = server.createobject("adodb.recordset")
rss.cursortype = 3
rss.locktype = 3
rss.open sqlstr, conn
number=0 //设置变量,当前部门人数合计初始值为0
//以下while循环计算出当前部门人数合计
while(not rss.eof)
rss.movenext
number=number+1
wend
hj=hj+number //总人数合计为各部门人数之和
rss.movefirst
flag=0 //设置变量,flag用来判断当前部门是否首次出现,初始值为0
//以下while循环输出当前部门统计数据和员工名单
while(not rss.eof)%>
<tr>
<%if (flag=0) then%>
//如果flag为0,表示该部门是首次出现,表格此处就应该输出部门名称,部门员工合计人数
<td width="93" height="24"><p align="center"><font size=2><%=departmenttmp%></font></td>
<td width="78" height="24"><p align="center"><font size=2><%=number%></font></td>
<%else%>
//如果flag不为0,表示该部门不是首次出现,表格此处就应该输出空白
<td width="93" height="24"><p align="center"> </td>
<td width="78" height="24"><p align="center"> </td>
<%end if%>
//无论该部门是否首次出现,此处输出员工姓名
<td width="413" height="24"><p align="center"><font size=2><%=rss("name")%></font></td>
<%rss.movenext //当前部门员工记录指针rss指向下一个员工记录
flag=flag+1 //flag加1
wend%>
</tr>
<%rs.movenext //部门记录指针rs指向下一个部门记录
wend%>
<tr>
//表格最后一行输出总人数合计
<td width="93" height="24"><p align="center"><font size=2>员工合计</font></td>
<td width="78" height="24"><p align="center"><font size=2><%=hj%></font></td>
<td width="413" height="24"><p align="center"><font size=2> </font></td>
</tr>
</table>
</div>
<input type=button onclick="vbscript:builddoc" value="打印"> //点击“打印”按钮,调用vbscript函数builddoc生成本地word文档,实现本地打印。
</html>
//以下vbscript代码实现builddoc函数
<script language="vbscript">
sub builddoc
set table = document.all.data //把html文档中的表格data的结构和数据赋值给table
row = table.rows.length //row为table的行数
column = table.rows(1).cells.length //colnum为table的列数
set objworddoc = createobject("word.document") //创建一个word.document的对象
dim thearray(10,10000) //定义数组变量,存放表格中的数据,10是虚拟列数,10000是虚拟行数
//以下两层for循环将html文档的表格中的纯文本数据赋值给数组
for i=0 to row-1
for j=0 to column-1
thearray(j+1,i+1) = table.rows(i).cells(j).innertext
next
next
objworddoc.application.activedocument.paragraphs.add.range.insertbefore("公司员工统计表") //显示表格标题
objworddoc.application.activedocument.paragraphs.add.range.insertbefore("") //输出标题后回车换行
set rngpara = objworddoc.application.activedocument.paragraphs(1).range
//以下with代码段设置标题属性
with rngpara
.bold = true //将标题设为粗体
.paragraphformat.alignment = 1 //将标题居中
.font.name = "arial" //设定标题字体
.font.size = 12 //设定标题字体大小
end with
set rngcurrent = objworddoc.application.activedocument.paragraphs(3).range
set tabcurrent = objworddoc.application.activedocument.tables.add(rngcurrent,row,column)
//以下for循环输出表头
for i = 1 to column
objworddoc.application.activedocument.tables(1).rows(1).cells(i).range.insertafter thearray(i,1)
objworddoc.application.activedocument.tables(1).rows(1).cells(i).range.paragraphformat.alignment=1
next
//以下两层for循环输出表格实际内容
for i =1 to column
for j = 2 to row
objworddoc.application.activedocument.tables(1).rows(j).cells(i).range.insertafter thearray(i,j)
objworddoc.application.activedocument.tables(1).rows(j).cells(i).range.paragraphformat.alignment=1
next
next
objworddoc.application.activedocument.saveas
end sub
</script>
5、 结束语
以上程序在windows2000及iis5.0下运行通过,数据库采用access2000。执行打印之前,需要将浏览器的安全级别设为低,或在中级安全级别下将activex控件设为启用。该方法的优点在于实现统计报表十分简单,调用word打印非常方便,并且可以按用户要求对表格属性进行设置;不足之处是需要调节浏览器的安全设置,且不支持图片和特殊字体的打印,同时客户端必须安装microsoft word软件。
参考文献:
[1]《active server page & web数据库》,王国荣著,人民邮电出版社,2000。
[2] msdn library visual basic文档
参考网址:
动感教育网 www.activeedu.net
