一般我们实现excel导出都是直接重定向或form表单提交,但如果后台发生异常,提示信息就会在新窗口以文本形式展示,很不友好,这里推荐另一种实现方式,使用post请求,并可以传递自定义错误信息:
前端使用axios,responseType要设置为blob,也就是二进制文件,在控制台打印是这种样子:
前端代码:
exportActivitiesAnalyze: function () { let that= this let params = { activitiesId: activitiesId, startTime: startTime, endTime: endTime } axios({ method: 'post', url: '/activityManage/exportExcel', data: params, responseType: 'blob' }).then(resp => { that.downloadFile(resp,that) }).catch(resp => { that.$notify.error(resp.msg || '导出失败') }) }
下载方法,实现方式为打开一个新链接,然后放置download按钮,并自动点击:
downloadFile (resp,that) { let data = resp.data // 此处提示自定义提示语,从header中获取 if(resp.headers['errormsg'] || !data){ that.$notify.error(decodeURI(resp.headers['errormsg'])||'导出失败') return } let url = window.URL.createObjectURL(new Blob([data])) let link = document.createElement('a') link.style.display = 'none' link.href = url // 文件名在后端设置 link.setAttribute('download', decodeURI(resp.headers['filename'])) document.body.appendChild(link) link.click() },
后台设置文件信息与文件名:
try { HSSFWorkbook hssfWorkbook = new HSSFWorkbook() String errorMsg = null; /** * 封装excel数据方法体,此处忽略,可自定百度poi * 根据需要自定义错误提示信息,最后放入header * errorMsg = "导出异常:活动不存在" */ String fileName = "excel导出数据.xls"; //清空response response.reset(); //设置response的Header response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "utf-8")); //提示信息 response.setHeader("errorMsg", URLEncoder.encode(errorMsg, "utf-8")); response.setHeader("FileName", URLEncoder.encode(fileName, "utf-8")); response.setContentType("application/vnd.ms-excel;charset=gb2312"); OutputStream os = new BufferedOutputStream(response.getOutputStream()); hssfWorkbook.write(os); hssfWorkbook.close(); os.flush(); os.close(); } catch (Exception e) { log.error("导出分析数据异常:"+e); throw new RuntimeException(e); }