今天在项目上遇到了一个问题,就是后端接口返回excel文件流,然后前端实现下载excel,前端下载的excel文件居然无法打开!
在网上搜索了很多对应的资料,也尝试了很多办法,还是没能解决,最后在这篇文章上面找到了解决的办法:http://t.csdn.cn/0u4aC ,然后我也总结了一下,希望能帮助到有希望的人!
我这个项目在客户端和后端之间还隔着一层node层,下面简单介绍一下后端返回文件流,前端实现下载excel的整体流程:
下面介绍主要的实现代码:
前端代码:
axios.post('/api/manage/downloadDataRecords', {}, { responseType: 'arraybuffer' }).then(res => {
const blob = new Blob(
[res.data],
{
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8'
},
)
const objUrl = URL.createObjectURL(blob);
const eleLink = document.createElement('a');
eleLink.download = '报表数据-${new Date().getTime()}.xlsx';
eleLink.style.display = 'none';
eleLink.href = objUrl;
document.body.appendChild(eleLink);
eleLink.click();
document.body.removeChild(eleLink);
})
注意:一定要设置responseType的值为arraybuffer
node层的代码:
// 下载
router.all('/data/download(.*)', async (ctx, next) => {
const body = ctx.request.body;
const method = ctx.request.method;
const path = ctx.request.url;
try {
let res;
if (method === 'GET') {
res = await axios.get(`${remoteUrl}${path}`, {
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
responseType: 'arraybuffer',
timeout: 6000,
});
} else if (method === 'POST') {
res = await axios.post(`${remoteUrl}${path}`, body, {
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
responseType: 'arraybuffer',
timeout: 6000,
});
}
/**
* 可以在这里打印一下,看看后端接口返回的content-type是否是application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8
* 如果不是则会导致下载的excel文件无法正常打开
*
*/
// console.log('====headers', res.headers);
ctx.res.writeHead(200, {
// 注意:后端接口响应头中的内容类型content-type必须是application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8,否则下载的文件无法正常打开
'Content-Type': res.headers['content-type'],
'Content-Disposition': res.headers['content-disposition'], // 后端接口返回的文件名称
});
// ctx.body = res.data;
ctx.res.end(res.data, 'binary');
} catch (e) {
ctx.body = e?.response?.data || e.code;
}
});
注意:一定要设置responseType的值为arraybuffer
上面就是具体实现的代码了,主要的地方就是设置axios的responseType的值为arraybuffer,还有就是需要注意一下后端接口响应体中的content-type是否是application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8,否则下载的excel文件无法打开或者乱码。如果有什么问题疑问,欢迎在下方留言一起讨论!