获取jqGrid中的全部数据导出并生成Excel文件流供用户下载(post请求实现文件下载)

最近有一个需求是:javascript

将jqGrid表格中的数据生成报表Excel文件返回给用户。css

个人想法是获取jqGrid中的数据而后生成json数据,传给后端,生成文件流,响应到前端,保存为excel文件。html

ajax为何不可以实现下载文件

ajax的返回值类型是json,text,html,xml类型,或者能够说ajax的接收类型只能是string字符串,不是流类型,因此没法实现文件下载。前端

但用ajax仍然能够得到文件的内容,该文件将被保留在内存中,没法将文件保存到磁盘。这是由于JavaScript没法和磁盘进行交互,不然这会是一个严重的安全问题,js没法调用到浏览器的下载处理机制和程序,会被浏览器阻塞。html5

而且 我用ajax实现的时候出现了不少bug。java

在网上参考好多博客,通过不断的调试,我仍是选择了原生的XMLHttpRequest对象进行post请求。web

blob(HTML5 新特性)

二进制大对象,是一个能够存储二进制文件的容器。ajax

做用

Js一直以来都没有比较好的能够直接处理二进制的方法。而Blob的存在,容许咱们能够经过JS直接操做二进制数据。chrome

Blob对象能够看作是存放二进制数据的容器,此外还能够经过Blob设置二进制数据的MIME类型。数据库

BLOB是一个大文件,典型的BLOB是一张图片或一个声音文件,因为它们的尺寸,必须使用特殊的方式来处理(例如:上传、下载或者存放到一个数据库)。

重点应用
  • 目前作的经过URL下载文件。
  • 分片上传文件(将大文件分片,轮询向后台提交各文件片断)。

后端代码

/** * 生成Excel报表 * Error:存在问题 * 1. 前端表格中没有Student对象的一些属性,生成报表时没必要要显示的属性字段在Excel中显示。 * solve:加判断控制。 * 2. (因为blob是HTML5新出的)兼容性问题:chrome、firefox、opera无问题, * 3. 检测grid表格中有无字段名称冲突问题。 * solve:细心检查便可 * 4. 下载完Excel,打开出现"文件已损坏 没法打开"问题,这是由于office受保护试图致使(安全问题) * solve:在office选项里边修改一下便可(客户端问题) * @param list * @param response */ @RequestMapping(value = "/exstudent",consumes = "application/json;charset=utf-8") public void export (@RequestBody List<Student> list, HttpServletResponse response){ OutputStream out = null; String name = "学生信息管理表"; for (Student stu:list) { System.out.println(stu.getStudentname()); } try { response.setHeader("content-type", "application/octet-stream"); response.setContentType("application/octet-stream"); response.setHeader("Content-Disposition", "attachment;filename=" +URLEncoder.encode(name, "UTF-8")+".xlsx"); out = response.getOutputStream(); //调用老师本身写的库,本篇文章不详细说生成Excel文件的事情。 TExcel.exportExcel(name,Student.class,list,out); System.out.println("下载ok"); out.flush(); out.close(); } catch (Exception e) { e.printStackTrace(); }finally{ } } /** * 生成Excel报表 * Error:存在问题 * 1. 前端表格中没有Student对象的一些属性,生成报表时没必要要显示的属性字段在Excel中显示。 * solve:加判断控制。 * 2. (因为blob是HTML5新出的)兼容性问题:chrome、firefox、opera无问题, * 3. 检测grid表格中有无字段名称冲突问题。 * solve:细心检查便可 * 4. 下载完Excel,打开出现"文件已损坏 没法打开"问题,这是由于office受保护试图致使(安全问题) * solve:在office选项里边修改一下便可(客户端问题) * @param list * @param response */ @RequestMapping(value = "/exstudent",consumes = "application/json;charset=utf-8") public void export (@RequestBody List<Student> list, HttpServletResponse response){ OutputStream out = null; String name = "学生信息管理表"; for (Student stu:list) { System.out.println(stu.getStudentname()); } try { response.setHeader("content-type", "application/octet-stream"); response.setContentType("application/octet-stream"); response.setHeader("Content-Disposition", "attachment;filename=" +URLEncoder.encode(name, "UTF-8")+".xlsx"); out = response.getOutputStream(); //调用老师本身写的库,本篇文章不详细说生成Excel文件的事情。 TExcel.exportExcel(name,Student.class,list,out); System.out.println("下载ok"); out.flush(); out.close(); } catch (Exception e) { e.printStackTrace(); }finally{ } }

前端代码:

//导出按钮被点击以后,将按钮制为无效(防止屡次生成) function abideBtn(){ console.log("禁止按钮......"); $("#download").attr({"href":"#"}); $("#download").css("cursor","not-allowed"); } //下载过程当中出错误, function downloadError(){ console.log("发生错误,下载失败"); alert("下载中出现错误!请重试"); $("#download").attr({"href":"javascript:exportData();"}); $("#download").css("cursor","pointer"); } //导出表格数据 //注意:下面获取jqGrid中全部行数据的前提是分页在前端,而不是后端。 //若是你是在后端分页,那么你会发现,你会将全部数据都显示出来。 function exportData() { var grid = jQuery("#grid"); //获取当前显示的数据 var rowNum = grid.jqGrid('getGridParam', 'rowNum'); //获取显示配置记录数量 var total = grid.jqGrid('getGridParam', 'records'); //获取查询获得的总记录数量 //设置rowNum为总记录数量而且刷新jqGrid,使全部记录现出来调用getRowData方法才能获取到全部数据 grid.jqGrid('setGridParam',{rowNum: total,}).trigger('reloadGrid'); var rows = o.jqGrid('getRowData'); grid.jqGrid('setGridParam',{rowNum: rowNum,}).trigger('reloadGrid'); postToPOM(rows); } //发送post请求 function postToPOM(rows) { console.log(rows); var url = "../student/exstudent"; var xhr = new XMLHttpRequest(); xhr.open('POST',url,true); xhr.responseType = "blob"; xhr.setRequestHeader("Content-Type" , "application/json;charset=utf-8"); //添加监听事件。 xhr.addEventListener("load",abideBtn,false); xhr.addEventListener("error",downloadError,false); xhr.onload = function (){ if(this.status === 200){ //建立Bolb对象 var blob = this.response;//html5新出的 var reader = new FileReader(); reader.readAsDataURL(blob); reader.onload = function(e){ //建立a标签,构造下载弹窗 var a = document.createElement("a"); a.id = "downloadTag"; a.download = '学生信息管理表.xlsx'; a.href = e.target.result; $("body").append(a); a.click(); $("#downloadTag").remove(); console.log("下载完成!"); //恢复按钮 $("#download").attr({"href":"javascript:exportData();"}); $("#download").css("cursor","pointer"); } } }; xhr.send(JSON.stringify(rows)); } //导出按钮被点击以后,将按钮制为无效(防止屡次生成) function abideBtn(){ console.log("禁止按钮......"); $("#download").attr({"href":"#"}); $("#download").css("cursor","not-allowed"); } //下载过程当中出错误, function downloadError(){ console.log("发生错误,下载失败"); alert("下载中出现错误!请重试"); $("#download").attr({"href":"javascript:exportData();"}); $("#download").css("cursor","pointer"); } //导出表格数据 //注意:下面获取jqGrid中全部行数据的前提是分页在前端,而不是后端。 //若是你是在后端分页,那么你会发现,你会将全部数据都显示出来。 function exportData() { var grid = jQuery("#grid"); //获取当前显示的数据 var rowNum = grid.jqGrid('getGridParam', 'rowNum'); //获取显示配置记录数量 var total = grid.jqGrid('getGridParam', 'records'); //获取查询获得的总记录数量 //设置rowNum为总记录数量而且刷新jqGrid,使全部记录现出来调用getRowData方法才能获取到全部数据 grid.jqGrid('setGridParam',{rowNum: total,}).trigger('reloadGrid'); var rows = o.jqGrid('getRowData'); grid.jqGrid('setGridParam',{rowNum: rowNum,}).trigger('reloadGrid'); postToPOM(rows); } //发送post请求 function postToPOM(rows) { console.log(rows); var url = "../student/exstudent"; var xhr = new XMLHttpRequest(); xhr.open('POST',url,true); xhr.responseType = "blob"; xhr.setRequestHeader("Content-Type" , "application/json;charset=utf-8"); //添加监听事件。 xhr.addEventListener("load",abideBtn,false); xhr.addEventListener("error",downloadError,false); xhr.onload = function (){ if(this.status === 200){ //建立Bolb对象 var blob = this.response;//html5新出的 var reader = new FileReader(); reader.readAsDataURL(blob); reader.onload = function(e){ //建立a标签,构造下载弹窗 var a = document.createElement("a"); a.id = "downloadTag"; a.download = '学生信息管理表.xlsx'; a.href = e.target.result; $("body").append(a); a.click(); $("#downloadTag").remove(); console.log("下载完成!"); //恢复按钮 $("#download").attr({"href":"javascript:exportData();"}); $("#download").css("cursor","pointer"); } } }; xhr.send(JSON.stringify(rows)); }
相关文章
相关标签/搜索