EasyExcel 是阿里开源的 Excel 处理工具,适合做:
这篇教程基于:
- 包名:
com.example.springboot
实现两个最常见功能:
1. 项目结构
springboot-easyexcel-demo
├─ pom.xml
├─ src/main/java/com/example/springboot
│ ├─ SpringbootApplication.java
│ ├─ controller
│ │ └─ ExcelController.java
│ ├─ listener
│ │ └─ UserExcelListener.java
│ ├─ model
│ │ └─ UserExcelData.java
│ └─ service
│ └─ ExcelService.java
└─ src/main/resources
└─ application.yml
2. 添加依赖
文件相对路径:pom.xml
<projectxmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.5</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>springboot-easyexcel-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-easyexcel-demo</name>
<description>Spring Boot 3 EasyExcel Demo</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<!-- web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- EasyExcel -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>4.0.3</version>
</dependency>
<!-- lombok,可选 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- 测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3. 启动类
文件相对路径:src/main/java/com/example/springboot/SpringbootApplication.java
package com.example.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
publicclassSpringbootApplication{
publicstaticvoidmain(String[] args){
SpringApplication.run(SpringbootApplication.class, args);
}
}
4. 定义 Excel 对应实体
这里定义导入导出都使用的对象。
文件相对路径:src/main/java/com/example/springboot/model/UserExcelData.java
package com.example.springboot.model;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
@Data
publicclassUserExcelData{
@ExcelProperty("用户ID")
private Long id;
@ExcelProperty("用户名")
private String username;
@ExcelProperty("年龄")
private Integer age;
@ExcelProperty("邮箱")
private String email;
}
说明:
@ExcelProperty("用户ID") 表示 Excel 表头名称
5. 编写导入监听器
EasyExcel 读 Excel 时通常使用监听器模式。
文件相对路径:src/main/java/com/example/springboot/listener/UserExcelListener.java
package com.example.springboot.listener;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.example.springboot.model.UserExcelData;
import java.util.ArrayList;
import java.util.List;
publicclassUserExcelListenerimplementsReadListener<UserExcelData> {
privatefinal List<UserExcelData> dataList = new ArrayList<>();
@Override
publicvoidinvoke(UserExcelData data, AnalysisContext context){
dataList.add(data);
}
@Override
publicvoiddoAfterAllAnalysed(AnalysisContext context){
System.out.println("Excel读取完成,共 " + dataList.size() + " 条数据");
}
public List<UserExcelData> getDataList(){
return dataList;
}
}
6. 编写业务层
文件相对路径:src/main/java/com/example/springboot/service/ExcelService.java
package com.example.springboot.service;
import com.alibaba.excel.EasyExcel;
import com.example.springboot.listener.UserExcelListener;
import com.example.springboot.model.UserExcelData;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
@Service
publicclassExcelService{
publicvoidexportUsers(HttpServletResponse response)throws IOException {
List<UserExcelData> userList = mockData();
String fileName = URLEncoder.encode("用户数据", StandardCharsets.UTF_8)
.replaceAll("\\+", "%20");
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-disposition",
"attachment;filename*=utf-8''" + fileName + ".xlsx");
EasyExcel.write(response.getOutputStream(), UserExcelData.class)
.sheet("用户列表")
.doWrite(userList);
}
public List<UserExcelData> importUsers(MultipartFile file)throws IOException {
UserExcelListener listener = new UserExcelListener();
EasyExcel.read(file.getInputStream(), UserExcelData.class, listener)
.sheet()
.doRead();
return listener.getDataList();
}
private List<UserExcelData> mockData(){
List<UserExcelData> list = new ArrayList<>();
UserExcelData user1 = new UserExcelData();
user1.setId(1L);
user1.setUsername("张三");
user1.setAge(20);
user1.setEmail("zhangsan@example.com");
list.add(user1);
UserExcelData user2 = new UserExcelData();
user2.setId(2L);
user2.setUsername("李四");
user2.setAge(25);
user2.setEmail("lisi@example.com");
list.add(user2);
return list;
}
}
7. 编写控制器
文件相对路径:src/main/java/com/example/springboot/controller/ExcelController.java
package com.example.springboot.controller;
import com.example.springboot.model.UserExcelData;
import com.example.springboot.service.ExcelService;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.List;
@RestController
@RequestMapping("/excel")
publicclassExcelController{
privatefinal ExcelService excelService;
publicExcelController(ExcelService excelService){
this.excelService = excelService;
}
@GetMapping("/export")
publicvoidexport(HttpServletResponse response)throws IOException {
excelService.exportUsers(response);
}
@PostMapping("/import")
public List<UserExcelData> importExcel(MultipartFile file)throws IOException {
return excelService.importUsers(file);
}
}
8. 配置文件
文件相对路径:src/main/resources/application.yml
server:
port:8080
spring:
servlet:
multipart:
max-file-size:10MB
max-request-size:10MB
9. 启动后如何测试
启动项目后:
9.1 导出 Excel
浏览器访问:
http://localhost:8080/excel/export
效果:
9.2 导入 Excel
接口地址:
POST http://localhost:8080/excel/import
使用 Postman 或 Apifox:
- Content-Type:
multipart/form-data
Excel 表头示例:
用户ID | 用户名 | 年龄 | 邮箱
1 | 张三 | 20 | zhangsan@example.com
2 | 李四 | 25 | lisi@example.com
返回结果示例:
[
{
"id": 1,
"username": "张三",
"age": 20,
"email": "zhangsan@example.com"
},
{
"id": 2,
"username": "李四",
"age": 25,
"email": "lisi@example.com"
}
]
10. Spring Boot 3 下的注意事项
这是本篇最重要的部分。
10.1 javax 改成了 jakarta
Spring Boot 3 基于 Spring Framework 6,很多 Servlet 相关包已经从:
javax.servlet.http.HttpServletResponse
改成:
jakarta.servlet.http.HttpServletResponse
所以导出文件时一定要导入:
import jakarta.servlet.http.HttpServletResponse;
不要再写 javax.servlet.*。
10.2 JDK 版本建议 17+
Spring Boot 3 最低要求 JDK 17,因此项目里建议直接使用:
10.3 导出时注意响应头
如果文件名包含中文,建议这样处理:
String fileName = URLEncoder.encode("用户数据", StandardCharsets.UTF_8)
.replaceAll("\\+", "%20");
否则下载后的文件名可能乱码。
10.4 不要一次性把超大文件全部放内存
虽然 EasyExcel 比 POI 更省内存,但如果你在监听器里把所有数据都放进 List,大文件仍然会占用很多内存。
更合理的做法是:
比如生产环境中通常会这样做:
10.5 表头必须和实体注解匹配
如果 Excel 表头写的是:
用户名称
但你的代码是:
@ExcelProperty("用户名")
private String username;
那么这个字段可能读不到值。
所以导入时要确保:
10.6 日期、数字格式要提前约定
实际项目中 Excel 常见问题:
建议:
11. 生产环境常见优化建议
如果你要把这套代码用于实际项目,建议补充:
例如导入接口可以先校验:
if (file == null || file.isEmpty()) {
thrownew IllegalArgumentException("上传文件不能为空");
}
还可以限制只允许上传:
12. 总结
在 Spring Boot 3 中集成 EasyExcel 并不复杂,核心步骤只有 4 个:
- 使用
EasyExcel.read() + Listener 导入
最需要注意的是:
Spring Boot 3 使用 jakarta.servlet- Excel 表头要和
@ExcelProperty 对应