Spring Boot 实现 Excel 导出功能(支持前端下载 + 文件流)

news2025/4/21 14:44:44

🧠 一、为什么用 EasyExcel?

在 Java 开发中,操作 Excel 的框架主要有:

  • Apache POI(经典但慢、内存占用大)

  • JXL(老旧不维护)

  • Alibaba EasyExcel(阿里出品,性能好,写入快,注解灵活)

EasyExcel 优点:

  • 注解式开发,简单直观

  • 支持大量数据写入不 OOM

  • 支持复杂表头、样式、合并单元格

今天我们用 EasyExcel 实现后端导出 Excel 文件并支持前端下载。


📦 二、添加依赖(Maven)

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.3.2</version>
</dependency>

🧱 三、定义导出数据结构

创建一个导出用的数据对象(VO),使用 @ExcelProperty 注解指定表头名和字段顺序:

package com.example.excel.vo;

import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;

@Data
public class UserExportVO {

    @ExcelProperty(value = "用户名", index = 0)
    private String username;

    @ExcelProperty(value = "手机号", index = 1)
    private String phone;

    @ExcelProperty(value = "注册时间", index = 2)
    private String registerTime;
}

🖥️ 四、后端导出接口

创建一个下载接口,核心是将 Excel 写入 HttpServletResponse 输出流。

@GetMapping("/api/export")
public void exportUserList(HttpServletResponse response) throws IOException {
    List<UserExportVO> dataList = getMockData(); // 获取数据(或从数据库查询)

    // 设置响应头
    response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
    response.setCharacterEncoding("utf-8");

    String fileName = URLEncoder.encode("用户信息导出", "UTF-8").replaceAll("\\+", "%20");
    response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

    // 写数据到响应输出流
    EasyExcel.write(response.getOutputStream(), UserExportVO.class)
            .sheet("用户信息")
            .doWrite(dataList);
}

✅ 示例 mock 数据方法

private List<UserExportVO> getMockData() {
    List<UserExportVO> list = new ArrayList<>();
    for (int i = 1; i <= 10; i++) {
        UserExportVO user = new UserExportVO();
        user.setUsername("用户" + i);
        user.setPhone("188888888" + i);
        user.setRegisterTime("2025-04-10");
        list.add(user);
    }
    return list;
}

🌐 五、前端调用方式

方式一:直接触发下载(window.open)

window.open('/api/export', '_blank');

方式二:使用 Axios 下载 Blob

axios({
  url: '/api/export',
  method: 'GET',
  responseType: 'blob'
}).then((res) => {
  const blob = new Blob([res.data], { type: res.headers['content-type'] });
  const link = document.createElement('a');
  link.href = window.URL.createObjectURL(blob);
  link.download = '用户信息.xlsx';
  link.click();
});

🧩 六、常见问题解答

❓1. 文件名乱码?

✅ 使用 URLEncoder.encode(fileName, "UTF-8") 编码,并加 replaceAll("\\+", "%20")

❓2. 表头顺序错乱?

✅ 使用 @ExcelProperty(index = x) 指定每列的顺序。

❓3. 导出文件打不开?

✅ 确保响应头设置正确,文件类型为 application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

❓4. 导出大量数据内存溢出?

✅ EasyExcel 默认使用 streaming write,但建议分页获取数据、分批写入。


📌 七、结语

到这里,我们已经完成了:

✅ 使用 EasyExcel 构建导出数据结构
✅ 实现了后端文件流输出接口
✅ 支持前端触发导出并自动下载 Excel

📁 导出功能在企业系统中非常常见,如果你在写后台管理系统,这篇教程绝对值得收藏!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2339490.html

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

相关文章

vue 中formatter

:formatter 是前端表格组件&#xff08;如 Element UI、Vxe-Table 等&#xff09;中用于 ​​自定义单元格内容显示格式​​ 的属性。它的核心作用是&#xff1a;将后端返回的原始数据&#xff08;如编码、状态值等&#xff09;转换为更友好、更易读的文本。 这段代码 :forma…

协程?协程与线程的区别?Java是否支持协程?

一、前言 协程&#xff08;Coroutine&#xff09; 是一种轻量级的并发编程模型&#xff0c;允许在单线程内通过协作式多任务调度实现并发。由用户代码显式控制&#xff08;用户态调度而非操作系统内核调度&#xff09;&#xff0c;避免了线程上下文切换的开销&#xff0c;适合…

Muduo网络库实现 [十六] - HttpServer模块

目录 设计思路 类的设计 模块的实现 公有接口 私有接口 疑问点 设计思路 本模块就是设计一个HttpServer模块&#xff0c;提供便携的搭建http协议的服务器的方法。那么这个模块需要如何设计呢&#xff1f; 这还需要从Http请求说起。 首先从http请求的请求行开始分析&…

关于进程状态

目录 进程的各种状态 运行状态 阻塞状态 挂起状态 linux中的进程状态、 进程状态查看 S状态&#xff08;浅睡眠&#xff09; t 状态&#xff08;追踪状态&#xff09; T状态&#xff08;暂停状态&#xff09; ​编辑 kill命令手册 D状态&#xff08;深度睡眠&#…

SQL注入 01

0x01 用户、脚本、数据库之间的关系 首先客户端发出了ID36的请求&#xff0c;脚本引擎收到后将ID36的请求先代入脚本的sql查询语句Select * from A where id 36 &#xff0c; 然后将此代入到数据库中进行查询&#xff0c;查到后将返回查询到的所有记录给脚本引擎&#xff0c;接…

学习笔记:黑马程序员JavaWeb开发教程(2025.3.24)

11.2 案例-文件上传-简介 火狐浏览器可以看到文件上传传递的底层数据&#xff0c;而chrome对这一块数据进行了包装 在输出日志代码处打了一个断点&#xff0c;看服务端接收到的数据&#xff0c;在上传文件的保存地址中&#xff0c;可以看到&#xff0c;有三个临时文件&…

计算机视觉cv2入门之视频处理

在我们进行计算机视觉任务时&#xff0c;经常会对视频中的图像进行操作&#xff0c;这里我来给大家分享一下&#xff0c;cv2对视频文件的操作方法。这里我们主要介绍cv2.VideoCapture函数的基本使用方法。 cv2.VideoCapture函数 当我们在使用cv2.VideoCapture函数时&#xff…

【Linux】Rhcsa复习5

一、Linux文件系统权限 1、文件的一般权限 文件权限针对三类对象进行定义&#xff1a; owner 属主&#xff0c;缩写u group 属组&#xff0c; 缩写g other 其他&#xff0c;缩写o 每个文件针对每类访问者定义了三种主要权限&#xff1a; r&#xff1a;read 读 w&…

FFmpeg:M3U8的AES加密

1、加密用的key&#xff0c;命令&#xff1a; openssl rand 16>enc.key 2、目的是生成一个enc.key文件 生成iv openssl rand -hex 16 生成后记录下来这个字符串 3、新建一个enc.keyinfo文件&#xff0c;内容有如下三行&#xff1a; key URIenc.key的路径&#xff0c;…

VMware虚拟机走主机代理上网

&#x1f310; VMware虚拟机走主机代理上网&#x1f511; 你是否也遇到过这样的困境&#xff1f;&#x1f4a1; 在虚拟机中测试某个项目&#xff0c;却因为网络限制而寸步难行。今天&#xff0c;就让我们一起探索如何让VMware虚拟机轻松调用本机的代理上网工具&#xff0c;开启…

Cursor入门教程-JetBrains过度向

Cursor使用笔记 **前置&#xff1a;**之前博主使用的是JetBrains的IDE&#xff0c;VSCode使用比较少&#xff0c;所以会尽量朝着JetBrains的使用习惯及样式去调整。 一、设置语言为中文 如果刚上手Cursor&#xff0c;那么肯定对Cursor中的众多选项配置项不熟悉&#xff0c;这…

Mac OS系统下kernel_task占用大量CPU资源导致系统卡顿

CPU负载突然飙升&#xff0c;如截图&#xff1a; 根本原因&#xff0c;大家从各种博主上已知晓&#xff0c;现在提供自己的解决办法&#xff0c;亲测有效 一、设置开机自动禁用温度管理守护进程 1.创建脚本文件 mkdir -p ~/Scripts touch ~/Scripts/disable_thermald.sh …

宝塔面板部署 Dify-latest 最新版本

一、本地部署Windows 版本宝塔面板 宝塔面板是一款简单容易上手使用的服务器管理软件&#xff0c;它可以帮助用户方便地管理服务器以及部署网站等。 &#xff08;1&#xff09;在宝塔面板官网的下载界面&#xff0c;选择 windows 版本下载。点此进入下载 &#xff08;2&#x…

《TCP/IP网络编程》学习笔记 | Chapter 24:制作 HTTP 服务器端

《TCP/IP网络编程》学习笔记 | Chapter 24&#xff1a;制作 HTTP 服务器端 《TCP/IP网络编程》学习笔记 | Chapter 24&#xff1a;制作 HTTP 服务器端HTTP 概要理解 Web 服务器端无状态的 Stateless 协议请求消息&#xff08;Request Message&#xff09;的结构响应消息&#x…

Origin将双Y轴柱状图升级为双向分组柱状图

当变量同时存在两个数值时的可视化时&#xff0c;往往会想到用双Y轴柱状图来表达我们的数据。 双Y轴柱状图是一种在同一图表中使用左右两个Y轴的可视化形式&#xff0c;常用于展示两组量纲不同或数值范围差异较大的数据。 双向分组柱状图是一种结合了双向柱状图和分组柱状图的…

测试基础笔记第六天

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、操作系统1.什么是操作系统2.操作系统的常见分类 二、linux系统1.linux发行版本2.文件和路径3.远程连接操作常见的远程连接工具远程连接基本步骤 三、linux命令操…

Edge Impulse 训练openMV分类模型(字母+数字)

前言 使用openMV Cam H7 Plus 固件4.5.9尝试多种方式均失败&#xff08;模板匹配、ORB特征识别&#xff09;&#xff0c;还毁了一个sd卡&#xff0c;还是老老实实用Edge Impulse 训练吧 准备字母数字图片&#xff0c;使用Python生成&#xff0c;文件名要存成“A.jpg”这样&…

Linux 动、静态库的实现

前言&#xff1a;当我们写了一段代码实现了一个方法&#xff0c;如果我们不想把方法的实现过程暴露给别人看&#xff0c;可以把代码打包成一个库&#xff0c;其中形成后缀为.a的是静态库&#xff0c;后缀为.so的为动态库&#xff1b;当别人想使用你的方法时&#xff0c;把打包好…

C++11特性补充

目录 lambda表达式 定义 捕捉的方式 可变模板参数 递归函数方式展开参数包 数组展开参数包 移动构造和移动赋值 包装器 绑定bind 智能指针 RAII auto_ptr unique_ptr shared_ptr 循环引用 weak_ptr 补充 总结 特殊类的设计 不能被拷贝的类 只能在堆上创建…

PcVue助力立讯:精密制造的智能化管控实践!

PcVue助力立讯&#xff1a; 精密制造的智能化管控实践&#xff01; 客户介绍 立讯精密&#xff08;Luxshare ICT&#xff0c;股票代码&#xff1a;002475&#xff09;成立于2004年5月24日&#xff0c;专注于为消费电子产品、汽车领域产品以及企业通讯产品提供从核心零部件、…