发送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显示为:

 


本页地址:http://www.foxtable.com/mobilehelp/topics/0148.htm