前端在处理数据量大的需求的时候,避免用户一个一个输入的尴尬境地,经常会通过导入文件的方式解决从而来减轻用户工作量。
通常导入的方式有两种:
- 导入文件后前端通过
xlsx
插件解析,然后返回想要的数据,社区已经有很多相关资料,本文不做详细讨论 - 通过调用后端接口,然后接口返回文件流,前端处理
而调用接口又有两种方式:
Get请求
get
请求就是通过请求接口,请求成功后接口返回数据流,然后前端直接open
就会直接下载返回的文件。
我把这个过程封装成了一个方法
// get请求方法,直接通过url打开
// apiHost:请求域名 prefix请求服务 url:请求地址 data:请求参数
export const exportExcel = (data, url) => {
let queryStr = "";
Object.keys(data).forEach(key => {
if (data[key] !== false && data[key] !== undefined && data[key] !== null) {
queryStr += `&${key}=${data[key]}`;
}
});
window.location.href = `${apiHost}${prefix}${url}?${queryStr}`;
};
从上面可以看出核心代码就是window.location.href = ${apiHost}${prefix}${url}?${queryStr}
,只要接口正常返回,浏览器就会自动下载返回的文件。
Post请求
post
请求会相对麻烦一些,因为要设置responseType
,responseType
的默认值是DOMString,而一般来说不管是用的Axios还是其他请求库,一般都是json
所以如果请求的是文件,就要针对这个字段设置,否则要么请求不成功,要么返回乱码。
下面用
axios
为例并封装对应的方法,关键在responseType: "blob"
// 接口请求,axios已经设置拦截器并封装了一层
axios({
url: `${prefix}/materials/export `,
data: {
...params
},
method: "POST",
responseType: "blob" // 如果返回的是数据/文件流,需要修改responseType为blob或者arraybuffer
})
下载文件的方法
// post请求方法,返回数据/文件流,请求的responseType要传"arraybuffer"或"blob"
// data就是请求返回的文件数据流,fileName是下载展示的文件名
export const exportExcelPost = (data, fileName) => {
const link = document.createElement("a");
const blob = new Blob([data], { type: "application/x-excel" });
link.style.display = "none";
link.href = URL.createObjectURL(blob);
link.download = fileName || `导出.xlsx`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
};
其实很久以前也处理过相关问题,记得当时还查了很多资料走了好多弯路才解决,所以为了避免这种情况这次就记录下来,方便以后查阅。