从后端获取文件数据并导出

导出文件的公共方法

javascript 复制代码
export const download = (res, tools) => {
  const { message, hide } = tools;
  const fileReader: any = new FileReader();
  console.log('fileReader-res>>>', res);
  fileReader.onload = (e) => {
    if (res?.data?.type === 'application/json') {
      try {
        const jsonData = JSON.parse(fileReader.result);
        if (jsonData?.success === false && jsonData?.message) {
          hide?.();
          message.error(jsonData?.message);
        }
      } catch (error) {
        hide?.();
        message.error(getLocalTextFun('common.export.error'));
      }
    } else {
      try {
        const filename = (
          res.response.headers.get('content-disposition').split('filename=')?.[1] || ''
        ).replace(/"/g, '');
        if ('msSaveOrOpenBlob' in navigator) {
          window.navigator.msSaveOrOpenBlob(res.data, decodeURI(filename));
        } else {
          const blob = new Blob([res.data]);
          const url = window.URL.createObjectURL(blob);
          const link: any = document.createElement('a');
          link.href = url;
          link.download = decodeURI(filename);
          link.click();
          hide?.();
          window.URL.revokeObjectURL(url);
        }
      } catch (err: any) {
        hide?.();
        message.error(getLocalTextFun('common.export.error'));
      }
    }
  };
  try {
    fileReader.readAsText(res.data);
  } catch (e) {
    hide?.();
    message.error(getLocalTextFun('common.export.error'));
  }
};

请求后端接口

javascript 复制代码
const hide = message.loading(`加载中...`, 0);
const res = await exportI18nByLocal(record.locale);
download(res, {message, hide});

接口请求

javascript 复制代码
export async function executeAndTryCatch(func: any) {
  try {
    return await func();
  } catch (error: any) {
    return error;
  }
}
export function exportI18nByLocal(locale:string) {
  return executeAndTryCatch(() =>
    request<Record<string, any>>(`${api().i18nExport}?locale=${locale}`, {
      method: 'GET',
      responseType: 'blob',
      //'Accept': 'application/vnd.ms-excel', 导出文件是excel
      headers: {
        'Accept': 'application/vnd.ms-excel',
        "locale": locale
      },
      //  获取返回数据结构里面包含response数据 如下图
      getResponse: true,
    }).then((res: any) => judgeErrorByResponseType(res)),
  );
}

接口返回结果

判断文件是否导出失败

javascript 复制代码
function judgeErrorByResponseType(response: any) {
  const res = response.response;
  return new Promise((resolve, reject) => {
    if (!res) resolve('');
    if (res.headers.get('Content-Type').includes('json')) {
      const reader = new FileReader();
      reader.onload = () => {
        const { result }: any = reader;
        const errorInfos = JSON.parse(result);
        resolve(errorInfos);
      };
      reader.onerror = (err) => {
        reject(err);
      };
      reader.readAsText(response.data);
    } else {
      resolve(response);
    }
  });
}
相关推荐
涔溪1 分钟前
深入了解 Vite 的核心特性 —— 开发服务器(Dev Server)和热更新(HMR)的底层工作机制
前端·vite
前端一课23 分钟前
【vue高频面试题】第 14 题:Vue3 中虚拟 DOM 是什么?为什么要用?如何提升性能?
前端·面试
前端一课23 分钟前
【vue高频面试题】第 17 题:Vue3 虚拟 DOM 与 PatchFlag 原理 + 静态节点提升
前端·面试
前端一课24 分钟前
【vue高频面试题】第 13 题:Vue 的 `nextTick` 原理是什么?为什么需要它?
前端·面试
前端一课25 分钟前
【vue高频面试题】第 12 题:Vue(尤其 Vue3)中父子组件通信方式有哪些?区别是什么?
前端·面试
前端一课27 分钟前
解释watch和computed的原理
前端·面试
前端一课29 分钟前
【vue高频面试题】第 18 题:Vue3 响应式原理中的 effect、依赖收集与依赖触发
前端·面试
前端一课29 分钟前
【vue高频面试题】第 19 题:Vue3 性能优化技巧
前端·面试
前端一课32 分钟前
【vue高频面试题】第 15 题:computed vs watch 区别 + 使用场景
前端·面试
前端一课32 分钟前
【vue高频面试题】第 20 题:Vue3 生命周期 + watch 执行顺序
前端·面试