项目需要,有一个功能是后端生成Excel文件并且写入文件流,前台接收并提示用户导出文件。
看起来是个很简单的功能,网上关于这个功能的解决办法也有很多,基本都差不多,大致如下:
- 后端:
@RequestMapping(value = "/exportGatherXls", method = RequestMethod.POST)
public void exportGatherXls(HttpServletResponse response) {
//导出Excel
response.setContentType("application/vnd.ms-excel;charset=utf-8");
String codedFileName = "test";
OutputStream fOut = null;
try {
String newtitle = new String(codedFileName.getBytes("UTF-8"), "ISO8859-1");
response.setHeader("content-disposition", "attachment;filename=" + newtitle + ".xls");
Workbook workbook = new HSSFWorkbook();
//2.创建工作簿
Sheet sheet = workbook.createSheet();
//3.创建标题行,测试数据
Row titlerRow = sheet.createRow(0);
titlerRow.createCell(0).setCellValue("省");
titlerRow.createCell(1).setCellValue("市");
titlerRow.createCell(2).setCellValue("区");
titlerRow.createCell(3).setCellValue("邮编");
titlerRow.createCell(4).setCellValue("简码");
titlerRow.createCell(5).setCellValue("城市编码");
fOut = response.getOutputStream();
workbook.write(fOut);
workbook.close();
} catch (Exception e) {
}finally {
try {
if (fOut != null) {
fOut.flush();
fOut.close();
}
} catch (IOException e) {
}
}
}
- 前端:
axios({
method: 'post',
url: url,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
data: qs.stringify(params, {arrayFormat: 'brackets'}),
// 这个非常重要!!
responseType: 'blob'
}).then(response => {
let blob = new Blob([response.data], {type: 'application/vnd.ms-excel;charset=utf-8'});
let downloadElement = document.createElement('a');
let href = window.URL.createObjectURL(blob); //创建下载的链接
downloadElement.href = href;
downloadElement.download = '导出文件.xls'; //下载后文件名
document.body.appendChild(downloadElement);
downloadElement.click(); //点击下载
document.body.removeChild(downloadElement); //下载完成移除元素
window.URL.revokeObjectURL(href); //释放掉blob对象
});
基本上就可以实现导出功能了。
但是!我尝试了无数次都遇到了导出的文件打开提示错误并且乱码的问题:

强行打开是这个鬼样子:

我对照网上的下载文件的代码检查和尝试了很多次都是这个错误,直到查看response的结构发现了这个:

这里的request类型不是原生的XMLHttpRequest,data是字符串类型,按照我们的设置应该是blob类型才对。
字面意思看起来应该是我使用了mockjs所以导致了Request类型被封装,去掉mock引入,正解!

结论:下载文件不要使用mockjs,尽管并没有配置拦截下载的后端地址,但是mock会拦截所有的请求,匹配规则的就使用模拟数据,不匹配的也会使用封装后的request请求后台。
真是一个不容易发现原因的问题,前后花了大半天时间才解决。希望可以帮助到和我遇到一样问题的小伙伴们~

项目中使用axios下载Excel时,遇到文件打开报错且显示乱码的问题。通过检查发现,虽然后端生成并返回了文件流,前端接收到的数据类型为字符串而非预期的blob。问题根源在于MockJS导致请求被封装,即使未配置拦截下载请求,也会对所有请求进行处理。解决方案是禁用MockJS,避免其影响下载请求。这样便能成功导出Excel文件。
&spm=1001.2101.3001.5002&articleId=102460136&d=1&t=3&u=845a72bed27249b081d2b95234572ea9)
361

被折叠的 条评论
为什么被折叠?



