vue3 处理后端返回Blob流文件(实现下载excel)

1,636 阅读2分钟

直接请求接口(问题)

一个导出excel的接口直接请求 可以看到返回来的数据是乱码的

image.png

那如何解决?

流文件导出注意

流文件导出需要在请求头加上 responseType: 'blob' 或者 responseType: 'arraybuffer' 否则文件会提示损坏

image.png

封装导出excel方法

封装的方法

import { reqExportExcel } from "@/api/common/index"
/**
 * 导出excel
 * @param { string } url 请求下载excel的地址
 * @param { object } params 地址所需要的参数
 * @param { string } fileName 下载后的文件名
 * @param { boolean } isGet 是否为get 请求 默认为post
 */
export async function exportExcel(url: string, params: any, fileName: string, isGet = false ) {
  const _params = Object.assign({}, params);
  try {
    let res: any = await reqExportExcel(url, _params, isGet);
    console.log(" res = data", res); // 注意你封装的axios 响应拦截 返回的是什么 我的返回是response,所有下面数据在 res.data里
    if(res.status === 200){
      let blob = new Blob([res.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
      const _fileName = `${fileName}.xlsx`
      if ('download' in document.createElement('a')) { // 非IE下载
        const elink = document.createElement('a'); // 创建一个<a></a>标签
        elink.download = _fileName; // 设置文件名
        elink.style.display = 'none'; // 障眼法藏起来a标签
        elink.href = URL.createObjectURL(blob); // 将流文件写入a标签的href属性值
        document.body.appendChild(elink); // 将a标签追加到文档对象中
        elink.click(); // 模拟点击了a标签,会触发a标签的href的读取,浏览器就会自动下载了
        URL.revokeObjectURL(elink.href) // 释放URL 对象
        document.body.removeChild(elink)
      } else { // IE10+下载
        navigator.msSaveBlob(blob, fileName);
      }
    }
  } catch (error) {
    console.log(error);
  }
}

导出excel请求

import { opCpep3 } from '@/api/index';
import { exportExcel } from '@/utils/methods'

/**
 * 导出查询订单列表
 */
export const exportOrderListReq = (params: any) => {
  let url = `v2/order/list?export=T`
  exportExcel(url, params, '订单统计', true);
}

/**
 *  导出excel
 */
export function reqExportExcel(url: string, params: any, isGet = false) {
  return opCpep3({ // opCpep3 是基于 axios 封装的
    method: isGet ? 'GET' : 'POST',
    url,
    data: params,
    config: {
      responseType: 'arraybuffer',
    }
    // 流文件导出注意事项 需要加responseType: 'blob'或者,responseType: 'arraybuffer' ,否则文件会损坏
  })
}

vue 里面接口调用

import { exportOrderListReq } from '@/api/common/index';

exportOrderListReq(params);
ElMessage.success("导出成功");

基本上代码就是这样了。也有相应的注释,可以看懂的。