下载
一. 下载固定文档
-
固定文档后端通常会返回一个文档链接,可以使用
window.open()
直接下载; -
此方法可以给给的下载链接或文件下载模版自定义设置名字并避免文件名中空格乱码
downLoad() {
axios
.get(
'https://p.ampmake.com/fed/application/vnd.openxmlformats-officedocument.spreadsheetml.sheet/2d111a64e05e53cdeb0c8bf45f6b7e2c.xlsx',
{ responseType: 'blob' }
).then((res) => {
const blob = res.data;
const a = document.createElement('a');
a.download = '还本计划上传模板';
a.href = URL.createObjectURL(blob);
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
});
},
二. 下载动态文档
1. 有时是动态文档,此时后端会返回一个文件流,此时前端需要做一些特殊处理进行下载并获取文件名。
// 处理模版文件流下载
const downloading = ref(false);
const downloadFile = async () => {
const res: any = await api({
id: id.value,
name: name.value,
});
try {
const blob = new Blob([res.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
const objectUrl = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = objectUrl;
a.download = '这是一个固定的文件名';
document.body.appendChild(a); // 部分浏览器要求a元素添加在DOM中才能正常工作
a.click();
URL.revokeObjectURL(objectUrl);
document.body.removeChild(a);
} catch (e: any) {
LiMessage.error('下载失败,请联系管理员。报错信息:', e);
}
};
2. 获取动态文件名后端会在content-disposition中返回,此时需要单独处理,如果使用的脚手架版本低于@1.4.6则需要进行手动处理,此时的response会被封装起来,需要在request.ts的拦截器中放开
注意:如果想在浏览器中通过 JavaScript 获取
`Content-Disposition`
字段,服务器需要在响应中设置`Access-Control-Expose-Headers`
响应头,并包括`Content-Disposition`
,这样前端代码才能访问到它。例如,后端可以设置以下的响应头:
Access-Control-Expose-Headers: Content-Disposition
3. 在response.header中获取文件名并处理如果文件名类似: "Excel-ÀíÏëL9Õýʽ°æ-SKUÄ£°æ-20240110095859.xlsx"
前端无法进行解码获取到正确文件名,这通常是因为前后端字符编码不一致,需要后端用url转码处理一下,此时获取到的文件名为filename="Excel-%E7%90%86%E6%83%B3L9%E6%AD%A3%E5%BC%8F%E7%89%88SKU%E6%A8%A1%E7%89%88-20240110103630.xlsx";之后就可以进行专门解析
const blob = new Blob([res.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
const objectUrl = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = objectUrl;
// 解析文件名,假设contentDisposition是响应头中获取到的Content-Disposition
let contentDisposition = res.headers['content-disposition'];
let fileName = contentDisposition.match(/filename\*?=(UTF-8'')?([^;]+)/)[2];
if (fileName.startsWith('"') && fileName.endsWith('"')) {
fileName = fileName.substring(1, fileName.length - 1); // 去掉两端的双引号
}
fileName = decodeURIComponent(fileName); // 对文件名进行解码
a.download = fileName;
document.body.appendChild(a); // 部分浏览器要求a元素添加在DOM中才能正常工作
a.click();
URL.revokeObjectURL(objectUrl);
document.body.removeChild(a);