前端导出excel/xlsx文件乱码

前端在处理数据量大的需求的时候,避免用户一个一个输入的尴尬境地,经常会通过导入文件的方式解决从而来减轻用户工作量。

通常导入的方式有两种:

  • 导入文件后前端通过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请求会相对麻烦一些,因为要设置responseTyperesponseType的默认值是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);
};

其实很久以前也处理过相关问题,记得当时还查了很多资料走了好多弯路才解决,所以为了避免这种情况这次就记录下来,方便以后查阅。

你可能感兴趣的:(前端导出excel/xlsx文件乱码)