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

news2025/4/1 19:58:59

当后端返回一个 .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.coloradmin.cn/o/2324844.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python中multiprocessing的使用详解

1.实现多进程 代码实现&#xff1a; from multiprocessing import Process import datetime import timedef task01(name):current_timedatetime.datetime.now()start_timecurrent_time.strftime(%Y-%m-%d %H:%M:%S). "{:03d}".format(current_time.microsecond //…

强化学习与神经网络结合(以 DQN 展开)

目录 基于 PyTorch 实现简单 DQN double DQN dueling DQN Noisy DQN&#xff1a;通过噪声层实现探索&#xff0c;替代 ε- 贪心策略 Rainbow_DQN如何计算连续型的Actions 强化学习中&#xff0c;智能体&#xff08;Agent&#xff09;通过与环境交互学习最优策略。当状态空间或动…

飞书电子表格自建应用

背景 coze官方的插件不支持更多的飞书电子表格操作&#xff0c;因为需要自建应用 飞书创建文件夹 创建应用 开发者后台 - 飞书开放平台 添加机器人 添加权限 创建群 添加刚刚创建的机器人到群里 文件夹邀请群 创建好后&#xff0c;就可以拿到id和key 参考教程&#xff1a; 创…

深度学习四大核心架构:神经网络(NN)、卷积神经网络(CNN)、循环神经网络(RNN)与Transformer全概述

目录 &#x1f4c2; 深度学习四大核心架构 &#x1f330; 知识点概述 &#x1f9e0; 核心区别对比表 ⚡ 生活化案例理解 &#x1f511; 选型指南 &#x1f4c2; 深度学习四大核心架构 第一篇&#xff1a; 神经网络基础&#xff08;NN&#xff09; &#x1f330; 知识点概述…

MCP Server 实现一个 天气查询

​ Step1. 环境配置 安装 uv curl -LsSf https://astral.sh/uv/install.sh | shQuestion: 什么是 uv 呢和 conda 比有什么区别&#xff1f; Answer: 一个用 Rust 编写的超快速 (100x) Python 包管理器和环境管理工具&#xff0c;由 Astral 开发。定位为 pip 和 venv 的替代品…

Headless Chrome 优化:减少内存占用与提速技巧

在当今数据驱动的时代&#xff0c;爬虫技术在各行各业扮演着重要角色。传统的爬虫方法往往因为界面渲染和资源消耗过高而无法满足大规模数据采集的需求。本文将深度剖析 Headless Chrome 的优化方案&#xff0c;重点探讨如何利用代理 IP、Cookie 和 User-Agent 设置实现内存占用…

知识就是力量——HELLO GAME WORD!

你好&#xff01;游戏世界&#xff01; 简介环境配置前期准备好文章介绍创建头像小功能组件安装本地中文字库HSV颜色空间音频生成空白的音频 游戏UI开发加载动画注册登录界面UI界面第一版第二版 第一个游戏&#xff08;贪吃蛇&#xff09;第二个游戏&#xff08;俄罗斯方块&…

电脑连不上手机热点会出现的小bug

一、问题展示 注意: 不要打开 隐藏热点 否则他就会在电脑上 找不到自己的热点 二、解决办法 把隐藏热点打开即可

JAVA反序列化深入学习(八):CommonsCollections6

与CC5相似&#xff1a; 在 CC5 中使用了 TiedMapEntry#toString 来触发 LazyMap#get在 CC6 中是通过 TiedMapEntry#hashCode 来触发 LazyMap#get 之前看到了 hashcode 方法也会调用 getValue() 方法然后调用到其中 map 的 get 方法触发 LazyMap&#xff0c;那重点就在于如何在反…

鸿蒙项目源码-外卖点餐-原创!原创!原创!

鸿蒙外卖点餐外卖平台项目源码含文档包运行成功ArkTS语言。 我半个月写的原创作品&#xff0c;请尊重原创。 原创作品&#xff0c;盗版必究&#xff01;&#xff01;&#xff01; 原创作品&#xff0c;盗版必究&#xff01;&#xff01;&#xff01; 原创作品&#xff0c;盗版…

React程序打包与部署

===================== 推荐超级课程: 本地离线DeepSeek AI方案部署实战教程【完全版】Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战目录 为生产环境准备React应用最小化和打包环境变量错误处理部署到托管服务部署到Netlify探索高级主题:Hooks、Su…

Leetcode算法方法总结

1. 双指针法解决链表/数组题目 只要数组有序&#xff0c;就要想到双指针做法。还有二分法 回文串一般也会用到双指针&#xff0c;回文串的长度由于可能是奇数也可能是偶数&#xff0c;所以在寻找时&#xff0c;既需要寻找奇数长度的回文串&#xff0c;也需要寻找偶数长度的回文…

全包圆玛奇朵样板间亮相,极简咖啡风引领家装新潮流

在追求品质生活的当下&#xff0c;家居装修风格的选择成为了许多消费者关注的焦点。近日&#xff0c;全包圆家居装饰有限公司精心打造的玛奇朵样板间正式对外开放&#xff0c;以其独特的咖啡色系极简风格&#xff0c;为家装市场带来了一股清新的潮流。玛奇朵样板间不仅展示了全…

大数据学习(92)-spark详解

&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4dd;支持一…

免费下载 | 2025年网络安全报告

报告总结了2024年的网络安全态势&#xff0c;并对2025年的安全趋势进行了预测和分析。报告涵盖了勒索软件、信息窃取软件、云安全、物联网设备安全等多个领域的安全事件和趋势&#xff0c;并提供了安全建议和最佳实践。 一、报告背景与目的 主题&#xff1a;2024企业信息安全峰…

RCE--解法

目录 一、利用php伪协议 1.代码分析 2.过程 3.结果 ​编辑 4.防御手段 二、RCE(php中点的构造&#xff09; 1.代码分析 2.过程 一、利用php伪协议 <?php error_reporting(0); if(isset($_GET[c])){$c $_GET[c];if(!preg_match("/flag|system|php|cat|sort…

JAVA反序列化深入学习(九):CommonsCollections7与CC链总结

CC7 依旧是寻找 LazyMap 的触发点 CC6使用了 HashSet而CC6使用了 Hashtable JAVA环境 java version "1.8.0_74" Java(TM) SE Runtime Environment (build 1.8.0_74-b02) Java HotSpot(TM) 64-Bit Server VM (build 25.74-b02, mixed mode) 依赖版本 Apache Commons …

HTML元素小卖部:表单元素 vs 表格元素选购指南

刚学HTML的同学经常把表单和表格搞混&#xff0c;其实它们就像超市里的食品区和日用品区——虽然都在同一个超市&#xff0c;但用途完全不同。今天带你3分钟分清这两大元素家族&#xff01; 一、表单元素家族&#xff08;食品区&#xff1a;收集用户输入&#xff09; 1. <i…

群体智能优化算法-算术优化算法(Arithmetic Optimization Algorithm, AOA,含Matlab源代码)

摘要 算术优化算法&#xff08;Arithmetic Optimization Algorithm, AOA&#xff09;是一种新颖的群体智能优化算法&#xff0c;灵感来源于加、减、乘、除四种基本算术运算。在优化过程中&#xff0c;AOA 通过乘除操作实现全局探索&#xff0c;通过加减操作强化局部开发&#…