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 导出功能。

相关推荐
KevinCyao2 小时前
java视频短信接口怎么调用?SpringBoot集成视频短信及回调处理Demo
java·spring boot·音视频
科技小花2 小时前
数据治理平台架构演进观察:AI原生设计如何重构企业数据管理范式
数据库·重构·架构·数据治理·ai-native·ai原生
一江寒逸2 小时前
零基础从入门到精通MySQL(中篇):进阶篇——吃透多表查询、事务核心与高级特性,搞定复杂业务SQL
数据库·sql·mysql
D4c-lovetrain2 小时前
linux个人心得22 (mysql)
数据库·mysql
總鑽風3 小时前
搭建Spring Boot + ELK日志平台,实现可视化日志监控
spring boot·elk·macos
阿里小阿希3 小时前
CentOS7 PostgreSQL 9.2 升级到 15 完整教程
数据库·postgresql
荒川之神3 小时前
Oracle 数据仓库雪花模型设计(完整实战方案)
数据库·数据仓库·oracle
做个文艺程序员3 小时前
MySQL安全加固十大硬核操作
数据库·mysql·安全
不吃香菜学java3 小时前
Redis简单应用
数据库·spring boot·tomcat·maven
新知图书4 小时前
搭建Spring Boot开发环境
java·spring boot·后端