Spring Boot 项目使用 EasyExcel 实现导出功能

你想要在 Spring Boot 项目中基于 EasyExcel 完整实现 Excel 导出功能,我会为你梳理一套标准化、可直接落地的实现方案,包含基础导出、字段控制、异常处理等核心内容,确保功能健壮且符合开发规范。

一、完整实现步骤

  1. 环境准备(引入依赖)
    在 pom.xml 中添加 EasyExcel 核心依赖(已兼容 Spring Boot 2.x/3.x):
xml 复制代码
<!-- EasyExcel 核心依赖 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.3.2</version>
</dependency>
<!-- Lombok(简化实体类,可选) -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
<!-- Web 依赖(Spring Boot 基础,若已引入可忽略) -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
  1. 定义导出实体类(控制导出字段)
    创建与 Excel 列映射的实体类,通过注解控制哪些字段导出、哪些忽略:
java 复制代码
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;

/**
 * 导出实体类:用户信息
 * 注解说明:
 * - @ExcelProperty:标注需要导出的字段,指定列名和列顺序
 * - @ExcelIgnore:标注需要忽略的字段(不导出)
 */
@Data
public class UserExportVO {
    // 导出:用户ID(第0列)
    @ExcelProperty(value = "用户ID", index = 0)
    private Long id;

    // 导出:用户名(第1列)
    @ExcelProperty(value = "用户名", index = 1)
    private String username;

    // 导出:用户状态(第2列)
    @ExcelProperty(value = "用户状态", index = 2)
    private String status;

    // 忽略:密码(不导出)
    @ExcelIgnore
    private String password;

    // 忽略:创建人(不导出)
    @ExcelIgnore
    private String createBy;
}
  1. 编写业务层(模拟数据查询)
    模拟从数据库查询导出数据(实际项目替换为真实 DAO/MyBatis 查询):
java 复制代码
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;

@Service
public class UserExportService {

    /**
     * 查询待导出的用户数据
     * @return 导出数据列表
     */
    public List<UserExportVO> listExportData() {
        // 模拟数据库查询结果(实际项目替换为真实查询逻辑)
        List<UserExportVO> dataList = new ArrayList<>();
        
        UserExportVO user1 = new UserExportVO();
        user1.setId(1L);
        user1.setUsername("张三");
        user1.setStatus("正常");
        user1.setPassword("123456"); // 该字段会被忽略,不导出
        
        UserExportVO user2 = new UserExportVO();
        user2.setId(2L);
        user2.setUsername("李四");
        user2.setStatus("禁用");
        user2.setCreateBy("admin"); // 该字段会被忽略,不导出
        
        dataList.add(user1);
        dataList.add(user2);
        return dataList;
    }
}
  1. 编写导出接口(核心)
    通过 HttpServletResponse 将 Excel 流直接返回给前端,实现文件下载:
java 复制代码
import com.alibaba.excel.EasyExcel;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;

@RestController
@RequestMapping("/api/export")
public class ExportController {

    @Resource
    private UserExportService userExportService;

    /**
     * 导出用户列表为 Excel 文件
     * @param response 响应对象,用于输出 Excel 流
     */
    @GetMapping("/user")
    public void exportUserExcel(HttpServletResponse response) {
        try {
            // 1. 设置响应头:告诉浏览器返回的是 Excel 文件,解决中文文件名乱码
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("UTF-8");
            // 文件名编码处理(兼容各浏览器)
            String fileName = URLEncoder.encode("用户列表_" + System.currentTimeMillis(), "UTF-8")
                    .replaceAll("\\+", "%20");
            response.setHeader("Content-Disposition", 
                    "attachment;filename*=utf-8''" + fileName + ".xlsx");

            // 2. 查询导出数据
            List<UserExportVO> exportData = userExportService.listExportData();

            // 3. 写入 Excel 并通过响应流返回
            EasyExcel.write(response.getOutputStream(), UserExportVO.class)
                    .sheet("用户数据") // Excel 工作表名称
                    .doWrite(exportData); // 写入数据

        } catch (Exception e) {
            // 异常处理:返回友好提示(实际项目建议用全局异常处理器)
            response.reset();
            response.setContentType("application/json");
            response.setCharacterEncoding("UTF-8");
            try {
                response.getWriter().write("{\"code\":500,\"msg\":\"导出失败:" + e.getMessage() + "\"}");
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }
}
  1. 全局异常处理(可选,优化体验)
    创建全局异常处理器,统一处理导出过程中的异常:
java 复制代码
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@RestControllerAdvice
public class ExportExceptionHandler {

    /**
     * 处理导出相关异常
     */
    @ExceptionHandler(Exception.class)
    public void handleExportException(HttpServletResponse response, Exception e) throws IOException {
        response.reset();
        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");
        response.getWriter().write("{\"code\":500,\"msg\":\"Excel 导出失败:" + e.getMessage() + "\"}");
    }
}

二、测试导出功能

启动 Spring Boot 项目;

访问接口:http://localhost:8080/api/export/user;

浏览器会自动下载名为「用户列表_时间戳.xlsx」的文件;

打开文件,仅包含「用户 ID」「用户名」「用户状态」3 列,password 和 createBy 字段未导出。

三、进阶优化(可选)

  1. 大数据量导出(避免内存溢出)
    若导出数据量超过 1 万条,使用「分批查询 + 数据监听器」:
java 复制代码
// 替换 Controller 中的写入逻辑
EasyExcel.write(response.getOutputStream(), UserExportVO.class)
        .sheet("用户数据")
        .doWrite(() -> {
            // 分批查询数据(示例:每次查1000条)
            return userExportService.listExportDataByPage(1, 1000);
        });
  1. 自定义 Excel 样式(表头 / 内容)
java 复制代码
// 自定义样式示例
WriteCellStyle headStyle = new WriteCellStyle();
headStyle.setFillForegroundColor(IndexedColors.LIGHT_BLUE.getIndex()); // 表头背景色
WriteFont headFont = new WriteFont();
headFont.setFontName("微软雅黑");
headFont.setFontHeightInPoints((short)12);
headStyle.setWriteFont(headFont);

// 写入时指定样式
EasyExcel.write(response.getOutputStream(), UserExportVO.class)
        .registerWriteHandler(new HorizontalCellStyleStrategy(headStyle, new WriteCellStyle()))
        .sheet("用户数据")
        .doWrite(exportData);

总结

EasyExcel 实现导出的核心是:实体类注解映射列 + 响应流输出文件,未标注 @ExcelProperty 或标注 @ExcelIgnore 的字段会被忽略;

关键配置:必须设置正确的响应头(Content-Type/Content-Disposition),解决文件类型识别和中文文件名乱码问题;

健壮性优化:添加异常处理避免接口报错,大数据量场景需分批查询写入,防止内存溢出。

以上代码可直接复制到项目中,替换 UserExportService 中的模拟数据为真实业务查询,即可快速实现生产级的 Excel 导出功能。

相关推荐
码农小卡拉12 分钟前
深入解析Spring Boot文件加载顺序与加载方式
java·数据库·spring boot
怣5017 分钟前
MySQL多表连接:全外连接、交叉连接与结果集合并详解
数据库·sql
Dragon Wu21 分钟前
Spring Security Oauth2.1 授权码模式实现前后端分离的方案
java·spring boot·后端·spring cloud·springboot·springcloud
wjhx38 分钟前
QT中对蓝牙权限的申请,整理一下
java·数据库·qt
冰暮流星1 小时前
javascript之二重循环练习
开发语言·javascript·数据库
万岳科技系统开发1 小时前
食堂采购系统源码库存扣减算法与并发控制实现详解
java·前端·数据库·算法
冉冰学姐1 小时前
SSM智慧社区管理系统jby69(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面
数据库·管理系统·智慧社区·ssm 框架
杨超越luckly2 小时前
HTML应用指南:利用GET请求获取中国500强企业名单,揭秘企业增长、分化与转型的新常态
前端·数据库·html·可视化·中国500强
Elastic 中国社区官方博客2 小时前
Elasticsearch:Workflows 介绍 - 9.3
大数据·数据库·人工智能·elasticsearch·ai·全文检索
仍然.2 小时前
MYSQL--- 聚合查询,分组查询和联合查询
数据库