当前位置: 首页 > article >正文

后端返回了 xlsx 文件流,前端怎么下载处理

当后端返回一个 .xlsx 文件流时,前端可以通过 JavaScript 处理这个文件流并触发浏览器下载。


实现步骤

  1. 发送请求获取文件流
    使用 fetchaxios 等工具向后端发送请求,确保响应类型设置为 blob(二进制数据流)。

  2. 创建 Blob 对象
    将返回的文件流转换为 Blob 对象,这是处理二进制数据的标准方式。

  3. 生成下载链接
    使用 URL.createObjectURL 方法将 Blob 对象转换为一个临时 URL。

  4. 触发下载
    动态创建一个 <a> 标签,设置其 href 属性为生成的临时 URL,并调用 click() 方法触发下载。

  5. 清理资源
    下载完成后,使用 URL.revokeObjectURL 释放生成的临时 URL,避免内存泄漏。


使用 axios 实现

如果你使用的是 axios,可以这样实现:

import axios from 'axios';

const downloadXlsx = async () => {
  try {
    // 发送请求并获取文件流
    const response = await axios.get('/api/download-xlsx', {
      responseType: 'blob', // 确保响应类型为 blob
      headers: {
        'Authorization': 'Bearer your_token_here', // 如果需要携带认证信息
      },
    });

    // 创建 Blob 对象
    const blob = new Blob([response.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });

    // 创建临时 URL
    const url = window.URL.createObjectURL(blob);

    // 创建 <a> 标签并触发下载
    const a = document.createElement('a');
    a.href = url;
    a.download = 'example.xlsx'; // 设置下载文件名
    document.body.appendChild(a); // 将 <a> 添加到 DOM 中(可选)
    a.click(); // 触发点击事件

    // 清理资源
    window.URL.revokeObjectURL(url);
    a.remove(); // 移除 <a> 标签
  } catch (error) {
    console.error('下载文件时发生错误:', error.message || '未知错误');
  }
};

// 调用函数
downloadXlsx();
responseType: 'blob' 的含义
  • responseType 是 Axios 提供的一个配置选项,用于告诉 Axios 如何解析服务器返回的数据。
  • 当设置为 'blob' 时,表示你期望服务器返回的数据是一个二进制大对象(Binary Large Object,简称 Blob)。
Blob 是什么?
  • Blob 是一种数据类型,通常用来表示不可变的、原始数据的类文件对象。
  • 它可以包含文本、图像、音频、视频等二进制数据,或者混合内容。
  • 在前端开发中,Blob 常用于处理文件下载、图片预览、或者将数据保存为文件。
为什么需要 responseType: 'blob'

当从服务器请求文件(如 Excel 文件、PDF 文件、图片等)时,服务器通常会返回二进制数据。如果直接使用默认的 responseType(通常是 'json'),Axios 会尝试将响应数据解析为 JSON 格式,这会导致错误或数据损坏。

通过设置 responseType: 'blob',你可以确保 Axios 正确地将响应数据作为二进制数据处理,而不会尝试将其解析为其他格式(如 JSON 或文本)。

代码的作用
const response = await axios({
  url: '/api/download-xlsx',
  method: 'GET',
  responseType: 'blob', // 指定响应数据为 Blob 类型
});
  1. 发起 GET 请求

    • 向 /api/download-xlsx 发起一个 GET 请求,通常用于下载文件(例如 Excel 文件)。
  2. 指定响应类型

    • 设置 responseType: 'blob',告诉 Axios 将服务器返回的数据解析为 Blob 对象。
  3. 处理响应数据

    • 返回的 response.data 将是一个 Blob 对象,代表下载的文件内容。

使用 fetch 实现

const downloadXlsx = async () => {
  try {
    // 发送请求并获取文件流
    const response = await fetch('/api/download-xlsx', {
      method: 'GET',
      headers: {
        'Authorization': 'Bearer your_token_here', // 如果需要携带认证信息
      },
    });

    // 检查响应是否成功
    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }

    // 获取 blob 数据
    const blob = await response.blob();

    // 创建临时 URL
    const url = window.URL.createObjectURL(blob);

    // 创建 <a> 标签并触发下载
    const a = document.createElement('a');
    a.href = url;
    a.download = 'example.xlsx'; // 设置下载文件名
    document.body.appendChild(a); // 将 <a> 添加到 DOM 中(可选)
    a.click(); // 触发点击事件

    // 清理资源
    window.URL.revokeObjectURL(url);
    a.remove(); // 移除 <a> 标签
  } catch (error) {
    console.error('下载文件时发生错误:', error.message || '未知错误');
  }
};

// 调用函数
downloadXlsx();
1. 定义异步函数
javascript
深色版本
const downloadXlsx = async () => {
  • async 关键字表示这是一个异步函数。
  • 异步函数允许使用 await 来等待异步操作(如网络请求)完成。

2. 发起 HTTP 请求
const response = await fetch('/api/download-xlsx', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer your_token_here', // 如果需要携带认证信息
  },
});
  • 使用 fetch 发起一个 GET 请求到 /api/download-xlsx

  • headers 部分用于设置请求头:

    • 'Authorization' 是一个常见的请求头字段,用于传递用户的身份验证信息(如 JWT Token)。
    • 如果 API 不需要认证,可以省略 headers

3. 检查响应状态
if (!response.ok) {
  throw new Error(`HTTP error! Status: ${response.status}`);
}
  • response.ok 是一个布尔值,表示 HTTP 响应的状态码是否在 200-299 范围内。
  • 如果响应失败(如 404 或 500 错误),会抛出一个错误,并终止后续代码执行。
  • 抛出的错误会被 catch 块捕获。

4. 获取 Blob 数据
const blob = await response.blob();
  • response.blob()  将响应数据解析为一个 Blob 对象。
  • Blob 是一种二进制数据类型,通常用来表示文件内容。
  • await 确保在继续执行后续代码之前,blob 数据已经被完全加载。

5. 创建临时 URL
const url = window.URL.createObjectURL(blob);
  • window.URL.createObjectURL(blob)  创建一个指向 Blob 的临时 URL。
  • 这个 URL 可以被用作 <a> 标签的 href 属性,从而触发文件下载。

6. 创建 <a> 标签并触发下载
const a = document.createElement('a');
a.href = url;
a.download = 'example.xlsx'; // 设置下载文件名
document.body.appendChild(a); // 将 <a> 添加到 DOM 中(可选)
a.click(); // 触发点击事件
  • 创建 <a> 标签

    • 使用 document.createElement('a') 动态创建一个 <a> 元素。
  • 设置 <a> 标签属性

    • href:设置为前面生成的临时 URL。
    • download:指定下载文件的名称(如 example.xlsx)。
  • 添加到 DOM 并触发点击

    • 将 <a> 标签添加到文档中(虽然不是必须,但某些浏览器可能需要这样做)。
    • 使用 a.click() 模拟用户点击,从而触发文件下载。

7. 清理资源
window.URL.revokeObjectURL(url);
a.remove();
  • 释放临时 URL

    • 使用 window.URL.revokeObjectURL(url) 释放前面创建的临时 URL,避免内存泄漏。
  • 移除 <a> 标签

    • 使用 a.remove() 从 DOM 中移除 <a> 标签,保持页面整洁。

8. 错误处理
} catch (error) {
  console.error('下载文件时发生错误:', error.message || '未知错误');
}
  • catch 块 用于捕获和处理可能出现的错误。
  • 如果在 try 块中的任何一步发生错误(如网络问题、API 返回错误等),都会进入 catch 块。
  • 使用 console.error 打印错误信息,方便调试。

9. 调用函数
downloadXlsx();
  • 最后调用 downloadXlsx 函数,触发整个文件下载流程。
适用场景
  • 下载动态生成的文件(如 Excel 表格、PDF 文档等)。
  • 需要通过 API 获取文件内容并提供给用户下载的场景。
注意事项
  1. 跨域问题

    • 如果 API 存在跨域限制,需要确保服务器配置了正确的 CORS(跨域资源共享)策略。
  2. 大文件下载

    • 对于非常大的文件,可能需要考虑分块下载或流式处理,以避免内存占用过高。
  3. 浏览器兼容性

    • fetch 和 Blob 在现代浏览器中广泛支持,但在一些老旧浏览器中可能需要使用 XMLHttpRequest 替代。

关键点说明

  1. 设置正确的 MIME 类型

    • .xlsx 文件的 MIME 类型是 application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
    • 如果后端未正确设置 MIME 类型,前端可以通过 Blob 的第二个参数手动指定。
  2. 动态文件名

    • 如果后端在响应头中提供了文件名(例如通过 Content-Disposition),可以通过解析响应头来动态设置文件名。
    • 示例:
      const contentDisposition = response.headers['content-disposition'];
      let fileName = 'example.xlsx';
      if (contentDisposition && contentDisposition.includes('filename=')) {
        fileName = contentDisposition.split('filename=')[1].split(';')[0];
      }
      
  3. 错误处理

    • 在实际开发中,务必对请求错误进行处理,例如检查 HTTP 状态码是否为 200,或者捕获网络异常。
  4. 兼容性

    • 上述方法适用于现代浏览器(如 Chrome、Firefox、Edge、Safari)。如果需要支持旧版浏览器,可能需要引入 FileSaver.js 库。

使用 FileSaver.js 简化操作

如果你希望简化文件下载逻辑,可以使用第三方库 file-saver。安装后,只需几行代码即可完成下载。

安装
npm install file-saver
使用示例
import { saveAs } from 'file-saver';
import axios from 'axios';

const downloadXlsx = async () => {
  try {
    const response = await axios({
      url: '/api/download-xlsx',
      method: 'GET',
      responseType: 'blob',
    });

    // 使用 FileSaver.js 保存文件
    saveAs(response.data, 'example.xlsx');
  } catch (error) {
    console.error('下载失败:', error);
  }
};

// 调用函数
downloadXlsx();

总结

  • 核心步骤:获取文件流 -> 转换为 Blob -> 创建临时 URL -> 触发下载 -> 清理资源。
  • 推荐工具fetchaxios 可以轻松获取文件流,FileSaver.js 可以进一步简化代码。
  • 注意事项:确保后端返回的文件流格式正确,前端设置合适的 MIME 类型和文件名。

axios 处理

try {
    const response = await axios({
      url: '/api/download-xlsx',
      method: 'GET',
      responseType: 'blob', // 一定要注意请求时加此方法
    });


getExportListApi(exportCarryData).then((res) => {
      // 创建一个a标签
      const link = document.createElement('a');
      const url = window.URL.create0bjectURL(new Blob([res.data])); 
      link.href = url;
      link.setAttribute('download', exportfile);
       
      document.body.appendChild(link); 
      link.click();
      // 销毁a标签
      document.body.removeChild(link); window.URL.revoke0bjectURL(url);

      message.success('导出成功!');
    }); 

http://www.kler.cn/a/600655.html

相关文章:

  • DIVA-GIS:一个免费的GIS分析小软件
  • 每日总结3.24
  • 如何理解 Apache Iceberg 与湖仓一体(Lakehouse)?
  • 【C++】 —— 笔试刷题day_8
  • SpringMVC 配置与应用详解
  • 《TCP/IP网络编程》学习笔记 | Chapter 22:重叠 I/O 模型
  • 基础场景-------------------(5)重载和重写的区别
  • 数据库练习
  • 笔试专题(三)
  • 思考我的未来职业
  • 力扣15.三数之和(双指针)
  • 【从零实现Json-Rpc框架】- 项目设计篇
  • ngx_conf_parse - location块
  • C# MemoryStream 中 ToArray 和 GetBuffer 的区别
  • 唯品会 unidbg 补环境 分析
  • 菜鸟的程序编程理解
  • 《大语言模型》学习笔记(四)--Transformer 模型
  • 大模型思维链COT:Chain-of-Thought Prompting Elicits Reasoningin Large Language Models
  • k8s存储介绍(二)Secret
  • 爬虫豆瓣电影