在开发中遇到问题是这样的:
在维护老的管理系统的过程中,老板说让加导出功能;项目中,查询的筛选条件是用的表单提交的方式写的。
解决方案有两种:
一、用ajax方式导出
var array = $('#frmSearch').serialize();
获得表单数据后,用post方式提交给服务器,服务器返回文件所存在的网络地址,然后用windows.open()的方式下载文件
但是我希望文件下载后,能够把文件删除了;用上边方式就不太合适了,不能及时删除旧文件,于是想出下面的方式:
二、文件流的方式下载
由于ajax不能处理文件流,所以不能再用ajax方式提交数据了,只能还用form表单方式提交数据,但问题来了,怎么能让一个form表单实现两个功能呢?
解决方式就是,我们在js中模拟出一个form表单即可,代码如下:
var $frm = $('<form action="" method="post"></form>'); var array = $('#frmSearch').serializeArray(); for (i = 0, length = array.length; i < length; i++) { key = array[i].name; value = array[i].value; $frm.append($('<input name = "' + key + '" value = "' + value + '" />')); } $frm.submit();
服务器端处理流程是这样的:①根据筛选条件查询数据,然后生成excel;②把文件转换成文件流;③删除该文件;④设置响应头,输出文件流数据;
简单示例代码如下:
//①根据筛选条件查询数据,然后生成excel List<TradeViewModel> modelList = ...;string fileName; string path = ExportHelper.ExportDataToExcel(modelList, "TradeModel.xlsx", "收支记录导出列表", new[] { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K" }, new[] { "Id", "Subject", "Payer", "Receiver", "Manager", "Recorder", "Amount", "PayWay", "PayDate", "Receipt", "Status" }, out fileName); //②把文件转换成文件流 byte[] bytes; using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Read)) { bytes = new byte[(int)fs.Length]; fs.Read(bytes, 0, bytes.Length); } //③删除该文件 System.IO.File.Delete(path); //④设置响应头,输出文件流数据 Response.ContentType = "application/octet-stream"; //通知浏览器下载文件而不是打开 Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8)); Response.BinaryWrite(bytes); Response.Flush(); Response.End();