报表打印是管理信息系统中的一个重要模块。在实际应用中,可以将用户录入的数据或者数据库中的统计结果,以报表的形式表现出来并进行打印,这样不仅使用户可以宏观地查看数据,还可以针对当前的情况制定下一步的计划方案。
在ASP应用程序中,可以通过调用组件、Excel、Word或者应用XML技术等进行报表打印,还可以根据实际情况设置页面及其他的打印属性等。应用报表打印技术,可以使数据信息具有概括性和统计性,并使数据信息以指定的格式由打印机打印输出,方便用户查看和浏览。本章将介绍几个实用的报表打印方案,如简单报表打印方案、Excel报表打印方案、XML技术报表打印方案、Word报表打印方案、图形报表打印方案等,使读者能够掌握各种报表打印方法,并能够灵活运用。
报表打印是指先将存储的数据经过格式编排、适当运算,然后再将其进行打印,以供相关人员查看。报表的应用氛围很广,例如:为了反映企业某一特定日期的资产负债和所有者权益状况,以及某一特定时期的经营成果和现金流量情况,可以制订企业报表;为了明确产品的详细销售记录以及统计产品在某一时期的销售和收入情况,可以制订销售报表;为了宏观统筹国民经济各行业各部门的经营现状,可以制订月度、季度的定期统计报表和年度统计报表;报表还可以应用在财务、仓储、生产等各领域。
报表的基本类型包括明细报表、主从报表、分组报表、分栏报表、子报表、图形报表、交叉报表等。报表的基本元素包括页眉、页脚、横表头、竖表头、报表细节等。在ASP应用程序中,可以根据实际情况,设计报表的格式。下面介绍几种报表设计方法,分别为表格+CSS设计方法、DIV+CSS设计方法、XML+CSS设计方法和XML+XSL设计方法。
表格是网站常用的页面元素,是网页排版的灵魂,在页面中用表格来显示数据,直观清晰,而且HTML的表格使用起来非常灵活。无论是使用简单的HTML语言编辑的网页,还是具有动态网站功能的网页,都可以借助表格进行排版。许多较复杂的页面布局也可以利用表格来完成。为了使表格更符合排版要求,可以定义CSS层叠样式表,通过调用其中的样式来规范文字显示方式和表格的显示格式等。下面主要介绍表格的一些相关内容。
在HTML中的表格主要由3个标记构成,分别为表格标记<TABLE>、行标记<TR>、单元格标记<TD>。
语法:
<TABLE>
<TR>
<TD>…</TD>
…
</TR>
<TR>
<TD>…</TD>
…
</TR>
…
</TABLE>
表格的属性如表5.1所示。
表5.1 表格的属性
属性 |
描 述 |
WIDTH |
表格宽度 |
HEIGHT |
表格高度 |
ALIGN |
表格水平对齐 |
CELLSPACING |
表格单元格间距 |
CELLPADDING |
表格单元格边距 |
BGCOLOR |
表格背景颜色 |
BACKGROUND |
表格背景图像 |
BORDER |
表格边框 |
BORDERCOLOR |
表格边框颜色 |
BORDERCOLORLIGHT |
表格亮边框色 |
BORDERCOLORDARK |
表格暗边框色 |
FRAME |
表格边框样式 |
RULES |
表格内部边框样式 |
通过设置表格的自有属性,可以设计出不同风格的表格。读者可尝试通过设置表格的属性,制作出指定格式的表格。
下面介绍表格的相关标记,分别为行标记<TR>、单元格标记<TD>、表格的标题与表头标记以及表格的结构标记。
(1)行标记<TR>
行标记<TR>具有特定的属性,其属性用于设定表格中某一行的显示格式。行标记<TR>属性如表5.2所示。
表5.2 行标记<TR>的属性
行标记<TR>属性 |
描 述 |
Align |
行内容水平对齐 |
Valign |
行内容垂直对齐 |
Bgcolor |
行的背景颜色 |
Bordercolor |
行的边框颜色 |
Bordercolorlight |
行的亮边框色 |
Bordercolordark |
行的暗边框色 |
(2)单元格标记<TD>
单元格标记<TD>具有特定的属性,其属性用于设定表格中某一单元格的显示格式。单元格标记<TD>属性如表5.3所示。
表5.3 单元格标记<TD>的属性
单元格标记<TD>属性 |
描 述 |
Width |
单元格的宽度 |
Height |
单元格的高度 |
Align |
单元格内容的水平对齐 |
Valign |
单元格内容的垂直对齐 |
Bgcolor |
单元格的背景颜色 |
Background |
单元格的背景图像 |
Bordercolor |
单元格的边框颜色 |
Bordercolorlight |
单元格的亮边框色 |
Bordercolordark |
单元格的暗边框色 |
Rowspan |
单元格的跨行属性 |
Colspan |
单元格的跨列属性 |
(3)表格的标题与表头标记
在HTML语言中,可以通过标记<CAPTION>为表格添加标题。
l 表格的标题标记<CAPTION>
通过标记<CAPTION>设定表格的标题。
语法:
<CAPTION>…</CAPTION>
可以通过标记<CAPTION>的ALIGN属性和VALIGN属性,设置标题在水平方向(设置为left表示为居左对齐;设置为center表示居中对齐;设置为right表示居右对齐)和垂直方向(设置为top表示标题在表格的上方;设置为bottom表示标题在表格的下方)相对于表格的对齐方式。
l 表格的表头<TH>
表头是指表格的第一行,应用标记<TH>时,在标记<TH>中的文字居中对齐并且会加粗显示,方便用户排版。
语法:
<TABLE>
<TR>
<TH>…</TH>
<TH>…</TH>
…
</TR>
</TABLE>
(4)表格的结构标记
为了在HTML源代码中区分表格结构,HTML语言规定了<THEAD>、<TBODY>和<TFOOT>3个标记,分别应用于表格的表首、表主体和表尾。下面分别介绍这3个标记。
l 表格的表首标记<THEAD>
语法:
<THEAD ALIGN=value BGCOLOR=color_value VALIGN=value>
ALIGN:代表水平对齐,value值可以为left居左,center居中或者right居右。
BGCOLOR:表首行的背景颜色。
VALIGN:代表垂直对齐,value值可以为top居上,middle居中或者bottom居下。
l 表格的表主体标记<TBODY>
语法:
<TBODY ALIGN=value BGCOLOR=color_value VALIGN=value>
ALIGN:代表水平对齐,value值可以为left居左,center居中或者right居右。
BGCOLOR:表主体行的背景颜色。
VALIGN:代表垂直对齐,value值可以为top居上,middle居中或者bottom居下。
l 表格的表尾<TFOOT>
语法:
<TFOOT ALIGN=value BGCOLOR=color_value VALIGN=value>
ALIGN:代表水平对齐,value值可以为left居左,center居中或者right居右。
BGCOLOR:表尾行的背景颜色。
VALIGN:代表垂直对齐,value值可以为top居上,middle居中或者bottom居下。
DIV+CSS在网页布局中的应用得到不断的扩展,例如,在XHTML网站设计标准中,可以采用DIV+CSS的方式实现各种定位等。其优点如下:
(1)它本身符合W3C标准,并且支持浏览器的向后兼容。
(2)使用DIV+CSS技术设计的网页,能够更容易被搜索引擎收录。
(3)DIV+CSS设计方法能够将页面显示内容和外观样式分离开来、能够通过CSS样式对DIV标记进行格式限定,从而减少程序代码的编写数量,并且能缩短网页打开时间以方便用户浏览。内容和样式的分离,使页面和样式的调整变得更加方便。
DIV是用来为HTML文档内的区块内容提供结构和背景的元素。DIV起始标记<DIV>与结束标记</DIV>之间的所有内容都是用来构成这个块的,其中所包含元素的特性可以通过定义DIV标记属性或者通过使用样式格式化区块来控制。<DIV>标记可用于设定文字、图形、表格等的摆放位置。
在DIV标记的属性如表5.4所示。
表5.4 DIV标记的属性
DIV标记的属性 |
描 述 |
id |
表示DIV标记的名称或调用的样式名称 |
align |
表示对齐方式 |
style |
定义显示的样式,如:在该属性中可以定义DIV显示的位置、是否透明显示、指定浏览器如何处理溢出等, |
class |
调用的CSS样式 |
title |
表示DIV元素的标题 |
<DIV>标记与<P>标记都可以定义块,但是两者的作用不尽相同。<DIV>标记本身没有特别的作用,不能产生空行或空格,并且<DIV>标记必须有结束标记;<P>标记本身可以增添一个空白行,可以有对应的结束标记</P>,也可以没有结束标记。
在实际应用中,一般使用定义的CSS样式来严格设定DIV的位置以及显示格式等,如:
DIV{position:absolute; left:200px; top:40px; height:150px}
通过DIV+CSS设计方法可以高效的制作出符合用户要求的页面或者报表格式等。
在XML文档中可以调用CSS样式表来规范XML文档内容。在XML文档中通过直接链接一个CSS样式表文件,来调用其中定义的样式。需要注意的是,CSS样式表中指定的样式名称应与XML文档中定义的元素名称相同。
语法:
<?xml-stylesheet type=“text/css”href=“CSS样式表文件路径”?>
XSL(eXtensible Stylesheet Language)语言与CSS样式表的功能类似。在一个XML文档中链接一个XSL样式表可以规范显示的XML数据。在XML文档中应用CSS样式表只允许指定每个XML元素的格式,而XSL样式表允许对输出的数据进行完整的控制。XSL样式表能够精确地选择想要显示的XML数据,能够按照任意顺序排列显示的数据,能够方便地修改或者添加数据。
XSL是XML的一个应用,即一个XSL样式表是一个遵守XML规则格式的正确有效的XML文档,其扩展名为.xsl。
在XML文档中使用XSL样式表的语法如下:
<?xml-stylesheet type=“text/xsl”href=“XSL样式表路径”?>
在ASP中,通过JavaScript脚本调用IE浏览器自身的打印功能可以将当前页面中的内容进行打印。调用JavaScript脚本window对象的print()方法,可以实现打印功能。
语法:
window.print();
例如,在超链接标记<A>中的onClick事件调用Window对象的print()方法,代码如下:
<a href="#" onClick="window.print()">JavaScript脚本打印</a>
在ASP页面中可以调用IE内置的浏览器控件WebBrowser,通过使用WebBrowser控件的Execwb方法可实现打印预览、打印、进行页面设置等操作。
在页面中调用控件WebBrowser的语句如下:
<object id=WebBrowser classid=ClSID:8856F961-340A-11D0-A96B-00C04Fd705A2 width="0" height="0"></object>
下面介绍WebBrowser控件的Execwb方法,该方法主要用于对IE浏览器页面的操作。
语法:
WebBrowser.ExecWB nCmdID,nCmdExecOpt,[pvaIn],[pvaOut]
nCmdID:表示执行命令的ID号。
nCmdExecOpt:命令执行的参数,一般设定其值为1。
其中nCmdID参数值如表5.5所示。
表5.5 nCmdID参数值
nCmdID参数 |
参数值 |
描 述 |
OLECMDID_OPEN |
1 |
打开 |
OLECMDID_NEW |
2 |
新建 |
OLECMDID_SAVE |
3 |
保存 |
OLECMDID_SAVEAS |
4 |
另存为 |
OLECMDID_SAVECOPYAS |
5 |
复制另存为 |
OLECMDID_PRINT |
6 |
打印 |
OLECMDID_PRINTPREVIEW |
7 |
打印预览 |
OLECMDID_PAGESETUP |
8 |
页面设置 |
OLECMDID_SPELL |
9 |
拼写检查 |
OLECMDID_PROPERTIES |
10 |
属性 |
OLECMDID_CUT |
11 |
剪切 |
OLECMDID_COPY |
12 |
复制 |
OLECMDID_PASTE |
13 |
粘贴 |
OLECMDID_PASTESPECIAL |
14 |
选择性粘贴 |
OLECMDID_UNDO |
15 |
撤消 |
OLECMDID_REDO |
16 |
重做 |
OLECMDID_selectALL |
17 |
全选 |
OLECMDID_CLEARselectION |
18 |
清除选区 |
OLECMDID_ZOOM |
19 |
显示比例 |
OLECMDID_GETZOOMRANGE |
20 |
获得显示比例 |
OLECMDID_updateCOMMANDS |
21 |
更新 |
OLECMDID_REFRESH |
22 |
刷新 |
OLECMDID_STOP |
23 |
停止,停止当前所有操作 |
OLECMDID_HIDETOOLBARS |
24 |
工具条 |
OLECMDID_SETPROGRESSMAX |
25 |
设定进度条的最大值 |
OLECMDID_SETPROGRESSPOS |
26 |
设定当前进度条的值 |
OLECMDID_SETPROGRESSTEXT |
27 |
设定当前进度条文本 |
OLECMDID_SETTITLE |
28 |
设定标题 |
OLECMDID_SETDOWNLOADSTATE |
29 |
设定下载状态 |
OLECMDID_STOPDOWNLOAD |
30 |
停止下载 |
nCmdExecOpt参数值如表5.6所示。
表5.6 nCmdExecOpt参数值
nCmdExecOpt参数 |
参数值 |
描 述 |
OLECMDEXECOPT_DODEFAULT |
0 |
预定执行动作 |
OLECMDEXECOPT_PROMPTUSER |
1 |
显示输入 |
OLECMDEXECOPT_DONTPROMPTUSER |
2 |
不显示输入 |
OLECMDEXECOPT_SHOWHELP |
3 |
显示说明 |
以上介绍了各参数的取值,下面介绍一些常用的命令(其中WebBrowser表示调用WebBrowser控件时定义的ID名称),如:
WebBrowser.Execwb(1,1)表示打开页面。
WebBrowser.Execwb(2,1)表示关闭现在所有的IE窗口,并打开一个新窗口。
WebBrowser.Execwb(4,1)表示保存网页。
WebBrowser.Execwb(6,1)表示打印页面。
WebBrowser.Execwb(6,6)表示直接打印页面。
WebBrowser.Execwb(7,1)表示打印预览页面。
WebBrowser.Execwb(8,1)表示进行打印页面设置。
WebBrowser.Execwb(10,1)表示查看页面属性。
WebBrowser.Execwb(22,1)表示刷新页面。
WebBrowser.Execwb(45,1)表示关闭窗体时无提示。
读者可根据实际情况,通过设置Execwb方法中各参数值,对页面进行各项操作。
Microsoft Excel是Microsoft提供的用于办公管理的应用软件,它具有强大的报表打印功能。
最初的一些管理信息系统基本上是采用客户机/服务器(C/S)模式进行开发的,但随着互联网的广泛应用,目前的管理信息系统已经逐渐开始从C/S模式向浏览器/服务器(B/S)模式转变。B/S模式有很多优点,如更加开放、与软硬件无关、应用扩充性强、易于系统维护升级等。基于B/S模式,Excel报表打印功能也得到了进一步的应用。下面介绍几种Excel报表打印的方法。
(1)直接将网页内容导入到Excel
在ASP应用程序中,为了方便用户进行报表打印的操作,通过设置Response对象的ContentType属性值,可以将网页中的内容(一般为表格数据)直接导入到Excel中进行编辑,即打开网页时可直接在Excel中编辑数据信息。
Response对象的ContentType属性指定服务器响应的HTTP内容类型。
语法:
Response.ContentType[=ContentType]
ContentType:描述内容类型的字符串,该字符串通常被格式化为类型/子类型,其中类型是常规内容范畴,而子类为特定内容类型,默认为“text/html”。
常用类型与子类型有:“text/html”、“image/gif”、“image/jpeg”。浏览器负责解释这些不同类型和子类型,调用客户端安装的联合程序,对文档进行查看及浏览。
将以下语句放置在页面的首行,即可实现直接将网页内容导入到Excel的操作。
<%response.ContentType="application/vnd.ms-excel"%>
(2)将网页内容写入到Excel
Microsoft Excel是Microsoft提供的用于办公管理的应用软件,它具有强大的表格统计功能。在ASP应用程序中,通过在JavaScript脚本中应用Application对象、Workbook对象、Worksheet对象和Range对象的相关属性和方法,可以实现将Web页面中的数据写入到Excel,然后由Excel自动打印报表内容的功能。
l Excel的Application对象
Excel的Application对象是Excel对象模型中的顶级对象。使用Application 对象可以确定或指定应用程序级属性或执行应用程序级方法。Application对象也是访问Excel对象模型的其它部分的转入点。
在JavaScript脚本中应用ActiveXObject()构造函数可以创建一个Excel.Application对象的实例,即显式引用Application对象。下面介绍Application对象的常用属性和方法。
² ActiveCell属性
ActiveCell属性返回一个Range对象,该对象代表活动窗口的活动单元格,或指定窗口的活动单元格。如果该窗口显示的不是工作表,则该属性无效。此属性为只读属性。下列表达式都是返回活动单元格,并都是等价的。
ActiveCell
或
Application.ActiveCell
或
ActiveWindow.ActiveCell
或
Application.ActiveWindow.ActiveCell
如果不指定对象识别符,本属性返回的是活动窗口中的活动单元格。活动单元格与选定区域是有区别的:活动单元格是当前选定区域内的单个单元格;选定区域可能包含多个单元格,但其中只有一个是活动单元格。
² ActiveChart属性
ActiveChart属性返回Chart对象,该对象代表活动图表(包括嵌入式图表或图表工作表)。当选定或激活嵌入式图表时,该嵌入式图表就成为当前活动的图表。如果当前没有活动的图表,本属性返回值为Nothing。此属性为只读属性。
语法:
[对象识别符.]ActiveChart
如果未指定对象识别符,此属性返回活动工作簿上的活动图表。
² ActivePrinter属性
通过ActivePrinter属性可以设置或返回活动打印机的名称。此属性为可读写的字符串类型。
语法:
Application.ActivePrinter
² ActiveSheet属性
ActiveSheet属性返回一个Worksheet对象,该对象代表活动工作簿中的,或者指定窗口工作簿中的活动工作表。如果没有活动的工作表,将返回值Nothing。此属性为只读属性。
语法:
[对象识别符.]ActiveSheet[.对象对应的属性]
如果未给出对象识别符,此属性返回活动工作簿中的活动工作表。
如果某一工作簿在若干个窗口中出现,那么该工作簿的ActiveSheet属性在不同窗口中的返回值可能不同。
² ActiveWorkbook属性
ActiveWorkbook属性返回一个Workbook对象,该对象代表活动窗口的工作簿。此属性为只读属性。
语法:
[对象识别符.]ActiveWorkbook[.对象对应的属性]
如果没有打开任何窗口、活动窗口、信息窗口或剪贴板窗口,则此属性返回值Nothing。
² Cells属性
Cells属性返回Range对象,该对象代表活动工作表中所有的单元格。此属性为只读属性。
语法:
[对象识别符.]Cells
如果当前活动文档不是工作表,则不能读取此属性值。
² Charts属性
Charts属性返回一个Sheets集合,该集合代表活动工作簿中的所有图表工作表。此属性为只读属性。
语法:
[对象识别符.] Charts
如果不给出对象识别符,将返回活动工作簿中所有的图表工作表。
² Columns属性
Columns属性返回一个Range对象,该对象代表活动工作表中的所有列。此属性为只读属性。
语法:
[对象识别符.]Columns
如果活动文档不是工作表,则Columns属性无效。
² Parent属性
Parent属性返回指定对象的父对象。此属性为只读属性。
语法:
对象识别符.Parent
² Path属性
Path属性是将Microsoft Excel的完整路径返回给应用程序,但不包括末尾的分隔符和应用程序名称。字符串类型,并为只读属性。
语法:
对象识别符.Path
² Range属性
Range属性返回一个Range对象,该对象代表一个单元格或单元格区域。
语法:
对象识别符.Range(Cell1,Cell2)
Cell1:表示区域名称,为必填项。可包括区域操作符(冒号)、相交区域操作符(空格)或合并区域操作符(逗号)。可在区域中任一部分使用局部定义名称。
Cell2:表示区域左上角和右下角的单元格,为可选项。可以是一个包含单个单元格、整列或整行的Range对象,或是一个用宏语言为单个单元格命名的字符串。
如果没有使用对象识别符,则该属性是ActiveSheet.Range
的快捷方式(它返回活动表的一个区域,如果活动表不是一张工作表,则该属性无效)。
² Rows属性
Rows属性返回代表活动工作表所有行的Range对象。如果活动文档不是工作表,Rows属性无效。
语法:
[对象识别符.]Range
在不用对象识别符的情况下使用此属性等价于ActiveSheet.Rows
。
² Sheets属性
Sheets属性返回代表活动工作簿中所有工作表的Sheets集合。
语法:
[对象识别符.]Sheets
在不用对象识别符的情况下,使用此属性等价于使用ActiveWorkbook.Sheets
。
² UserControl属性
如果应用程序可见,或者用户已创建或启动应用程序,则UserControl属性值为True。如果以编程方式通过CreateObject函数或GetObject函数启动应用程序,且应用程序为隐藏状态,则该属性值为False。此属性可读写。
语法:
对象识别符.UserControl[=属性值]
当对象的UserControl属性为False时,则最后一个以编程方式对该对象的引用释放以后,该对象也将释放。如果属性值为False,并且会话中最后一个对象已释放,Microsoft Excel将自动退出。
² Workbooks属性
Workbooks属性返回一个Workbooks集合,此集合代表所有打开的工作簿。此属性为只读属性。
语法:
[对象识别符.]Workbooks
在不使用对象识别符的情况下,使用此属性等价于Application.Workbooks
。
由Workbooks属性返回的集合并不包含打开的加载宏(一种特殊的隐藏工作簿)。但如果已知宏文件名,则可返回单个打开的加载宏。例如,Workbooks("mr.xla")
将打开的名为“mr.xla
”的加载宏作为Workbook属性返回结果。
² Quit方法
调用Quit方法将退出Microsoft Excel。
语法:
对象识别符.Quit
使用此方法时,如果有未保存的工作簿处于打开状态,则Microsoft Excel将弹出一个对话框,询问是否要保存所作的更改。为避免这一情况,可在使用Quit方法前保存所有的工作簿或将DisplayAlerts属性(宏运行时Microsoft Excel显示特定的警告和消息,默认值为True)设置为False,这时在Microsoft Excel退出时,即使有未保存的工作簿,也不会显示对话框,而且不保存就执行退出命令。
l Excel的Workbook对象
Workbook对象表示一个.xls或.xla工作簿文件。使用Workbook对象可以处理单个Excel工作簿。使用Workbooks集合可以处理所有当前打开的Workbook对象。
使用Application对象的ActiveWorkbook属性可以返回对当前活动工作簿的引用。Workbooks集合中的Count属性可以用于确定打开了多少可见工作簿和隐藏工作簿。默认情况下,Excel通常有一个名为Personal.xls的隐藏工作簿,它是由Excel作为宏的存储位置而创建的。如果隐藏的Personal.xls工作簿是唯一打开的工作簿,ActiveWorkbook属性将返回字符串Nothing;而Workbooks集合的Count属性将返回1,仅当没有打开的隐藏或可见工作簿时,Workbooks集合的Count属性才返回0。
下面介绍几个Workbook对象的常用方法。
² Add方法
使用Workbooks集合的Add方法可以创建新的Workbook对象。Add方法不但创建新的工作簿,同时立即打开创建的工作簿。调用Add方法还将返回一个表示创建的新工作簿的对象变量。
语法:
对象识别符.Add
² SaveAs方法
调用Workbook对象的SaveAs方法并指定要保存的工作簿的名称,可以保存新工作薄。如果已存在该名称的工作簿,则调用此方法时将出现错误。使用SaveAs方法保存工作簿之后,可以使用Workbook对象的Save方法来保存其它更改,也可以使用SaveCopyAs方法用另一个文件名来保存现有工作簿的副本。
Workbook对象的Name属性是一个由Excel指定的值,使用SaveAs方法保存新工作簿后,Name属性将为SaveAs方法的Filename参数中提供的名称。Name属性是只读的,所以要更改工作簿的名称,必须再次使用SaveAs方法,并在Filename参数中传递另一个值。
语法:
对象识别符.SaveAs(Filename)
Filename:表示保存的Excel文件名称。
注意:Workbook对象的FullName属性包含对象的路径和文件名,而Path属性只包含当前工作簿的已保存路径。保存新工作簿之前,FullName属性值与Name属性值相同,而Path属性不包含任何值。
² Open方法
Workbooks集合的Open 方法可用于打开现有的工作簿。使用Open方法打开工作簿后,该工作簿即成为活动工作簿。在调用Open方法时可以指定文件名。
语法:
对象识别符.Open(Filename)
² Close方法
Workbook对象的Close方法用于关闭打开的工作簿。
语法:
对象识别符.Close
注意:Workbook对象的Saved属性返回的是一个布尔值,该值指明该工作簿是否已经保存。对于任何新建或已打开但没有进行任何更改的工作簿,Saved属性将为True;对于包含未保存更改的工作簿,该属性则为False。可以将Saved属性设置为True,这样做的用处在于,当用户关闭工作簿时如果未对工作簿做任何更改,可以不提示用户保存更改。
l Excel的Worksheet对象
用户在Microsoft Excel中进行的大多数工作是在工作表环境中进行的。工作表包含用于处理数据的单元格,以及数百个用于处理工作表中数据的属性、方法和事件。
Worksheet对象包含在Worksheets集合中,可以使用Workbook对象的Worksheets属性来访问工作表中的数据。通过Workbook对象的Worksheets属性可以返回工作簿中所有工作表的集合,通过Workbook对象的Sheets属性可以返回工作簿中所有工作表和图表工作表的集合。
使用Worksheets集合的Add方法,可以将一个或多个工作表添加到Worksheets集合中;调用Worksheet对象的Delete方法可以从Worksheets集合中删除工作表。
l Excel的Range对象
在Microsoft Excel中,Range对象是功能强大、应用灵活的对象之一。
就对象而言,Excel的Range对象是比较独特的。一个区域在不同情况下可以是不同的事物,Range对象可以是单个单元格或单元格集合;可以是单个对象或对象的集合;可以是某个行或列;可以表示三维的跨多个工作表的单元格集合。此外,与其他对象不同,工作簿或工作表中不存在包含所有Range对象的Ranges集合。
为了弥补HTML语言不可扩展的缺点,并适应当前网站中庞大数据交换的需求,Web标准化组织万维网联合会建议并推出可扩展标记语言XML(eXtentsible Markup Language)。XML语言是一种精简的标准通用化标记语言SGML(Standard Generalized Markup Language)版本,是一种提供数据描述格式的标记语言,适用于不同应用程序间的数据交换,而且这种交换不以预先定义的一组数据结构为前提,增强了可扩展性。
在ASP应用程序中,可以应用XML相关技术进行报表打印。ASP应用DOM技术可以读取(包括远程读取)或存储XML数据,而且在XML文挡中数据与显示格式是分离的,从而可以方便地规定XML文档中数据的输出格式,利于报表打印。
下面介绍XML文档的结构、XML语法要求和DOM技术。
l XML文档的结构
XML是一套定义语义标记的规则,是可以定义其他标识语言的元标识语言。在XML文档中可以自定义标记和文档结构。
下面通过一个XML文档示例来介绍XML的文档结构。
<?xml version="1.0"?>
<?xml-stylesheet type=“text/css”href=“style.css”?>
<!-- 这是XML文档的注释 -->
<RESUME>
<NAME>明日科技</ NAME >
<EMAIL>mingrisoft@mingrisoft.com</EMAIL>
<HOMEPAGE>http://www.mingrisoft.com</HOMEPAGE>
<PUBLICATION>
<BOOK>
<TITLE>ASP技术</TITLE>
<PAGES>760</PAGES>
</BOOK>
<BOOK>
<TITLE>SQL技术</TITLE>
<PAGES>520</PAGES>
</BOOK>
</PUBLICATION>
</RESUME>
XML文档总体上包括两部分:序言和文档元素。
² 序言
序言中包含XML声明、处理指令和注释。序言必须出现在XML文档的开始处。
上面示例代码中的第1行是XML声明,用于说明这是一个XML文档,并且给出版本号。示例代码中的第2行是一条处理指令,引用处理指令的目的是提供有关XML应用程序信息,本示例中处理指令告诉浏览器使用CSS样式表文件style.css。示例代码中的第3行为注释语句。
² 文档元素
XML文档中的元素是以树型分层结构排列的,元素可以嵌套在其他元素中。文档中必须只有一个顶层元素,称为文档元素或者根元素,类似于HTML页中的BODY元素,其他所有元素都嵌套在根元素中。文档元素中包含各种元素、属性、文本内容、字符和实体引用、CDATA区等。
在上面示例代码中,文档元素是RESUME,其起始和结束标记分别是<RESUME>、</RESUME>。在文档元素中定义了标记<NAME>、<EMAIL>、<HOMEPAGE>、<PUBLICATION>,分别代表的含义为名称、电子邮箱、主页地址、出版物信息;在标记<PUBLICATION>中定义了两个<BOOK>标记,用于说明出版物情况;<BOOK>标记中定义了标记<TITLE>、<PAGES>,说明出版物的名称、页码信息。
在XML文档中,元素指出了文档的逻辑结构,并且包含了文档的信息内容。
HTML语言也是一种基于SGML的语言,XML在形式上与HTML相似,但是实际上和HTML有很大区别。下面介绍XML和HTML的主要不同点。
(1)XML是关于如何描述信息的语言,使用XML可以让应用程序知道哪些是数据,如何存储数据、组织数据和交换数据,而HTML是关于如何显示信息的语言。在XML中,标记仅用于描述数据本身。在HTML中,浏览器通过编译HTML标记来显示数据。
(2)XML是可扩展的标记语言,而在HTML中所有的标记和文档结构都是预定义的。在HTML中只允许使用当前HTML标准所支持的标记,而XML允许自定义标记和文档结构,其标记的定义是无限制的。
(3)XML文档中的元素所要表现的内容不能在网络浏览器上直接显示,HTML文档中的元素能够在浏览器中直接显示。
l XML语法要求
创建格式正确的XML文档的语法要求如下:
(1)XML文档必须有一个顶层元素,即文档元素。所有其他元素必须嵌入在文档元素中。
(2)元素嵌套要正确,即如果一个元素在另一个元素中开始,那么必须在同一元素中结束。
(3)每一个元素必须同时拥有起始标记和结束标记。与HTML不同,XML不允许忽略结束标记。
(4)起始标记中的元素类型名必须与相应结束标记中的名称完全匹配。
(5)元素类型名区分大小写。例如,分别定义起始标记<TITLE>、结束标记</Title>,起始标记的类型名与结束标记的类型名不匹配,则元素是非法的。
(6)元素类型名称中可以包含字母、数字以及其他字母元素类型,也可以使用非英文字符。名称不能数字或者符号"-"开头,名称中不能包含空格符和冒号“:”。
l DOM技术
DOM(Document Object Model,文档对象模型)技术主要是指利用DOM分析器通过对XML文档的分析,把整个XML文档以一棵DOM树的形式存放在内存中,应用程序可以随时对DOM树中的任何一个部分进行访问与操作,也就是说,通过DOM树,应用程序可以对XML文档进行随机访问。
在ASP中,通过创建Document对象可以对XML文档进行相关功能的操作。在IE 5.0中,包含了Microsoft XML类库,其中就包含了Document对象。要在ASP中使用Microsoft XML,首先必须在服务器端安装IE 5.0或XML的插件,如果使用的是Windows 2000或Windows XP就不需要安装IE 5.0或XML的插件,如果使用的是Windows 98,则需安装一个IE 5.0或IE 5.0以上版本的浏览器即可运行XML文件。
在ASP中创建Document对象的基本语法为:
newXML=Server.CreateObject("Microsoft.XMLDOM")
当对象创建完成后就可以使用其内部的函数。
ASP是通过DOM接口来访问XML文档中的任何一部分数据的。下面介绍两种访问XML文档的方法,分别为通过load方法直接加载XML文档和通过loadXML方法加载XML文档片断。
l 通过load方法直接加载XML文档
通过load方法可以将指定的文件装载到当前的Document文档对象中,如果装载成功则返回True值,否则将返回False值。
语法:
load(filename)
filename:需要加载的文件名。
l 通过loadXML方法加载XML文档片断
通过loadXML方法可以将指定的XML字符串装载到当前的Document文档对象中,如果装载成功则返回True值,否则返回False值。
语法:
loadXML(xmlString)
xmlString:需要加载的XML字符串,此字符串应是符合XML语法规则的XML片断。
Microsoft Word是Microsoft提供的优秀文档处理软件,它在处理文档、资料过程中都显现出其强大的处理功能。在ASP中可以调用Word的相关对象实现报表打印的功能。下面介绍Word的Application对象、Document对象和Range对象的常用属性和方法。
l Word的Application对象
通过Application对象,可以访问由应用程序提供的所有其他对象。下面介绍Application对象的常用属性和方法。
² ActiveDocument属性
ActiveDocument属性返回一个表示活动文档或具有焦点的文档的Document对象。
² ActivePrinter属性
通过ActivePrinter属性可以设置或返回活动打印机的名称。
² ActiveWindow属性
ActiveWindow属性返回具有焦点的窗口。
² Caption属性
通过Caption属性设置或返回指定文档或应用程序窗口的标题文本。
² DisplayAlerts属性
DisplayAlerts属性用于指定代码运行时处理警报的方式。WdAlertlevel的取值有3个,分别为WdAlertsAll(默认值,显示所有消息和警报)、wdAlertsMessageBox(只显示消息框)和wdAlertsNone(不显示任何警报或消息框)。如果在执行程序之前将DisplayAlerts属性值设置为wdAlertsNone,程序将在无任何消息和警报的情况下执行,但在完成指定代码后,要确保将DisplayAlerts设置为WdAlertsAll。如:
Application.DisplayAlerts=Word.WdAlertLevel.wdAlertsAll
² DisplayStatusBar属性
DisplayStatusBar属性用于指示是否显示状态栏,返回一个Boolean类型值,为读/写属性。
² Path属性
Path属性返回当前应用程序的路径。
² Visible属性
Visible属性用于打开或关闭Word应用程序自身的显示,为读/写属性。当设置Visible属性值为False时,将隐藏所有打开的Word窗口,但实际Word应用程序仍在运行。
² CheckSpelling方法
CheckSpelling方法用于检查字符串的拼写是否有误。如果发现错误则返回True,如果未发现错误则返回False。
² Move方法
通过设置Move方法中的Left和Top参数(二者均为Integer值)移动应用程序主窗口。
² Resize方法
通过设置Resize方法Width和Height参数(二者以磅为单位)调整应用程序主窗口的大小。
² Quit方法
调用Quit方法将退出Word应用程序。WdSaveOptions的取值有3个,分别为wdSaveChanges(自动保存更改)、wdPromptToSaveChanges(提示保存更改)和wdDoNotSaveChanges(不保存更改退出)。如:
Application.Quit(Word.WdSaveOptions.wdPromptToSaveChanges)
l Word的Document对象
Microsoft Word中的大多数编程活动都将涉及Document对象或其相关内容。在Word中处理某个特定文档时,这个文档就称为活动文档,这时可通过Application对象的ActiveDocument属性创建Document对象。所有的Document对象同时也是Application对象的Documents集合的成员,该集合由所有打开的文档组成。使用Document对象时,允许使用单个文档,而Document集合则允许使用所有打开的文档。由于通过Application对象和Document对象都可以进行文档操作,所以Application对象和Document对象共享许多成员。
文档是由字符组成,字符排列成词,词构成句子,句子排列成段落,段落依次排列而构成节。Document对象具有一些映射到这些构造的集合,如Characters集合、Words集合、Sentences集合、Paragraphs集合、Sections集合、HeadersFooters集合。
l Word的Range对象
Range对象表示文档中的一个连续区域,此区域由起始字符位置和终止字符位置定义。指定的区域可以小至插入点、大至整个文档,还可以是当前选定内容代表的区域。可以定义一个Range对象,也可以在单个文档中定义多个Rang对象。Range对象中的字符包括非打印字符,如空格、回车符和段落标记。创建Range对象后,可以对在指定范围内搜索字符、设置文本格式等。
在使用ASP开发动态网站时,通常是将从数据源读取到的数据输出到页面中,以供用户浏览。在页面中,提供打印功能,不仅使用户可以便捷地获取到数据,还有利于网站信息的宣传。本节将介绍通过JavaScript脚本和WebBrowse组件打印页面中数据报表。
JavaScript是由Netscape Communication Corporation(网景公司)所开发的,它是目前客户端浏览程序应用最普遍的脚本语言之一。在ASP中,可以使用JavaScript脚本打印数据报表。
JavaScript是一种基于对象和事件驱动并具有安全性能的解释型脚本语言,在Web系统中得到了非常广泛的应用,它不但可以用于编写客户端的脚本程序,由Web浏览器解释执行;还可以编写在服务器端执行的脚本程序,即在服务器端处理用户提交的信息并动态地向浏览器返回处理结果。
ASP通过调用JavaScript脚本中的Window对象的Print()方法,可以实现打印功能。通过JavaScript脚本打印报表的流程图,如图5.1所示。
图5.1 JavaScript脚本打印报表流程图
JavaScript脚本语言可以直接对用户的请求作出响应,无须经过Web服务程序,从而实现网页的动态化。下面分别通过打印明细报表与打印分组报表,来介绍JavaScript脚本打印报表的过程。
l JavaScript脚本打印明细报表
实例位置:光盘"mr"5"5.2"5.2.1"01
动态网站的特点就是使浏览者能够实时地查看到网站发布的信息,为浏览者提供最新、准确的信息。在网页中提供报表打印,可以使浏览者快捷地获取到所需要的信息。明细报表是指显示数据库表中一条记录的多个字段信息,或是同时显示多条明细数据。下面以商务网后台管理系统的员工业绩管理模块为例,介绍JavaScript脚本打印员工业绩报表的过程。运行效果如图5.2所示。
图5.2 JavaScript脚本打印明细报表
在员工业绩信息查看页面中,可以浏览到员工业绩的详细信息,并可以进行分页查看,单击“JavaScript脚本打印明细报表”按钮可以打印“员工业绩登记表”中的数据。代码如下:
例程5-1 代码位置:光盘"mr"5"5.2"5.2.1"01"index.asp
<%
Set rs=Server.CreateObject("ADODB.Recordset")
sqlstr="select * from tb_result"
rs.open sqlstr,conn,1,1
If rs.eof or rs.bof Then
Response.Write("<tr align=center><td colspan=8>暂时不能提供任何信息!</td></tr>")
Response.End
End if
rs.pagesize=4 '定义每页显示的记录数
pages=clng(Request("pages")) '获得当前页数
If pages<1 Then pages=1
If pages>rs.recordcount Then pages=rs.recordcount
showpage rs,pages '执行分页子程序showpage
Sub showpage(rs,pages) '分页子程序showpage(rs,pages)
rs.absolutepage=pages '指定指针所在的当前位置
For i=1 to rs.pagesize '循环显示记录集中的记录SendTime=Now()
%>
<tr align="center" valign="middle" bgcolor="#FFFFFF">
<td height="22"><%=rs("id")%></td>
<td height="22"><%=rs("Name")%></td>
<td height="22"><%=rs("Sex")%></td>
<td height="22"><%=rs("icebox")%></td>
<td height="22"><%=rs("washer")%></td>
<td height="22"><%=rs("TV")%></td>
<td height="22"><%=rs("air-condition")%></td>
<td height="22"><%=rs("cleaner")%></td>
</tr>
<%
rs.movenext
If rs.eof Then Exit For
Next
End Sub
%>
</table>
<br>
<table width="450" height="25" border="0" align="center" cellpadding="-2" cellspacing="0" class="Noprint">
<tr valign="middle" bgcolor="#FFFFFF">
<%If Not (rs.eof and rs.bof) Then%>
<td width="280" height="28"><% if pages<>1 then %>
<a href=?pages=1>第一页</a> <a href=?pages=<%=(pages-1)%>>上一页</a>
<%end if
if pages<>rs.pagecount then %>
<a href=?pages=<%=(pages+1)%>>下一页</a> <a href=?pages=<%=rs.pagecount%>>最后一页</a>
<%end if%></td>
<%If not(rs.Eof and rs.Bof) Then%>
<td width="220" height="28" align="right" class="word_grey">[<%=pages%>/<%=rs.PageCount%>] 每页<%=rs.PageSize%>条 共<%=rs.RecordCount%>条信息</td>
<%End If
rs.close
Set rs=Nothing
End If
%>
</tr>
<tr bgcolor="#000000">
<td colspan="2" valign="bottom" height="1"></td>
</tr>
</table>
<br>
调用JavaScript脚本中window对象的print()方法,实现打印功能。
<div align="center" class="Noprint">
<input type="submit" name="Submit" value="JavaScript脚本打印明细报表" onClick="window.print()">
</div>
在页面中定义了CSS样式,可以应用此样式隐藏页面中不需要打印的元素。
<style type="text/css">
<!--
@media print{
.Noprint{display:none /*应用该样式的对象在实际打印时将不可见*/
}
-->
</style>
l JavaScript脚本打印分组报表
实例位置:光盘"mr"5"5.2"5.2.1"02
数据库中的数据是按照一定规律和格式进行存储的,在展现数据时,为了使浏览者更加明确数据的结构,可以将数据进行分组显示。下面以企业内部管理系统的销售管理模块为例,介绍JavaScript脚本打印分组报表的过程。运行效果如图5.3所示。
图5.3 JavaScript脚本打印分组报表
在季度销售报表查看页面中,用户可以查看到按年份进行分组后的季度商品销售信息,单击“JavaScript脚本打印分组报表”按钮,可以打印“企业各季度销售报表”中的数据。代码如下:
例程5-2 代码位置:光盘"mr"5"5.2"5.2.1"02"index.asp
<%
Set rsm=Server.CreateObject("ADODB.Recordset")
sqlstr="select sell_year from tb_total group by sell_year"
rsm.open sqlstr,conn,1,1
If rsm.eof or rsm.bof Then
Response.Write("<tr align=center><td colspan=6>暂时不能提供任何信息!</td></tr>")
Response.End
End if
do while not rsm.eof
首先将数据库中的数据进行分组,然后创建另一个Recordset记录集对象,读取分组后各记录的详细信息。
i=0
Set rs=Server.CreateObject("ADODB.Recordset")
sql_sub="select * from tb_total where sell_year="&rsm(0)&""
rs.open sql_sub,conn,1,1
do while not rs.eof
%>
<tr align="center" valign="middle" bgcolor="#F0F0F0">
<td height="22"><%If i=0 Then%><%=rs("sell_year")%><%End If%></td>
<td height="22"><%=rs("sell_quarter")%></td>
<td height="22"><%=rs("name")%></td>
<td height="22"><%=rs("price")%></td>
<td height="22"><%=rs("money")%></td>
<td height="22"><%=rs("comment")%></td>
</tr>
<%
i=i+1
rs.movenext
loop
rsm.movenext
loop
rs.close
Set rs=Nothing
rsm.close
Set rsm=Nothing
%>
</table>
<br>
应用JavaScript脚本打印页面中的数据报表。
<div align="center" class="Noprint">
<input type="submit" name="Submit" value="JavaScript脚本打印分组报表" onClick="window.print()">
</div>
在ASP中,可以应用JavaScript脚本语言开发出更灵活、更具有动态特征的网站。JavaScript脚本语言的特点如下:
(1)JavaScript是一种脚本语言,它采用小程序段的方式实现编程,和其他脚本语言一样,JavaScript同样也是一种解释性语言,提供了一个简易的开发过程。其基本结构形式与C、C++、VB十分类似。
(2)JavaScript是一种基于对象的语言,这说明它可以应用自己已经创建的对象。因此,许多功能都是通过调用其脚本环境中对象的方法和属性来实现的。
(3)JavaScript的主要特征是实现网页的动态化,它可以直接对客户端的请求作出响应,而无须经过Web服务程序。
(4)JavaScript具有安全性。它不允许访问本地硬盘,不能将数据存入到服务器上,并且不允许对网络文档进行修改和删除,只能通过浏览器实现信息浏览或动态交互,从而有效地避免数据的丢失。
在ASP中可以使用WebBrowse组件实现打印页面内容的功能。只要保证服务器端安装了IE浏览器,用户就可以灵活运用WebBrowse组件实现打印样式报表的功能。
根据本章5.1.2节中对WebBrowser组件打印技术的介绍,读者会发现应用WebBrowser组件,可以实现与IE浏览器各菜单项命令等同的功能。在实际应用中,主要是调用WebBrowser组件的Execwb方法来实现各项命令。
ASP使用WebBrowse组件打印报表的流程图,如图5.4所示。
图5.4 WebBrowse组件打印报表流程图
在实际工作中,程序设计人员需根据用户所要求的内容,设计样式报表,从而将数据以明晰的结构展现在用户面前。下面分别通过打印汇总报表和主从报表,来介绍WebBrowse组件打印报表的过程
l WebBrowse组件打印汇总报表
实例位置:光盘"mr"5"5.2"5.2.2"01
汇总报表是一种对多条记录的一个或多个字段信息进行累加的报表样式。下面以企业生产经营管理系统的生产经营统计模块为例,介绍通过WebBrowse组件打印企业生产和经营报表的过程,运行效果如图5.5所示。
图5.5 WebBrowse组件打印汇总报表
在企业生产和经营情况查看页面中,用户可以查看到生产和经营所涉及到收入、支出及利润率、增长率等信息,还可以浏览到各部分的总计数据信息。单击页面上提供的“页面设置”超链接,可以设置纸张大小、纸张来源、纸张的打印方向、页眉和页脚、页边距等打印选项;单击“打印预览”超链接,可以查看打印效果,如图5.6所示;单击“打印”超链接,可以直接对所指定的内容进行打印操作。
图5.6 汇总报表的打印预览效果
在程序处理页面中,首先从数据库中读取数据;然后在循环显示记录的同时,对相关字段的数据进行累加操作,从而实现总计的效果;再应用WebBrowser组件实现打印操作。代码如下:
例程5-3 代码位置:光盘"mr"5"5.2"5.2.2"01"index.asp
<%
Set rs=Server.CreateObject("ADODB.Recordset")
sqlstr="select * from tb_run"
rs.open sqlstr,conn,1,1
If rs.eof or rs.bof Then
Response.Write("<tr align=center><td colspan=8>暂时不能提供任何信息!</td></tr>")
Response.End
End if
do while not rs.eof
%>
<tr align="center" valign="middle">
<td height="22" bgcolor="#FFFFFF"><%=rs("nianfen")%></td>
<td height="22" bgcolor="#FFFFFF"><%=rs("shouru")%></td>
<td height="22" bgcolor="#FFFFFF"><%=rs("chengben")%></td>
<td height="22" bgcolor="#FFFFFF"><%=rs("guanggao")%></td>
<td height="22" bgcolor="#FFFFFF"><%=rs("shuijin")%></td>
<td height="22" bgcolor="#FFFFFF"><%=rs("lirun")%></td>
<td height="22" bgcolor="#FFFFFF"><%=rs("lirunlv")%></td>
<td height="22" bgcolor="#FFFFFF"><%=rs("zengchanglv")%></td>
</tr>
在循环显示记录信息的同时,对各字段数据进行累加操作。
<%
shouru=shouru+rs("shouru")
chengben=chengben+rs("chengben")
guanggao=guanggao+rs("guanggao")
shuijin=shuijin+rs("shuijin")
lirun=lirun+rs("lirun")
lirunlv=lirunlv+rs("lirunlv")
zengchanglv=zengchanglv+rs("zengchanglv")
rs.movenext
loop
rs.close
Set rs=Nothing
%>
<tr align="center" valign="middle">
<td height="22" bgcolor="#FFFFFF">总计</td>
<td height="22" bgcolor="#FFFFFF"><%=shouru%></td>
<td height="22" bgcolor="#FFFFFF"><%=chengben%></td>
<td height="22" bgcolor="#FFFFFF"><%=guanggao%></td>
<td height="22" bgcolor="#FFFFFF"><%=shuijin%></td>
<td height="22" bgcolor="#FFFFFF"><%=lirun%></td>
<td height="22" bgcolor="#FFFFFF"><%=lirunlv%></td>
<td height="22" bgcolor="#FFFFFF"><%=zengchanglv%></td>
</tr>
</table>
<br>
使用<object>标记引用WebBrowser组件,调用其Execwb实现各种打印功能。
<object id=WebBrowser classid=ClSID:8856F961-340A-11D0-A96B-00C04Fd705A2 width="0" height="0"> </object>
<div align="center"><a href="#" onClick="document.all.WebBrowser.Execwb(8,1)" class="Noprint">页面设置</a> <a href="#" onClick="document.all.WebBrowser.Execwb(7,1)" class="Noprint">打印预览</a> <a href="#" onClick="document.all.WebBrowser.Execwb(6,1)" class="Noprint">打印</a></div>
l WebBrowse组件打印主从报表
实例位置:光盘"mr"5"5.2"5.2.2"02
主从报表中所涉及到的数据集来自两个或两个以上具有主从关系的结果集。下面以学生信息管理系统的档案管理模块为例,介绍如何使用WebBrowse组件打印由主表(学生基本信息表)和从表(学生详细信息表)构成的主从报表,运行效果如图5.7所示。
图5.7 WebBrowse组件打印主从报表
在档案信息查看页面中,用户可以浏览到学生基本信息,如图5.8所示;当单击学生姓名时,此学生的详细信息将显示到该记录的下方,如图5.7所示。
图5.8 浏览学生基本信息
页面中提供了“页面设置”、“打印预览”和“打印”3个超链接,单击“打印预览”可以查看到页面的最终效果,如图5.9所示。
图5.9 打印主从报表的预览效果
在程序处理页面中,首先从数据表tb_student中读取学生的基本信息并将其显示在表格中,然后根据读取的学生基本信息,查询数据表tb_resume并读取其中对应的学生详细信息记录;再编写JavaScript脚本函数,确定是否将此学生的详细背景信息显示在表格中。代码如下:
例程5-4 代码位置:光盘"mr"5"5.2"5.2.2"02"resume.asp
<script language="javascript">
function ShowTR(objTr){
if(objTr.style.display == ""){
objTr.style.display = "none";
}else{
objTr.style.display = "";
}
}
</script>
以上自定义的JavaScript脚本函数的功能是隐藏或显示指定的元素。
<%
Set rs=Server.CreateObject("ADODB.Recordset")
sqlstr="select * from tb_resume"
rs.open sqlstr,conn,1,1
If rs.eof or rs.bof Then
Response.Write("<tr align=center><td colspan=5>暂时不能提供任何信息!</td></tr>")
Response.End
End if
m=0
do while not rs.eof
%>
<tr align="center" valign="middle">
<td height="22" bgcolor="#FFFFFF"><a href="Javascript:ShowTR(OpenRep<%=m%>)"><%=rs("s_name")%></a></td>
<td height="22" bgcolor="#FFFFFF"><%=rs("Grand")%></td>
<td height="22" bgcolor="#FFFFFF"><%=rs("Teacher")%></td>
<td height="22" bgcolor="#FFFFFF"><%=rs("level")%></td>
<td height="22" bgcolor="#FFFFFF"><%=rs("flag")%></td>
</tr>
<%
Set rsc=Server.CreateObject("ADODB.Recordset")
sql_sub="select * from tb_student where id="&rs("s_id")&""
rsc.open sql_sub,conn,1,1
%>
以下显示学生详细信息的<tr>标记,在默认情况下是隐藏的。
<tr align="center" valign="middle" id="OpenRep<%=m%>" style="display:none">
<td height="22" colspan="5" bgcolor="#FFFFFF"><table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td width="30%" height="22" align="left" valign="middle">性别:<%=rsc("Sex")%></td>
<td width="32%" align="left" valign="middle">年龄:<%=rsc("Age")%></td>
<td width="38%" align="left" valign="middle">入学日期:<%=rsc("ruxue_date")%></td>
</tr>
<tr>
<td height="22" colspan="3" align="left" valign="middle">家庭住址:<%=rsc("Address")%></td>
</tr>
<tr>
<td height="22" align="left" valign="middle">家长姓名:<%=rsc("parent")%></td>
<td align="left" valign="middle">联系电话:<%=rsc("tel")%></td>
<td align="left" valign="middle"> </td>
</tr>
</table></td>
</tr>
<%
m=m+1
rs.movenext
loop
rs.close
Set rs=Nothing
%>
在档案信息查看页面中,使用<iframe></iframe>标记,将名为resume.asp的文件嵌入到index.asp文件中,然后使用WebBrowser组件实现打印的功能。代码如下:
例程5-5 代码位置:光盘"mr"5"5.2"5.2.2"02"index.asp
<p align="left" style="text-indent:40px " class="Noprint">注意:单击学生姓名,可以看到此学生的详细信息!</p>
<iframe align="center" src="resume.asp" width="550" height="400" name="mainFrame" scrolling="no" frameborder="no" marginwidth="20px"></iframe>
<object id=WebBrowser classid=ClSID:8856F961-340A-11D0-A96B-00C04Fd705A2 width="0" height="0"> </object>
<div align="center"><a href="#" onClick="document.all.WebBrowser.Execwb(8,1)" class="Noprint">页面设置</a> <a href="#" onClick="document.all.WebBrowser.Execwb(7,1)" class="Noprint">打印预览</a> <a href="#" onClick="document.all.WebBrowser.Execwb(6,1)" class="Noprint">打印</a></div>
在系统默认情况下,无论是利用IE自身的打印功能,还是使用WebBrowser组件进行打印,在打印文档顶部和底部都会包括页眉和页脚,而有时并不需要打印默认的页眉和页脚。通过调用WshShell对象的相关方法可以实现清空或者恢复页眉页脚。
在如图5.10所示的页面中,单击“清空页眉页脚”超链接,即可清空IE默认的页眉页脚,这时单击“打印预览”超链接,在“打印预览”对话框中将不显示IE默认的页眉页脚,如图5.11所示,单击“恢复页眉页脚”超链接即可恢复页眉页脚的显示,如图5.12所示。
图5.10 设置页眉页脚
图5.11 打印预览对话框不显示页眉页脚
图5.12 打印预览对话框显示页眉页脚
在JavaScript脚本中创建WScript.Shell对象,并应用RegWrite方法可以实现清空或者恢复页眉页脚的功能。Shell对象是WSH(WSH是Windows Scripting Host的缩写,内嵌于Windows操作系统中的脚本语言工作环境)的内建对象,主要负责程序的本地运行、处理注册表、创建快捷方式、获取系统文件夹信息及处理环境变量等工作。代码如下:
<script language="JavaScript">
var HKEY_RootPath="HKEY_CURRENT_USER""Software""Microsoft""Internet Explorer""PageSetup""";
function PageSetup_del(){ //清空页眉页脚
try{
var WSc=new ActiveXObject("WScript.Shell");
HKEY_Key="header";
WSc.RegWrite(HKEY_RootPath+HKEY_Key,"");
HKEY_Key="footer";
WSc.RegWrite(HKEY_RootPath+HKEY_Key,"");
}catch(e){}
}
function PageSetup_set(){ //恢复页眉页脚
try{
var WSc=new ActiveXObject("WScript.Shell");
HKEY_Key="header";
WSc.RegWrite(HKEY_RootPath+HKEY_Key,"&w&b页码,&p/&P");
HKEY_Key="footer";
WSc.RegWrite(HKEY_RootPath+HKEY_Key,"&u&b&d");
}catch(e){}
}
</script>
在页面中建立超链接,调用自定义的JavaScript脚本函数;使用<object>标记嵌入WebBrowser组件,并调用Execwb方法实现“打印预览”和“打印”的功能。代码如下:
<a href="#" onClick="PageSetup_del()" class="print">清空页眉页脚</a>
<a href="#" onClick="PageSetup_set()" class="print"> 恢复页眉页脚 </a>
<object id="WebBrowser" classid="ClSID:8856F961-340A-11D0-A96B-00C04Fd705A2" width="0" height="0"></object>
<a href="#" onClick="document.all.WebBrowser.Execwb(7,1)" class="print">打印预览</a>
<a href="#" onClick="document.all.WebBrowser.Execwb(6,1)" class="print">打印</a>
报表打印在实际的开发项目中占有重要位置,而Excel凭借它功能强大、应用灵活、通用性强等优势在报表打印中获得了广泛的应用。ASP通过调用Excel的相关对象可以将网页中的内容或数据库的数据导入到Excel中,也可以通过相关技术访问Excel中的数据,从而使数据以指定的格式显示出来,并实现报表打印的功能。
在ASP应用程序中,可以读取Excel文件中的数据并将其显示到页面中,进而应用相关的打印技术实现打印Excel报表的功能。
在实际工作中,通常使用Microsoft Excel存储一些关键的报表数据。为了方便用户操作,在ASP中可以读取Excel文件中的数据,并将其显示在网页中,使操作人员易于查看数据并进行打印操作。
ASP读取Excel文件中数据的方法有3种:一是创建Excel的Application对象实例,调用Workbooks集合的Open方法打开指定的Excel文件,并确定当前活动的工作表,然后将Excel文件单元格中的数据按照一定的布局添加到表格中;一是使用ADO访问Excel文件,将获取到的Excel文件数据存储到创建的记录集中,然后再将其显示到页面表格中;一是使用OLE DB访问Excel文件,通过创建记录集,并读取记录集中的数据将Excel文件中的内容显示到表格中。获取到Excel文件中的数据后,再应用打印技术打印网页中的报表内容。
ASP打印Excel报表的流程图,如图5.13所示。
图5.13 打印Excel报表流程图
Excel报表在实际工作中的应用非常广泛,例如公司在月末总结时需要使用财务报表、工资报表、业绩报表等。为了使用户在网站管理系统中,能够直接查看到Excel报表中的内容,ASP提供了访问Excel文件中数据的技术。下面以销售管理系统中的统计查询模块为例,介绍ASP访问Excel文件并将读取到的数据显示到页面中的3种不同方法。运行效果如图5.14所示。
图5.14 打印Excel报表
下面介绍ASP访问Excel文件的3种方法。
l 方法一 直接访问Excel中的数据
实例位置:光盘"mr"5"5.3"5.3.1"01
直接访问Excel中的数据是指应用Excel的相关对象打开并读取指定Excel文件中的数据。
在本例程中,销售管理系统的首页是一个上下型的框架,代码如下:
例程5-6 代码位置:光盘"mr"5"5.3"5.3.1"01"index.asp
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>直接访问Excel中的数据</title>
</head>
<frameset rows="324,*" frameborder="NO" border="0" framespacing="0">
<frame src="top.asp" name="topFrame" scrolling="NO" noresize>
<frame src="main.asp" name="mainFrame">
</frameset>
<noframes><body>
</body></noframes>
</html>
在上方框架中,放置一个“打印”按钮,此按钮的功能是打印下方框架中的内容;在下方框架的员工业绩信息查看页面中,用户可以填写数据显示的列数,并选择Excel文件所在的路径。运行效果如图5.15所示。
图5.15 直接访问Excel中的数据
为了便于读者理解,下面以列表的形式给出员工业绩信息查看页面main.asp中所涉及到的表单及表单元素,如表5.7所示。
表5.7 员工业绩信息查看页面main.asp中的表单及表单元素
名称 |
元素类型 |
重要属性 |
含义 |
form1 |
form |
method="post" action=" " |
确定访问Excel文件的参数 |
cln |
input |
type="text" value="8" |
数据显示的列数 |
asf |
input |
type="file" size="20" |
Excel文件路径 |
show |
input |
type="button" value="查看" onClick="ExcelShow()" |
查看按钮 |
在员工业绩信息查看页面中,单击“查看”按钮,将调用自定义的VBScript函数,此函数的功能是将Excel文件中各单元格中的内容输出到页面表格中。运行效果如图5.16所示。
图5.16 读取并显示Excel中的数据
在自定义的VBScript函数中,首先创建Excel的Application对象实例,并调用Workbooks集合的Open方法打开指定路径的Excel文件,然后确定当前活动的工作表,再使用Worksheet对象的cells属性读取Excel单元格中的内容,并调用document对象的Write方法将数据显示到表格中。代码如下:
例程5-7 代码位置:光盘"mr"5"5.3"5.3.1"01"main.asp
<script language="vbscript">
sub ExcelShow()
set xlap=CreateObject("Excel.Application")
strsource=document.all.form1.asf.value
cln=document.all.form1.cln.value
set xlbook=xlap.Workbooks.open(strsource)
set xlsheet=xlbook.worksheets(1)
调用document对象的write方法显示表格内容。
document.write("<body style='background-image: url(images/bg.gif);'>")
document.write("<table width='778' border='0' align='center' cellpadding='0' cellspacing='0'>")
document.write("<tr><td height='31' background='images/images_04.jpg'> == <font style='font-size:12px'>员工业绩</font> ==</td> </tr>")
document.write("<tr align='center'><td height='200' background='images/images_05.jpg'>")
i=2
ii=0
document.write("<table width='500' border='1' align='center' cellspacing='0' style='font-size:12px'>")
显示报表的标题信息。
document.write("<caption>"&xlsheet.cells(1,1)&"</caption>")
根据获取到的“数据显示的列数”文本框的值,使用while及for…to循环语句,依次读取Excel文件中的数据,并将其显示在表格中。
while xlsheet.cells(i,1)<>""
ii=ii+1
document.write("<tr>")
for j=1 to cln
document.Write("<td width='60' align='center' style='font-size:12px'>"&xlsheet.cells(i,j)&"</td>")
next
document.Write("</tr>")
i=i+1
wend
document.Write("</table>")
document.Write("</tr></td>")
document.Write("<tr><td><img src='images/images_07.gif' width='778' height='144'></td></tr>")
document.Write("</table>")
document.Write("</body>")
释放资源。
set xlsheet=nothing
set xlbook=nothing
xlap.quit
end sub
</script>
将Excel文件中的数据读取到页面中后,在首页面的上方框架中单击“打印”按钮,即可打印下方框架中显示的报表数据。代码如下:
将Excel文件中的数据读取到页面中后,在首页面的上方框架中单击“打印”按钮,即可打印下方框架中显示的报表数据。代码如下:
例程5-8 代码位置:光盘"mr"5"5.3"5.3.1"01"top.asp
<object id=WebBrowser classid=ClSID:8856F961-340A-11D0-A96B-00C04Fd705A2 width="0" height="0"></object>
<input type="button" name="Submit" value="打印" onClick="javascript:parent.mainFrame.focus();parent.mainFrame.document.all.WebBrowser.ExecWB(6,1);">
l 方法二 使用ADO访问Excel文件
实例位置:光盘"mr"5"5.3"5.3.1"02
在开发ASP应用程序时,通过指定的数据源,可以使用ADO连接Excel文件,并读取Excel文件中的数据信息。
注意:在运行本例程之前,建立的Excel文件的第一行各数据项的名称不能为中文,即应根据创建数据库时规定的命名要求来确定各数据项的名称。
在员工业绩信息查看页面中,单击“打印预览”超链接,可以预览将要打印的报表内容;单击“打印”超链接即可打印页面中的报表内容。打印预览的运行效果如图5.17所示。
图5.17 分页打印预览报表
在程序处理页面中,首先创建Connection对象实例,确定连接Excel文件的语句,并建立此连接;然后创建一个Recordset对象实例,通过此对象来读取Excel文件中的数据。在此过程中,通过CSS样式可以定义在实际打印时元素不可见的样式以及分页打印页面内容的样式。
例程5-9 代码位置:光盘"mr"5"5.3"5.3.1"02"index.asp
<style>
@media print{
.print{display:none /*应用该样式的对象在实际打印时将不可见*/
}
</style>
建立表格显示数据。
<table width="500" border="1" align="center" cellpadding="1" cellspacing="1" bordercolor="#7D7350" bgcolor="#FFFFFF">
<caption align="center" style="font-size:12px">员工业绩记录表</caption>
<thead style="display:table-header-group;">
<tr align="center" bgcolor="#BBAC85">
<td width="47" height="26" bgcolor="#BBAC85" class="style2">姓名</td>
<td width="40" class="style2">性别</td>
…略,显示各数据项名称
</tr>
</thead>
<%
Set Conn = Server.CreateObject("ADODB.Connection")
connstr = "Driver={Microsoft Excel Driver (*.xls)};DBQ="&Server.MapPath("employee.xls")
Conn.Open connstr
Sql="Select * From [Sheet1$]" '注意表名的书写方式为 "[表名$]"
Set Rs=Conn.Execute(Sql)
IF Rs.Eof And Rs.Bof Then
Response.write "暂无数据!"
Else
i=0
Do While Not Rs.EOF
i=i+1
%>
根据实际情况,在显示一定数据的记录时,应用CSS样式进行分页打印报表的操作。
<tr <%If i mod 3=0 Then Response.Write("style=page-break-after:always") End If%>>
<td height="31"><span class="style2"> <%=rs("Ename")%></span></td>
<td><span class="style2"> <%=rs("Esex")%></span></td>
<td><span class="style2"> <%=rs("Edepartment")%></span></td>
<td><span class="style2"> <%=rs("Esellnum")%></span></td>
<td><span class="style2"> <%=rs("Esoldnum")%></span></td>
<td><span class="style2"> <%=rs("Etotal")%></span></td>
<td><span class="style2"> <%=rs("Escore")%></span></td>
<td><span class="style2"> <%=rs("Eflag")%></span></td>
</tr>
<%
Rs.MoveNext
Loop
End IF
Rs.Close
Set Rs=nothing
Conn.Close
Set Conn=Nothing
%>
<tfoot style="display:table-footer-group; border:none;">
<tr align="center" bgcolor="#FFFFFF">
<td colspan="8"> </td>
</tr>
</tfoot>
</table>
<br>
使用<object>标记引用WebBrowse组件,调用WebBrowser组件的Execwb方法,并设置相应参数,实现“打印预览”和“打印”报表的功能。
<object id=WebBrowser classid=ClSID:8856F961-340A-11D0-A96B-00C04Fd705A2 width="0" height="0"></object>
<div align="center"><a href="#" onClick="document.all.WebBrowser.Execwb(7,1)" class="print">打印预览</a> <a href="#" onClick="document.all.WebBrowser.Execwb(6,1)" class="print">打印</a></div><br></td>
</tr>
</table>
l 方法三 使用OLE DB访问Excel文件
实例位置:光盘"mr"5"5.3"5.3.1"03
在ASP中,不仅可以使用ADO访问Excel文件,还可以使用OLE DB访问Excel文件,从而将Excel文件中的数据显示到页面中。
在员工业绩信息查看页面中,为用户提供了“打印预览”和“打印”两个超链接,单击“打印预览”可以预览将要打印的报表内容,单击“打印”即可打印页面中的报表内容。打印预览的运行效果如图5.18所示。
图5.18 打印预览报表
在程序处理页面中,首先创建Connection对象实例,使用OLE DB的方法连接Excel文件,然后查询Excel文件中当前工作表中的数据信息,并将其显示在页面中。代码如下:
例程5-10 代码位置:光盘"mr"5"5.3"5.3.1"03"index.asp
<%
set conn=Server.CreateObject("ADODB.Connection")
conn.open "Provider=Microsoft.Jet.OLEDB.4.0; Extended Properties=""Excel 8.0;HDR=Yes;"";Data Source="&server.MapPath("employee.xls")&";"
Sql="Select * From [Sheet1$]" '注意表名的书写方式为 "[表名$]
Set Rs=Conn.Execute(Sql)
IF Rs.Eof And Rs.Bof Then
Response.write "暂无数据!"
Else
Do While Not Rs.EOF
%>
<tr>
<td height="31"><%=rs("Ename")%></td>
<td><%=rs("Esex")%></td>
<td><%=rs("Edepartment")%></td>
<td><%=rs("Esellnum")%></td>
<td><%=rs("Esoldnum")%></td>
<td><%=rs("Etotal")%></td>
<td><%=rs("Escore")%></td>
<td><%=rs("Eflag")%></td>
</tr>
<%
Rs.MoveNext
Loop
End IF
Rs.Close
Set Rs=nothing
Conn.Close
Set Conn=Nothing
%>
注意:指定的Excel文件的第一行各数据项的名称不能为中文。
在开发报表打印模块时,用户可以定义CSS样式来指定不需要打印的内容(如:表格等元素)。但是,当用户在预览页面打印效果时,会发现网页背景颜色及图像也在打印的范围之内,这并不是想要看到的效果。这时可以通过设置IE浏览器的Internet选项,来指定打印时是否显示网页背景颜色和图像。具体步骤如下:
(1)在浏览网页时,单击IE浏览器上方的“工具”菜单项,选择“Internet选项”命令。
(2)在打开的“Internet选项”窗口中,选择“高级”选项卡,查看“打印背景颜色和图像”复选框是否处于选中状态。如果处于选中状态,则说明在打印时将打印网页的背景颜色及图像;如果处于未选中状态,则说明在打印时将忽略网页的背景颜色及图像。用户可以根据实际情况,设置该选项。如图5.19所示。
图5.19 Internet选项窗口
普通报表,也称为明细报表,是指将存储的数据以原本存储的格式显示出来,以使用户明确详细的数据内容。例如,企业员工的每月考勤记录信息、企业员工档案信息、学生考试成绩信息等。下面介绍通过Excel打印普通报表的方案。
在互联网普及的今天,网络已成为信息传播的是一个重要途径。企业或个人都将一些内部信息发布到网上,以供浏览者查看和参考。为了给浏览者提供方便或是为了便于网站管理员对网站数据的统计和管理,网站可以为用户提供报表打印服务,这样用户就可以快捷地打印自己所需要的数据报表信息。
ASP通过设置Response对象的ContentType属性,可以将网页中的数据内容以Excel文件的形式呈现出来,用户可以在该文件中编辑数据项,然后使用Excel自带打印功能将报表打印出来。
ASP还可以将数据库中的数据信息直接导入到Excel文件中。导入的方式有两种:一种是使用Insert Into语句将数据库中的数据导入到指定的Excel文件中;另一种是建立Excel模板,然后通过调用Excel相关对象将数据库数据导入到Excel文件中(这时将自动产生Excel文件)。用户在打开的Excel文件中,可以对数据进行编辑,并进行打印操作。
Excel普通报表打印的流程图,如图5.20所示。
图5.20 Excel普通报表打印流程图
在ASP应用程序中,应用相关技术可以将网页中或数据库中的数据导入到Excel中,在Excel文件中可以对数据进行实时编辑,打印出符合用户需求的详细报表信息。下面以企业进销存管理系统为例,介绍对企业商品信息的报表打印模块,运行效果如图5.21所示。
图5.21 Excel普通报表打印
下面介绍3种将数据导入到Excel中的方法。
l 方法一 将网页内容直接保存到Excel
实例位置:光盘"mr"5"5.3"5.3.2"01
在企业商品信息查看页面中,可以浏览库存商品的详细信息,单击“导入到Excel进行报表打印”按钮,即可将网页中的报表内容(这里为“企业商品信息列表”)直接以Excel文件的形式呈现出来,打开的页面具有IE浏览器和Excel文件的双重功能,用户可以在打开的页面中对数据项进行编辑,使其符合一定的规格,进而执行报表打印的操作。运行效果如图5.22所示。
图5.22 将网页内容导入到Excel中
在程序处理页面中,通过设置Response对象的ContentType属性(此属性用于指定服务器响应的HTTP内容类型)为“application/vnd.ms-excel”,即可将网页中的内容导入到Excel中。代码如下:
例程5-11 代码位置:光盘"mr"5"5.3"5.3.2"01"print.asp
<%response.ContentType="application/vnd.ms-excel"%>
<table width="500" border="1" align="center" cellpadding="1" cellspacing="0" bordercolorlight="#84FFA3" bordercolordark="#000000" bgcolor="#FF9900">
<caption align="center">
企业商品信息列表
</caption>
<tr align="center">
<td height="22">商品名称</td>
<td height="22">供应商</td>
<td height="22">产地</td>
<td height="22">进价</td>
<td height="22">库存</td>
</tr>
<%
Set rs=Server.CreateObject("ADODB.Recordset")
sqlstr="select * from tb_goods"
rs.open sqlstr,conn,1,1
while not rs.eof
%>
<tr align="center" bgcolor="#FFFFFF">
<td height="22"><%=rs("Gname")%></td>
<td height="22"><%=rs("Gsupply")%></td>
<td height="22"><%=rs("Garea")%></td>
<td height="22"><%=rs("Ginprice")%></td>
<td height="22"><%=rs("Gstock")%></td>
</tr>
<%
rs.movenext
wend
rs.close
Set rs=Nothing
%>
</table>
注意:在浏览print.asp文件的同时,不允许在编辑器内对此文件进行编辑。
l 方法二 将数据库数据直接导入到Excel
实例位置:光盘"mr"5"5.3"5.3.2"02
在实际应用中,为了准确的得到数据库中的数据信息,方便用户查看和核实数据,可以编写程序将数据库中的信息直接导入到Excel文件中,从而可以快捷地进行报表打印操作。在企业商品信息查看页面中,单击“导入到Excel进行报表打印”按钮,即可将数据库中的数据(这里以SQL Server数据库为例)直接导入到指定的Excel文件中,用户在该文件中可以针对各数据项执行进一步的操作。运行效果如图5.23所示。
图5.23 将数据库数据直接导入到Excel
在执行程序前,应建立指定的Excel文件时,需要注意的是Excel文件第一行的内容应与数据表中的字段信息相匹配。
在程序处理页面中,首先获取指定的Excel文件的物理路径;然后同时使用Insert Into语句与openrowset语句,确定与数据源的连接信息和导入的信息内容;最后调用Connection对象的Execute方法执行定义的语句,如果执行正确则直接打开Excel文件,如果执行出现异常则给出提示信息。代码如下:
例程5-12 代码位置:光盘"mr"5"5.3"5.3.2"02"index.asp
<%
If Not Isempty(Request("sure")) Then
on error resume next
DBpath=Server.MapPath("info.xls")
sqlstr="insert into openrowset('microsoft.jet.oledb.4.0','Excel 5.0;HDR=no;database="&DBpath&"',Sheet1$) select id,Gname,Gsupply,Garea,Ginprice,Gstock from tb_goods" '注意此语句中HDR参数的取值
conn.Execute(sqlstr)
If err<>0 Then
err.clear
Response.Write("<script language='javascript'>alert('操作不正确,请重试!');window.location.href='index.asp';</script>")
Response.End()
Else
Response.Write("<script language='javascript'>alert('已将SQL Server数据库中的数据成功导出到Excel文件中,请查看info.xls文件!');window.open('info.xls','_blank','');</script>")
End If
End IF
%>
注意:在执行程序时,不允许再次打开指定的Excel文件,否则将出现错误提示。
l 方法三 建立Excel模板,将数据库数据导入到Excel
实例位置:光盘"mr"5"5.3"5.3.2"03
在以上介绍的“方法二 将数据库数据直接导入到Excel”中,在执行程序之前,需要建立指定的Excel文件,然后将数据库中的数据导入到Excel文件中。每次执行程序之前,为了得到清晰的数据,都要清空Excel文件中的内容,然后再执行操作,这样并不方便用户操作。基于这种情况的考虑,可以建立一个Excel模板(以.xlt为后缀的文件),这样每次执行程序的时候都会自动创建一个新的Excel文件供用户使用。
在企业商品信息查看页面中,单击“导入到Excel进行报表打印”按钮,调用自定义的VBScript函数,即可将数据库中的内容导入到以建立的Excel模板为基础的Excel文件中,用户在此文件中可以根据实际情况对数据再作修整等。运行效果如图5.24所示。
图5.24 建立Excel模板将数据库数据导入到Excel
在程序处理页面中,自定义一个VBScript函数,在该函数中首先创建一个EXCEL的APPLICATION对象实例,然后调用Workbooks集合的Open方法打开指定的.xlt文件,再创建一个Worksheet对象实例,将数据表中字段的对应数据写入到工作表中的指定单元格中。代码如下:
例程5-13 代码位置:光盘"mr"5"5.3"5.3.2"03"index.asp
<script language="VBScript">
function xlprint()
Set xlApp = CreateObject("EXCEL.APPLICATION")
//打开工作表
Set xlBook = xlApp.Workbooks.Open("D:"工作文件"书稿"ASP技术方案宝典"mr"5"5.2"5.2.1"03"mode"info.xlt") //修改文件的实际存放路径
set xlsheet1 = xlBook.ActiveSheet
<%
set rs=server.createobject("adodb.recordset")
str="select * from tb_goods"
rs.open str,conn
ii=1
do while not rs.eof and ii<11
%>
<%response.write"xlSheet1.cells("&ii+1&",1).value="%>"<%=rs("id")%>"
<%response.write"xlSheet1.cells("&ii+1&",2).value="%>"<%=rs("Gname")%>"
<%response.write"xlSheet1.cells("&ii+1&",3).value="%>"<%=rs("Gsupply")%>"
<%response.write"xlSheet1.cells("&ii+1&",4).value="%>"<%=rs("Garea")%>"
<%response.write"xlSheet1.cells("&ii+1&",5).value="%>"<%=rs("Ginprice")%>"
<%response.write"xlSheet1.cells("&ii+1&",6).value="%>"<%=rs("Gstock")%>"
<%
rs.movenext
ii=ii+1
loop
rs.close
set rs=nothing
%>
xlSheet1.Application.Visible = True
end function
</script>
在一些情况下,用户会选择使用Excel文件存放数据,当要求将数据录入到SQL Server数据库时,可以编写程序批量地将Excel文件中的数据导入到SQL Server数据库中。具体的实现步骤如下:
(1)在ASP页面中,分别建立与SQL Server数据库和Excel文件的连接。
(2)创建记录集读取Excel文件中的数据,并使用循环语句将数据逐条地插入到数据库中。代码如下:
<%
If Not Isempty(Request("sure")) Then
Dim SqlConn,Connstr,XslConn,Connstr2,sqlstr,rsxsl,rssql,maxid
'与SQL Server数据库的连接
Set SqlConn=Server.CreateObject("ADODB.Connection")
Set cmd=Server.CreateObject("ADODB.Command")
Connstr="provider=sqloledb;data source=(local);initial catalog=db_sql;user id=sa;password=;"
SqlConn.open Connstr
cmd.ActiveConnection=Connstr
'与Excel文件的连接
Set XslConn=Server.CreateObject("ADODB.Connection")
Connstr2="Driver={Microsoft Excel Driver (*.xls)};DBQ="&+++("info.xls")&""
XslConn.Open Connstr2
'访问Excel文件,使用循环语句将其中数据插入到sql server对应的数据表中
Set rsxsl=Server.CreateObject("ADODB.Recordset")
Set rssql=Server.CreateObject("ADODB.Recordset")
sqlstr="select * from [sheet1$]"
rsxsl.open sqlstr,XslConn,1,1
Do While not rsxsl.eof
sqlstr="select Max(id) as maxid from tb_user"
rssql.open sqlstr,SqlConn,1,3
If Not (rssql.eof and rssql.bof) Then
If Not IsNull(rssql("maxid")) Then
maxid=Clng(rssql("maxid")+1)
Else
maxid=1
End If
Else
maxid=1
End If
rssql.close
sqlstr="insert into tb_user values("&maxid&",'"&rsxsl(1)&"','"&rsxsl(2)&"','"&rsxsl(3)&"')"
cmd.CommandText=sqlstr
cmd.Execute()
rsxsl.movenext
loop
'释放资源
Set rssql=Nothing
rsxsl.close
Set rsxsl=Nothing
Set XslConn=Nothing
Set cmd=Nothing
Set SqlConn=Nothing
Response.Write("<script language='javascript'>alert('已经将数据从Excel导入到SQL Server中!');window.location.href='index.asp';</script>")
End If
%>
在实际应用中,除了使用明细报表以外,还经常使用到一些复杂格式的报表,如:分组报表、分栏报表、交叉报表等。在ASP应用程序中,使用Excel的相关对象,可以对设计完成的复杂报表进行打印操作。
在实际应用中,根据情况需要对数据库中的数据进行分组统计,以便用户查看数据结构,明确整个过程的运行情况等。分组统计是指根据某一数据项进行数据的分组汇总。用户可以将分组统计后的报表数据进行打印。
ASP应用Excel的Application、Workbook、Worksheet等对象的相关属性和方法,可以将网页表格中的数据按照顺序写入到Excel工作表中。Excel复杂报表打印的流程图,如图5.25所示。
图5.25 Excel复杂报表打印流程图
实例位置:光盘"mr"5"5.3"5.3.3
分组报表在数据统计方面的应用很广,通过对数据进行分组统计,可以使数据内在的结构呈现在用户面前。下面以企业生产管理系统为例,介绍在对产品信息进行分组查看的同时,将此报表信息导入到Excel文件,从而实现报表打印的功能。运行效果如图5.26所示。
图5.26 Excel复杂报表打印
在产品信息查看页面中,通过列表框选择分组统计的条件,然后单击“分组统计”按钮,在下方就可以查看到按照分组条件而查询、统计出的数据信息。显示查询数据信息的代码如下:
例程5-14 代码位置:光盘"mr"5"5.3"5.3.3"index.asp
<table width="564" border="0" align="center" cellpadding="1" cellspacing="1" bgcolor="#347095" id="product">
<tr bgcolor="#E5EAED">
<th width="73" height="22" align="center" valign="middle">产品名称</th>
<th width="75" height="22" align="center" valign="middle">生产车间</th>
…略,显示表头信息
</tr>
根据用户选择的分组查询条件,确定Group By语句后面的字段名称。
<%
sel_type=Trim(Request.Form("sel_type"))
Set rsc=Server.CreateObject("ADODB.Recordset")
sql_main="select prdc_name from tb_product group by prdc_name"
If sel_type<>"" Then
Set rse=Server.CreateObject("ADODB.Recordset")
select case sel_type
case 1
sql_main="select prdc_name from tb_product group by prdc_name"
case 2
sql_main="select prdc_department from tb_product group by prdc_department"
case 3
sql_main="select prdc_date from tb_product group by prdc_date"
end select
End If
查询产品信息表中的所有字段信息,并根据获取到的查询条件,使用select case语句确定where语句中的字段名称。
rsc.open sql_main,conn,1,1
num_sum=0
total_sum=0
do while not rsc.eof
Set rs=Server.CreateObject("ADODB.Recordset")
sqlstr="select * from tb_product where 1=1"
select case sel_type
case "1"
sqlstr=sqlstr&" and prdc_name='"&rsc(0)&"'"
case "2"
sqlstr=sqlstr&" and prdc_department='"&rsc(0)&"'"
case "3"
sqlstr=sqlstr&" and prdc_date='"&rsc(0)&"'"
case else
sqlstr=sqlstr&" and prdc_name='"&rsc(0)&"'"
end select
%>
<tr>
<td height="22" colspan="7" align="left" valign="middle" bgcolor="#FFFFFF"> <table width="100%" align="center" cellpadding="0" cellspacing="1" bgcolor="#327095" id="sub_product">
<tr>
<td height="22" colspan="7" align="left" valign="middle" bgcolor="#FFFFFF"><%=rsc(0)%></td>
</tr>
<%
rs.open sqlstr,conn,1,1
prdc_num_sum=0
prdc_total_sum=0
do while not rs.eof
%>
将数据库中的数据输出到表格中,并同时统计分组产品的总生产量和总成本,以及所有产品的总生产量和总成本。
<tr>
<td><%=rs("prdc_name")%></td>
<td><%=rs("prdc_department")%></td>
<td><%=rs("prdc_type")%></td>
<td><%=rs("prdc_date")%></td>
<td><%=rs("prdc_avg")%></td>
<td><%=rs("prdc_num")%></td>
<td><%=rs("prdc_total")%></td>
</tr>
<%
prdc_num_sum=prdc_num_sum+rs("prdc_num")
prdc_total_sum=prdc_total_sum+rs("prdc_total")
rs.movenext
loop
%>
<tr>
<td height="22" align="center" valign="middle" bgcolor="#FFFFFF"> </td>
<td height="22" align="center" valign="middle" bgcolor="#FFFFFF"> </td>
<td height="22" colspan="3" align="center" valign="middle"><%=rsc(0)%> 汇总</td>
<td height="22" align="center" valign="middle"><%=prdc_num_sum%></td>
<td height="22" align="center" valign="middle"><%=prdc_total_sum%></td></tr>
</table></td>
</tr>
<%
num_sum=num_sum+prdc_num_sum
total_sum=total_sum+prdc_total_sum
rsc.movenext
loop
rs.close
Set rs=Nothing
rsc.close
Set rsc=Nothing
%>
<tr>
<td height="22" align="center" valign="middle" bgcolor="#FFFFFF"> </td>
<td height="22" align="center" valign="middle" bgcolor="#FFFFFF"> </td>
<td height="22" colspan="3" align="center" valign="middle">总计</td>
<td height="22" align="center" valign="middle" bgcolor="#FFFFFF"><%=num_sum%></td>
<td height="22" align="center" valign="middle" bgcolor="#FFFFFF"><%=total_sum%></td>
</tr></table>
在产品信息查看页面中,确定显示的数据信息后,单击“Excel报表打印”按钮,即可将产品的分组统计数据信息按照一定的布局写入到Excel文件,以方便用户进行打印操作。运行效果如图5.27所示。
图5.27 将表格数据导入到Excel文件中
在程序处理页面中,首先创建Excel的Application对象实例,调用Workbooks集合的add方法添加一个新的工作薄,再打开一个当前活动的工作表;然后将页面表格中显示数据项名称的第一行写入到Excel工作表的第一行中;再次使用for循环语句按照一定规则将分组后的数据块依次写入到Excel工作表中;最后,将显示总计信息的最末行写入到Excel工作表中,并调用Worksheet对象的Printout方法自动打印Excel文件中的报表信息。代码如下:
例程5-15 代码位置:光盘"mr"5"5.3"5.3.3"index.asp
<script language="javascript">
function outExcel(){
var table=document.all.product;
row=table.rows.length;
column=table.rows(0).cells.length;
var excelapp=new ActiveXObject("Excel.Application");
excelapp.visible=true;
objBook=excelapp.Workbooks.Add(); //添加新的工作簿
var objSheet = objBook.ActiveSheet;
添加表格中显示数据项名称的第一行数据信息。
for(j=0;j<column;j++){
objSheet.Cells(1,j+1).value=table.rows(0).cells(j).innerHTML.replace(" ","");
}
应用for循环语句添加分组块信息。
flag=0
for (t=0;t<document.all.sub_product.length;t++){
table_sub=document.all.sub_product(t)
row_sub=table_sub.rows.length
tt=1
if(flag==0){tt=2}
添加分组块的第一行数据,主要为分组名称。
objSheet.Cells(flag+tt,1)=table_sub.rows(0).cells(0).innerHTML.replace(" ","");
添加分组块中的具体产品信息。
for(i=1;i<row_sub-1;i++){
for(j=0;j<column;j++){
objSheet.Cells(flag+i+tt,j+1).value=table_sub.rows(i).cells(j).innerHTML.replace(" ","");}
}
flag=flag+I
添加分组块中最后一行的分组统计数据信息。
for(i=row_sub-1;i<row_sub;i++){
objSheet.Cells(flag+i-1,3).value=table_sub.rows(i).cells(2).innerHTML.replace(" ","");
objSheet.Cells(flag+i-1,6).value=table_sub.rows(i).cells(3).innerHTML.replace(" ","");
objSheet.Cells(flag+i-1,7).value=table_sub.rows(i).cells(4).innerHTML.replace(" ","");
}
flag=flag+i-2
}
添加表格中显示所有产品总计信息的最末行数据。
objSheet.Cells(flag+1,3).value=table.rows(row-1).cells(2).innerHTML.replace(" ","");
objSheet.Cells(flag+1,6).value=table.rows(row-1).cells(3).innerHTML.replace(" ","");
objSheet.Cells(flag+1,7).value=table.rows(row-1).cells(4).innerHTML.replace(" ","");
objBook.SaveAs("goodsinfo.xls");
objSheet.Printout; //自动打印
excelapp.UserControl = true;
}
</script>
复杂报表不仅包括以上各节中应用到的汇总报表、分组报表和主从报表,还包括分栏报表、子报表、交叉报表等。
分栏报表是报表中比较常见的报表格式。一般的报表生成时都是一页接一页的,在分栏报表中可以将多页记录打印在同一页上,每页记录显示在指定的栏框内。分栏报表可分为横向和纵向两种分栏方式。
子报表是在一份报表中插入另一份报表,原来的报表称为主报表,插入的报表称为子报表。子报表是一个完整的报表,不过子报表被视为主报表的一个对象,而且子报表可以插入到主报表的任何一个“节”中。
交叉报表是应用在打印栏目可变的数据表上,并且显示的数据是由一个表中两个动态数据字段对应得到的结果。