这两天在做报表的导出功能,做了多年的开发,对代码的严谨性自然有了一些自我约束,对于这种与业务无关的通用外部处理,都觉得应该将其划分为外部的服务,做处理调用。所以我就想到采用一般处理程序来做文件的下载,前端使用Ajax做无刷新处理,代码如下:
function QueryExcel() { var data = Ext.getCmp("frmMain").GetValues();// 获取json数据 Ext.Ajax.request({ url: '../Services/ReportExportHandler.ashx',// Webservice的地址以及方法名 jsonData: data,method: 'POST',// poste 方式传递 success: function (result) { // 调用成功处理 },failure: function (result) { // 调用失败处理 } }); }
一般处理程序实现文件下载的代码:
string fileName = HttpUtility.UrlEncode(System.Text.Encoding.UTF8.GetBytes("111.csv")); context.Server.ScriptTimeout = 600; context.Response.ContentType = "application/octet-stream"; context.Response.Charset = "gb2312"; context.Response.AddHeader("Content-Disposition",string.Format("attachment;filename=\"{0}\"",fileName)); context.Response.ContentEncoding = System.Text.Encoding.GetEncoding("GB2312"); DataTable dt = this.GetReportExcuteData(dto,paramsValues).Tables[0]; byte[] bs = ExportHelper.GetMemoryBytes(dt); context.Response.BinaryWrite(bs); context.Response.End();
将文件生成到内存的代码:
/// <summary> /// 从内存中获取字节数组 /// </summary> /// <param name="dt">数据表</param> /// <returns>字节数组</returns> public static byte[] GetMemoryBytes(DataTable dt) { // 先打印标头 StringBuilder strColu = new StringBuilder(); StringBuilder strValue = new StringBuilder(); int i = 0; try { MemoryStream ms = new MemoryStream(); byte[] bs; for (i = 0; i <= dt.Columns.Count - 1; i++) { strColu.Append(dt.Columns[i].ColumnName); strColu.Append(","); } strColu.Remove(strColu.Length - 1,1); // 移出掉最后一个,字符 bs = System.Text.Encoding.Default.GetBytes(strColu.ToString() + "\r\n"); ms.Write(bs,bs.Length); foreach (DataRow dr in dt.Rows) { strValue.Remove(0,strValue.Length); // 移出 for (i = 0; i <= dt.Columns.Count - 1; i++) { strValue.Append(dr[i].ToString()); strValue.Append(","); } strValue.Remove(strValue.Length - 1,字符 bs = System.Text.Encoding.Default.GetBytes(strValue.ToString() + "\r\n"); ms.Write(bs,bs.Length); } byte[] data = ms.GetBuffer(); ms.Close(); return data; } catch (Exception ex) { throw ex; } }
在处理时发现点击按钮没有反应,起初我以为是一般处理程序内部写的有问题,但用浏览器的开发者工具查看请求和响应,发现响应的报头跟响应的的内容都与预期的相同,说明我的一般处理程序没有问题。后端没问题,那就是前端的问题了,由于对于Ajax的处理不是非常了解,所以一直也没有想到问题出在哪,后来我就发了个帖子问了一下,这才恍然大悟,原来Ajax可处理的数据格式是有要求的,引用资料原文: Jquery Ajax
另外还查到一篇关于 Ajax数据格式比较的博文,内容如下:
1.html 优点:html片段实现起来只需要很小的工作量。这种格式的外部数据可以通过一种简单的方法加载并插入到页面中,甚至连回调函数都不必使用。无需遍历数据。 缺点:重用性差,外部文件必须与它们的目标容器紧密结合。 2.JavaScript JavaScript文件能投提供极大的灵活性,但它却不是一种真正的数据存储机制。 3.json 优点: json文件的结构使它可以方便地被重用。而且它们非常简洁,也容易阅读,读取速度快。 缺点: json文件中的错误可能导致页面上的脚本静默地终止运行,甚至还会带来其它的负面影响,因此,这种数据必须由信得过的人仔细进行构建。 4.xml 优点: xml文档的可移植性是当之无愧的王者,xml已经成为了web服务领域的“世界语”。xpath、dtd等都为它增色不少,能够对格式进行有效的验证。 缺点: xml格式的文件体积相对较大,解析和操作它们的速度要慢一些。 总结: 通过对以上各种数据格式优缺点的分析,我们知道在不需要与其它应用程序共享数据的情况下,以html片段提供外部数据一般来说都是最简单的。如果数据需要重 用,而且其它应用程序也可能因此受影响,那么在性能和文件大小方面具有优势的json通常是不错的选择。而当远程应用程序未知时,xml则能够为良好的互 操作性提供最可靠的保证。发现了错误就记录以下,对于以后再发现类似的问题也方便查找解决方案。 原文链接:https://www.f2er.com/ajax/163532.html