前端 文件流导出

75 阅读2分钟

前言 记录一下 后面会贴代码

这里写的示例都是 Excel 导出

目前我遇到两个情况,一个是后端单独给接口去导出文件流,一个是和其他列表共用同一个接口

先说第一个情况

单独 导出文件流,这个其实没什么好说的

第一步接口,这里一定一定要设置 responseType: "blob",如果没有设置,你怎么导出都没有用,导出的文件会显示已损坏,导个der

这里说一下 responseType: "blob" 是什么东西

responseType: "blob" 是一个设置请求响应类型的选项,表示服务器响应的数据是二进制大对象(Blob)。Blob 通常用于处理文件数据,如图片、视频或文档。在这种设置下,响应将不会被解析为文本或 JSON,而是以二进制形式接收,使得下载和处理文件数据成为可能。

好了,这里贴一个接口的示例

TS写的不规范,求大佬放过

// request是我自己封装的 axios 拦截器
export const Iexport = (params: any) => {
  return request({
    url: `index.php`,
    method: "get",
    params: {
      ...params
    },
    responseType: "blob",
  });
};

第二步

这里有一个点,比较重要,就是type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' 这个类型,要和后端对应,要不然就得寄,导出来也看不了,显示文件已损坏

type 你也可以用其他的类型

type 指定了 Blob 对象的 MIME 类型,这里是 Excel 文件的 MIME 类型

其他我就不一一写注释了

const export = async () => {
  const parmas = {
    export: true,
  }
  try {
    const res = await Iexport(parmas);
    const blob = new Blob([res.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
    const url = URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = url;
    link.setAttribute('download', 'export_logs.xlsx');
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    URL.revokeObjectURL(url);
  } catch (error) {
    console.log(error)
  }
}

第二个情况

和其他列表共用同一个接口,就是这个接口又要展示列表数据,又要做导出功能

第一步

TS写的不规范,求大佬放过

还是接口,接口要改一下,上面我用的是axios的拦截器,这里不用了

最主要的是要用 AxiosRequestConfig ,要不然页面或者接口会报错(不用也应该可以,只是我这里会报错), 但是responseType = 'blob 一定要有

创建一个 requestOptions 对象,并将其类型指定为 AxiosRequestConfig

AxiosRequestConfig 是 axios 库提供的接口类型,用来定义请求的配置选项。使用 AxiosRequestConfig 可以明确定义请求的结构和配置

import { AxiosRequestConfig } from 'axios'
export const IgetList = (params: any) => {
  const requestOptions: AxiosRequestConfig = {
    url: `/index.php`,
    method: 'get',
    params: {
      ...params,
    },
  }
  if (params.export === true) {
    requestOptions.responseType = 'blob'
  }
  return request(requestOptions)
}

第二步

这里的代码和上面的一样,不用担心,只是写法不一样,你也可以用上面的方法来写,重要的是 接口的设置

这里你也可以用其他的类型 type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' 这个类型,还是要和后端对应

const export = async () => {
  const params = {
    export: true,
  }
  try {
    const res = await IgetList(params)
    const blob = new Blob([res.data], {
      type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
    })
    const url = URL.createObjectURL(blob)
    const a = document.createElement('a')
    Object.assign(a, {
      href: url,
      download: 'Info_sheet.xlsx',
      style: 'display: none',
    })
    document.body.appendChild(a)
    a.click()
    URL.revokeObjectURL(url)
    document.body.removeChild(a)
  } catch (error) {
    console.error('Export failed: ', error)
  }
}