发送Excel报表
我们通常会采用下面的HttpRequest事件代码来响应用户访问Excel报表的请求:
Select
Case e.path
Case "ckd.xls"
Dim
Book As New
XLS.Book(ProjectPath
&
"Attachments\出库单.xls")
Dim fl
As String =
ProjectPath &
"Reports\出库单.xls"
book.AddDataTable("出库","数据源名称","Select
* from {出库}
where
出库单编号=
'CK-20030726001'")
'添加父表
book.AddDataTable("出库明细","数据源名称","Select
* from {出库明细}
where
出库单编号=
'CK-20030726001'")
'添加子表
book.AddRelation("出库","出库单编号","出库明细","出库单编号")
'建立关联
Book.Build()
Book.Save(fl)
e.WriteFile(fl)
End
Select
过程很简单:基于模版生成Excel报表,将生成的报表保存为一个文件,然后用WriteFile方法将文件发送到客户端的浏览器。
这样的设计有以下不足:
1、虽然WriteFile是异步执行的,但是Excel报表的生成和保存却是和主线程同步的,且Excel报表的生成并非很高效,所以用户量比较大的时候,会影响效率。
2、整个过程要分别保存和读取一次文件,我们知道计算机性能的瓶颈就是硬盘的读写,所以这同样会影响效率。
3、由于要保存为实际的文件,所以容易出现文件名冲突,假定有多个用户同时访问,上面的代码肯定会出错,虽然可以采用一些手段避免同名冲突,但毕竟增加了工作量。
WriteBook
为彻底解决上述问题,我们为HttpRequest事件增加了一个WriteBook方法,此方法专门用于发送Excel报表,其语法为:
WriteBook(Book,FileName,InLine)
Book | 要发送的Excel报表 |
FileName | 客户端浏览器下载此报表时使用的文件名 |
InLine | 可选参数,逻辑型,是否直接在浏览器显示报表,默认为True,设为False将下载报表。 实际上除了iOS设备,其他设备不管如何设置,都会下载报表。 |
WriteBook是异步执行的,而且在发送报表之前,还是会异步执行Build方法生成报表,所以如果不是Excel报表模板,请将Book的PreBuild属性设置为False,避免WriteBook执行Build方法。
一个例子
HttpRequest事件代码:
Select
Case e.path
Case
"ckd.xls"
'直接在浏览器显示
Dim
Book As New
XLS.Book(ProjectPath
& "Attachments\出库单.xls")
book.AddDataTable("出库","数据源名称","Select
* from {出库} where 出库单编号= 'CK-20030726001'")
'添加父表
book.AddDataTable("出库明细","数据源名称","Select
* from {出库明细} where 出库单编号= 'CK-20030726001'")
'添加子表
book.AddRelation("出库","出库单编号","出库明细","出库单编号")
'建立关联
e.WriteBook(book,"出库单.xls",True)
Case "emp.xls"
'下载为文件
Dim
Book As New
XLS.Book(ProjectPath
& "Attachments\资料卡.xls")
book.AddDataTable("员工","数据源名称","Select
* from {员工} where 姓名 = '王伟'")
e.WriteBook(book,"emp.xls",False)
Case "orders.htm"
'请求的是网页,返回的是Excel文件
Dim nms()
As String =
{"产品","客户","数量","单价","金额","日期"}
Dim cmd
As New
SQLCommand
cmd.ConnectionName
= "数据源名称"
cmd.CommandText
= "Select
产品,
客户,
数量,
单价,
数量
* 单价
As 金额,
日期
From {订单}
Where 日期 = #" &
Date.Today &
"#"
Dim dt
As DataTable
= cmd.ExecuteReader
Dim
Book As New
XLS.Book
Dim
Sheet As XLS.Sheet
= Book.Sheets(0)
For c
As Integer =
0 To
nms.Length -
1
Sheet(0,
c).Value =
nms(c)
Next
For r
As Integer =
0 To
dt.DataRows.Count
- 1
For
c As Integer
= 0 To
nms.Length -
1
Sheet(r
+ 1, c).Value
= dt.Datarows(r)(nms(c))
Next
Next
book.PreBuild
= False
'非报表模请将PreBuild
属性设置为False
e.WriteBook(book,"订单.xls",True)
End
Select
提示:
1、InLine参数仅对iOS设备有效。
2、非报表模板请将Book的PreBuild参数设置为False。
3、FileName参数可以和客户请求的文件名不同,甚至可以在客户请求一个网页时,返回一个excel文件。
尽管iOS设备可以在浏览器直接查看Office文档,但是兼容性却不好,例如上面的第二个报表,分别在iOS上的浏览器和iOS上的WPS显示,存在很大的差异:
iOS上的浏览器显示为:
iOS上的WPS显示为: