点击下载《Java SpringBoot使用EasyExcel导入导出Excel文件(源代码)》
在 Java Spring Boot 项目中,导入(读取)和导出(写入) Excel 文件是一项常见的需求。EasyExcel 是阿里巴巴开源的一个用于简化 Java 环境下 Excel 文件读取和写入操作的库。相比于传统的 Apache POI,EasyExcel 在性能和易用性方面进行了优化,特别适用于处理大规模 Excel 文件。
1. EasyExcel 介绍
1.1 EasyExcel 的特点
特性/方面 | 详细说明 |
---|---|
基于事件驱动的解析 | 采用 SAX 解析方式,通过事件驱动逐行读取 Excel 数据,避免将整个文件加载到内存中,降低内存消耗。 |
内存友好 | 由于逐行读取和处理数据,内存占用极低,适合处理大型 Excel 文件,避免内存溢出问题。 |
简洁易用的 API | 提供高度封装的 API,通过注解(如 @ExcelProperty )轻松实现 Java 对象与 Excel 列的映射,减少样板代码的编写。 |
支持多种数据格式 | 支持常见的 Excel 数据格式,包括 .xlsx 和 .xls 文件,并支持自定义数据格式转换。 |
丰富的功能 | 支持读取和写入 Excel 文件、自定义转换器、多工作表操作、注解支持、异常处理等。 |
高性能 | 在处理大规模数据时表现出色,能够显著提高数据导入和导出的效率。 |
社区活跃 | 作为阿里巴巴开源项目,拥有活跃的社区和及时的更新,能够及时修复问题和添加新功能。 |
依赖其他库 | 依赖于 cglib 和其他一些库,如果项目中已经使用了不同版本的这些库,可能会导致版本冲突。 |
学习曲线 | 虽然 API 简洁,但对于不熟悉事件驱动编程或注解映射的开发者,可能需要一定的学习成本。 |
功能相对有限 | 与 Apache POI 相比,EasyExcel 对公式、图表、样式等复杂功能的支持相对较少。 |
灵活性高 | 支持自定义数据转换器、多工作表操作等功能,提供了高度的灵活性以满足不同的业务需求。 |
1.2 EasyExcel 的优点
优点 | 详细说明 |
---|---|
内存效率高 | 采用事件驱动和逐行读取的方式,内存占用低,适合处理大型 Excel 文件,避免内存溢出问题。 |
性能优越 | 在处理大规模数据时具有更高的性能,能够显著减少处理时间,提高数据导入和导出效率。 |
易用性强 | 通过简洁的 API 和注解支持,简化了 Excel 数据的读取和写入操作,减少了代码量,提高了开发效率。 |
灵活性高 | 支持自定义数据转换器、多工作表操作等功能,能够满足不同的业务需求。 |
社区支持 | 作为开源项目,拥有活跃的社区和及时的更新,能够及时响应用户需求和问题。 |
1.3 EasyExcel 的缺点
缺点 | 详细说明 |
---|---|
功能相对有限 | 与 Apache POI 相比,EasyExcel 对公式、图表、样式等复杂功能的支持较少。 |
依赖其他库 | 依赖于 cglib 和其他一些库,可能导致版本冲突,需要注意依赖管理。 |
学习曲线 | 对于不熟悉事件驱动编程或注解映射的开发者,可能需要一定的学习成本。 |
社区规模 | 虽然拥有活跃的社区,但与 Apache POI 相比,社区规模相对较小,可能在某些情况下获取帮助的渠道相对有限。 |
2. EasyExcel使用
2.1 引入 EasyExcel 依赖
首先,需要在 pom.xml
中引入 EasyExcel 的依赖:
xml
<dependencies>
<!-- Spring Boot Starter Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- EasyExcel 依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel-core</artifactId>
<version>3.1.2</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version> <!-- 请检查最新版本 -->
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
<!-- 其他依赖 -->
</dependencies>
2.2 定义数据模型
使用 EasyExcel 导入导出数据时,需要定义与 Excel 列对应的 Java 类,并使用注解标注列信息。
java
package com.yyqq.exceldemo.model;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
@Data
public class UserData {
@ExcelProperty("编号") // Excel 中的列名
private Integer id;
@ExcelProperty("姓名")
private String name;
@ExcelProperty("年龄")
private Integer age;
@ExcelProperty("邮箱")
private String email;
}
说明:
@Data
:Lombok 提供的注解,用于自动生成 getter、setter、toString 等方法。@ExcelProperty
:指定 Excel 中对应的列名。
2.3 Excel 导入导出Controller类
java
package com.yyqq.exceldemo.controller;
import com.alibaba.excel.EasyExcel;
import com.yyqq.exceldemo.model.UserData;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@RestController
public class ExcelController {
/**
* 导入execl文件
*/
@GetMapping("/export")
public ResponseEntity<byte[]> exportExcel() {
String fileName = "用户数据.xlsx";
List<UserData> userList = generateUserData();
// EasyExcel 写入到字节数组
byte[] bytes = exportToExcel(userList);
// 设置响应头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentDispositionFormData("attachment", fileName);
return ResponseEntity.ok()
.headers(headers)
.body(bytes);
}
@PostMapping("/import")
public String importExcel(@RequestParam("file") MultipartFile file) {
try {
InputStream inputStream = file.getInputStream();
// 使用 EasyExcel 读取 Excel 数据
List<UserData> userList = EasyExcel.read(inputStream)
.head(UserData.class)
.sheet()
.doReadSync();
// 处理导入的数据,例如保存到数据库
processUserData(userList);
return "导入成功,共导入 " + userList.size() + " 条数据";
} catch (Exception e) {
e.printStackTrace();
return "导入失败: " + e.getMessage();
}
}
/**
* 模拟生产用户数据
* @return
*/
private List<UserData> generateUserData() {
List<UserData> list = new ArrayList<>();
for (int i = 1; i <= 100; i++) {
UserData user = new UserData();
user.setId(i);
user.setName("用户" + i);
user.setAge(20 + i % 30);
user.setEmail("user" + i + "@example.com");
list.add(user);
}
return list;
}
/**
* 将数据导出至byte数组中
*/
private byte[] exportToExcel(List<UserData> userList) {
// 使用 EasyExcel 写入 Excel 到字节数组
ByteArrayOutputStream out = new ByteArrayOutputStream();
EasyExcel.write(out, UserData.class)
.sheet("用户数据")
.doWrite(userList);
return out.toByteArray();
}
/**
* 导入数据方法
*/
private List<UserData> importFromExcelWithPOI(MultipartFile file) {
List<UserData> userList = new ArrayList<>();
try (InputStream inputStream = file.getInputStream();
Workbook workbook = WorkbookFactory.create(inputStream)) {
Sheet sheet = workbook.getSheetAt(0);
Iterator<Row> iterator = sheet.iterator();
// 跳过表头
if (iterator.hasNext()) {
iterator.next();
}
while (iterator.hasNext()) {
Row row = iterator.next();
UserData user = new UserData();
user.setId((int) row.getCell(0).getNumericCellValue());
user.setName(row.getCell(1).getStringCellValue());
user.setAge((int) row.getCell(2).getNumericCellValue());
user.setEmail(row.getCell(3).getStringCellValue());
userList.add(user);
}
} catch (Exception e) {
e.printStackTrace();
}
return userList;
}
private void processUserData(List<UserData> userList) {
// 这里可以添加将数据保存到数据库的逻辑
// 例如使用 JPA 或 MyBatis 等持久层框架
userList.forEach(user -> {
// 模拟保存操作
System.out.println("保存用户: " + user);
});
}
}
2.4 编写测试html文件
在src/main/resources/static目录创建import.html文件,代码如下:
html
<!DOCTYPE html>
<html>
<head>
<title>Excel 导入</title>
</head>
<body>
<h1>导入 Excel 文件</h1>
<form method="POST" enctype="multipart/form-data" action="/import">
<input type="file" name="file" accept=".xlsx, .xls" />
<button type="submit">上传</button>
</form>
</body>
</html>
export导出接口说明
- 导出接口 :
/export
接口返回 Excel 文件。 - generateUserData() 方法:生成示例用户数据。
- exportToExcel() 方法
- 使用 EasyExcel 的
write
方法将数据写入ByteArrayOutputStream
。 sheet("用户数据")
指定工作表名称。doWrite(userList)
写入数据列表。
- 使用 EasyExcel 的
- 启动 Spring Boot 应用后,访问
http://localhost:8080/export
,即可下载生成的 Excel 文件。
import导入接口说明
- 导入接口 :
/import
接口接收 Excel 文件并处理。 - 导入逻辑
- 使用 EasyExcel 的
read
方法读取上传的 Excel 文件。 head(UserData.class)
指定数据模型类。sheet()
指定读取的工作表。doReadSync()
同步读取数据。
- 使用 EasyExcel 的
- processUserData() 方法:处理导入的数据,例如保存到数据库。
- 使用Postman调用接口
- 或者直接在浏览器中输入地址:http://127.0.0.1:8080/import.html,然后上传一个excel文件:
结果如下:
3. 总结
EasyExcel 是一个高性能、易用性强的 Java 库,适用于处理大规模 Excel 文件的导入和导出操作。其基于事件驱动的解析方式、内存友好的特性以及简洁的 API 使得开发者能够高效地完成数据处理任务。然而,在需要处理复杂 Excel 功能(如公式、图表、样式等)时,EasyExcel 的功能可能相对有限。对于大多数常见的 Excel 操作需求,EasyExcel 是一个非常不错的选择,但在特定场景下,可能需要结合使用其他库或工具。