今天分享JBolt极速开发平台中使用的异步下载文件的解决方案。
需求场景:
列表查询界面有一个【导出Excel】按钮,需要点击按钮,弹出loading信息框,异步调用后台action,得到数据库数据后生成Excel数据然后响应发送到前端,异步请求拿到数据后,当做文件下载下来。
重点:
异步请求,导出Excel,前端拿到后做成文件下载
解决方案:
1、前端异步请求
点击按钮的时候,执行一个异步请求,去访问Action
<button type="button" onclick="ajaxDownload('admin/user/exportExcel')">导出Excel</button>
//异步下载 function ajaxDownload(url,fileName){ var xhr = new XMLHttpRequest(); xhr.timeout=jboltAjaxTimeout; xhr.open('GET', url, true); xhr.responseType = "blob"; // 返回类型blob //定义请求完成的处理函数 xhr.onload = function () { // 请求完成 if (this.status === 200) { // 返回200 var blob = this.response; var reader = new FileReader(); reader.readAsDataURL(blob); // 转换为base64,可以直接放入a href reader.onload = function (e) { // 转换完成,创建一个a标签用于下载 var a = document.createElement('a'); if(fileName){ a.download =fileName; }else{ var headerName=xhr.getResponseHeader("Content-disposition"); if(headerName){ headerName=decodeURI(headerName); var dl_filenameArr=headerName.split("="); if(dl_filenameArr&&dl_filenameArr.length==2){ a.download =$.trim(dl_filenameArr[1]); } }else{ alert("下载失败,未设置下载文件的filename"); return false; } } a.href = e.target.result; jboltBody.append(a); // 修复firefox中无法触发click a.click(); $(a).remove(); } }else{ alert("网络异常"); } }; // 发送ajax请求 xhr.send(); }
好,这样前端在点击按钮的时候就会执行异步请求,去请求指定的URL地址。
那么后端就需要处理这个请求,从数据库查询后做成excel。
2、后端写出Excel文件流
注意:为了方便演示 看清楚后端导出流程 我没有再service里写 直接在action中快速写完逻辑。
大体意思就是读取数据,把生成的Excel文件流形式写出给Response。
其中header中的content-disposition属性值里的filename是自定义的。
前端按钮上调用ajaxDownload如果传入一个名字的话,会按照传入的名字去下载生成文件。具体是前端工作了。
/** * 导出Excel */ public void exportExcel() { HttpServletResponse response=getResponse(); response.setHeader("Content-Disposition", "attachment;filename=jbolt.xls"); response.setHeader("Pragma", "no-cache"); response.setHeader("Cache-Control", "no-cache"); response.setHeader("Accept-Ranges", "bytes"); response.setDateHeader("Expires", 0); response.setContentType("application/vnd.ms-excel"); //使用hutool 导出excel ExcelWriter excelWriter=ExcelUtil.getWriter(); List<User> users=service.findAll(); int row=0; //循环遍历 for(User user:users) { excelWriter.writeCellValue(0,row, user.getId()); excelWriter.writeCellValue(1,row, user.getName()); excelWriter.writeCellValue(2,row, user.getPinyin()); row++; } //导出下载文件流 try { excelWriter.flush(response.getOutputStream()); } catch (IORuntimeException | IOException e) { e.printStackTrace(); } excelWriter.close(); }
看一下效果:
这个按钮的高级延伸版,我在JBolt极速开发平台里实现的,后端做了更完善的处理,大体原理就是这样。
可以登录演示版,找到这个异步按钮,点击感受一下!
谁在使用JFinal极速开发平台开发项目?
点我查看:
https://mp.weixin.qq.com/s/9InIK3Uf_H0qgeK5k-f9pg
有问题就加我微信
微信:mumengmeng