首先前端发起HTTP请求之后,后端返回一个Excel输出流,然后前端用Blob类型接收数据,并且解析响应头数据以及提取源文件名,最后用a标签完成下载。
一、后端代码
(1)导入阿里巴巴的EasyExcel依赖(pom.xml)
<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.3.1</version>
</dependency>
(2)控制层(GameController.java)
@CrossOrigin
@RequestMapping(value = "exportFile", method = RequestMethod.GET)
@ResponseBody
public void exportFile(@RequestParam("operator") String operator, HttpServletResponse response) throws IOException {gameService.exportFile(operator, response);
}
(3)接口层(IGameService.java)
void exportFile(String operator, HttpServletResponse response) throws IOException;
(4)实现层(GameServiceImpl.java)
/*** 王者Excel实体* 说明:this$0特指该内部类所在的外部类的引用,不需要手动定义,编译时自动加上*/
@Data
@AllArgsConstructor
@NoArgsConstructor
static class KingExcelEntity {@ExcelProperty(value = "英雄", index = 0)private String hero;@ExcelProperty(value = "等级", index = 1)private String level;@ExcelProperty(value = "金币", index = 2)private String gold;@ExcelProperty(value = "击杀", index = 3)private String kill;@ExcelProperty(value = "被击杀", index = 4)private String beKilled;@ExcelProperty(value = "助攻", index = 5)private String assists;@ExcelProperty(value = "评分", index = 6)private String score;@ExcelProperty(value = "是否MVP", index = 7)private String mvp;
}@Override
public void exportFile(String operator, HttpServletResponse response) throws IOException {List<KingExcelEntity> KingsList = new ArrayList<>();KingsList.add(new KingExcelEntity("云缨", "15", "20013", "21", "5", "16", "12.9", "True"));KingsList.add(new KingExcelEntity("王昭君", "15", "17336", "2", "6", "20", "7.5", "False"));KingsList.add(new KingExcelEntity("狄仁杰", "15", "16477", "9", "8", "22", "8.4", "False"));KingsList.add(new KingExcelEntity("兰陵王", "15", "16154", "21", "5", "16", "8.6", "False"));KingsList.add(new KingExcelEntity("赵怀真", "15", "17414", "6", "6", "21", "10.2", "False"));try {String fileName = URLEncoder.encode(operator + "-" + "王者荣耀战绩" + ".xlsx", "utf-8");response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");response.setCharacterEncoding("utf-8");response.setHeader("Content-disposition", "attachment;filename=" + fileName);EasyExcel.write(response.getOutputStream(), KingExcelEntity.class).sheet("第一页").doWrite(KingsList);} catch (Exception e) {response.reset();response.setContentType("application/json");response.setCharacterEncoding("utf-8");HashMap<String, Object> map = new HashMap<>();map.put("status", false);map.put("msg", e.getMessage());response.getWriter().println(JSONObject.toJSONString(map));}
}
二、前端代码
(1)视图页面(/src/view/Example/DownloadBlobFile/index.vue)
<template><div style="padding: 100px"><el-button size="small" type="primary" plain @click="handleDownloadBlobFile()"><el-icon :size="18"><Download /></el-icon><span>下载文件</span></el-button></div>
</template><script>
export default {data() {return {// ...}},methods: {/*** 下载Blob文件句柄方法*/handleDownloadBlobFile(evt) {const operator = '帅龍之龍' // 操作人员this.$axios.get(`/api/exportFile`,{params: {'operator': operator},headers: {'Access-Control-Allow-Origin': '*','Auth-Token': '5201314'},responseType: 'blob'}).then((res) => {try {console.log('响应信息 =>', res)if (res.data.size > 0) {// 响应头信息const headers = res.headers// attachment;filename=%E5%B8%85%E9%BE%8D%E4%B9%8B%E9%BE%8D-%E7%8E%8B%E8%80%85%E8%8D%A3%E8%80%80%E6%88%98%E7%BB%A9.xlsxconst contentDisposition = headers['content-disposition']console.log('contentDisposition =>', contentDisposition)// application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8const contentType = headers['content-type']console.log('contentType =>', contentType)let fileName = contentDisposition.split(`=`)[1]console.log('解析前文件名 =>', fileName) // 解析前文件名:%E5%B8%85%E9%BE%8D%E4%B9%8B%E9%BE%8D-%E7%8E%8B%E8%80%85%E8%8D%A3%E8%80%80%E6%88%98%E7%BB%A9.xlsxfileName = decodeURIComponent(fileName)console.log('解析后文件名 =>', fileName) // 解析后文件名:帅龍之龍-王者荣耀战绩.xlsxthis.exportFileToExcel(contentType, res.data, fileName)} else {this.$message({ message: '文件数据为空', type: 'error', duration: 1000 })}} catch (e) {console.error(e)this.$message({ message: e, type: 'error', duration: 1000 })}}).catch((e) => { console.error(e)this.$message({ message: e, type: 'error', duration: 1000 })})},/*** 导出Excel文件*/exportFileToExcel(contentType, data, fileName) {const url = window.URL.createObjectURL(new Blob([data],{type: contentType}))const link = document.createElement('a')link.style.display = 'none'link.href = urllink.setAttribute('download', `${fileName}` || 'template.xlsx')document.body.appendChild(link)link.click()document.body.removeChild(link)},},
};
</script>
三、效果如下 ~