今天分享JBolt极速开发平台中使用的异步下载文件的解决方案。
需求场景:
列表查询界面有一个【导出Excel】按钮,需要点击按钮,弹出loading信息框,异步调用后台action,得到数据库数据后生成Excel数据然后响应发送到前端,异步请求拿到数据后,当做文件下载下来。
重点:
异步请求,导出Excel,前端拿到后做成文件下载
解决方案:
1、前端异步请求
点击按钮的时候,执行一个异步请求,去访问Action
导出Excel
//异步下载
functionajaxDownload(url,fileName){
varxhr=newXMLHttpRequest();
xhr.timeout=jboltAjaxTimeout;
xhr.open('GET',url,true);
xhr.responseType="blob";//返回类型blob
//定义请求完成的处理函数
xhr.onload=function(){
//请求完成
if(this.status===200){
//返回200
varblob=this.response;
varreader=newFileReader();
reader.readAsDataURL(blob);//转换为base64,可以直接放入ahref
reader.onload=function(e){
//转换完成,创建一个a标签用于下载
vara=document.createElement('a');
if(fileName){
a.download=fileName;
}else{
varheaderName=xhr.getResponseHeader("Content-disposition");
if(headerName){
headerName=decodeURI(headerName);
vardl_filenameArr=headerName.split("=");
if(dl_filenameArr&&dl_filenameArr.length==2){
a.download=$.trim(dl_filenameArr[1]);
}
}else{
alert("下载失败,未设置下载文件的filename");
returnfalse;
}
}
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
*/
publicvoidexportExcel(){
HttpServletResponseresponse=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
ExcelWriterexcelWriter=ExcelUtil.getWriter();
Listusers=service.findAll();
introw=0;
//循环遍历
for(Useruser: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|IOExceptione){
e.printStackTrace();
}
excelWriter.close();
}
看一下效果:
这个按钮的高级延伸版,我在JBolt极速开发平台里实现的,后端做了更完善的处理,大体原理就是这样。
可以登录演示版,找到这个异步按钮,点击感受一下!
有问题就加我微信
微信:mumengmeng