什么是 FastExcel
FastExcel 是由原 EasyExcel 作者创建的最新作品。在 2023 年作者从阿里离职后,随着阿里宣布停止更新 EasyExcel,原作者决定继续维护和升级这个项目。在重新开始时,选择为它起名为 FastExcel,以突出这个框架在处理 Excel 文件时的高性能表现,而不仅仅是简单易用。
FastExcel 的特点
- 完全兼容原 EasyExcel 的所有功能和特性,这使得用户可以无缝过渡。
- 从 EasyExcel 迁移到 FastExcel只需简单地更换包名和 Maven 依赖即可完成升级。
- 在功能上,比 EasyExcel 提供更多创新和改进。
- FastExcel1.0.0 版本新增了读取 Excel 指定行数和将 Excel 转换为 PDF 的功能。
主要特征
- 高性能读写:FastExcel 专注于性能优化,能够高效处理大规模的 Excel 数据。相比一些传统的 Excel 处理库,它能显著降低内存占用。
- 简单易用:该库提供了简洁直观的 API,使得开发者可以轻松集成到项目中,无论是简单的 Excel 操作还是复杂的数据处理都能快速上手。
- 流式操作:FastExcel 支持流式读取,将一次性加载大量数据的问题降到最低。这种设计方式在处理数十万甚至上百万行的数据时尤为重要。
项目环境
- Spring Boot: 3.4.x
- FastExcel: 1.1.0
- JDK: 17
- Maven: 构建工具
引入依赖
<dependency>
<groupId>cn.idev.excel</groupId>
<artifactId>fastexcel</artifactId>
<version>1.1.0</version>
</dependency>
配置FastExcel
FastExcel无需特别复杂的配置,直接通过依赖注入到Spring上下文即可。
代码示例
1、启动类
package com.example.fastexcel;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class FastexcelApplication {
public static void main(String[] args) {
SpringApplication.run(FastexcelApplication.class, args);
}
}
2、配置文件
application.yml
spring:
servlet:
multipart:
max-file-size: 100MB
max-request-size: 100MB
3、实体类
在使用 FastExcel 进行 Excel 文件的读写操作之前,需要定义一个实体类,该类中的每个属性对应 Excel 中的一列。使用@ExcelProperty注解来指定列名。
package com.example.fastexcel.entity;
import cn.idev.excel.annotation.ExcelProperty;
public class User {
@ExcelProperty("编号")
private Integer id;
@ExcelProperty("名字")
private String name;
@ExcelProperty("年龄")
private Integer age;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
4、数据监听器
FastExcel 通过事件监听器实现 Excel 文件的逐行读取,这对于处理大文件尤为重要,因为它可以避免内存溢出的问题。下面是一个事件监听器的示例,它在读取每行数据时将数据添加到列表中,并在所有数据读取完成后执行一些操作。
package com.example.fastexcel.listener;
import cn.idev.excel.context.AnalysisContext;
import cn.idev.excel.event.AnalysisEventListener;
import java.util.ArrayList;
import java.util.List;
public class BaseExcelListener<T> extends AnalysisEventListener<T> {
// 定义一个数据列表,用于存储读取到的每一行数据
private List<T> dataList = new ArrayList<>();
//定义一个计数器
private int count = 0;
@Override
public void invoke(T t, AnalysisContext analysisContext) {
// 添加读取到的每一行数据到数据列表
dataList.add(t);
//计数器自增
count++;
if (count % 10000 == 0) {
System.out.println("已读取 " + count + " 条数据");
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
// 读取完成后,打印数据列表的大小
System.out.println("读取完成,共读取了 " + dataList.size() + " 条数据");
}
public List<T> getDataList() {
return dataList;
}
}
5、控制器
package com.example.fastexcel.controller;
import cn.idev.excel.FastExcel;
import com.example.fastexcel.entity.User;
import com.example.fastexcel.listener.BaseExcelListener;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
@Controller
public class ExcelController {
/**
* 导出Excel
*
* @param response
* @throws IOException
*/
@GetMapping("/download")
public void download(HttpServletResponse response) throws IOException {
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
String fileName = URLEncoder.encode("test", "UTF-8");
response.setHeader("Content-disposition",
"attachment;filename*=utf-8''" + fileName + ".xlsx");
Long start = System.currentTimeMillis();
// 写入数据
FastExcel.write(response.getOutputStream(), User.class)
.sheet("模板")
.doWrite(buildData());
Long end = System.currentTimeMillis();
System.out.println("耗时:" + (end - start));
}
/**
* 导入Excel
*
* @param file
* @return
*/
@PostMapping("/upload")
public ResponseEntity<String> upload(@RequestParam("file") MultipartFile file) {
if (file.isEmpty()) {
return ResponseEntity.badRequest().body("请选择一个文件上传!");
}
try {
Long start = System.currentTimeMillis();
BaseExcelListener<User> baseExcelListener = new BaseExcelListener<>();
FastExcel.read(file.getInputStream(), User.class, baseExcelListener).sheet().doRead();
List<User> dataList = baseExcelListener.getDataList();
System.out.println(dataList.size());
Long end = System.currentTimeMillis();
return ResponseEntity.ok("文件上传并处理成功!耗时:" + (end - start) + "ms");
} catch (IOException e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("文件处理失败!");
}
}
private List<User> buildData() {
List<User> list = new ArrayList<>();
for (int i = 0; i < 1000000; i++) {
User user = new User();
user.setId(i);
user.setAge(88);
user.setName("张三" + i);
list.add(user);
}
return list;
}
}
5、测试:
下载地址::http://127.0.0.1:8080/download
上传地址:127.0.0.1:8080/upload
下载地址直接复制即可
上传需要使用postMan等测试工具
参考:
6、总结
通过集成FastExcel,我们可以更高效地实现Excel文件的读写操作。它简单易用,性能优秀,是Spring Boot项目中处理Excel任务的理想选择。希望本文能为你在实际项目中应用FastExcel提供帮助!
源码地址:
标签:FastExcel,return,读取,Spring,Excel,源码,import,public From: https://www.cnblogs.com/chengxuyuanxiaoyang/p/18686367https://github.com/Yning2333/SpringBoot3-LearningLabs
https://github.com/Yning2333/SpringBoot3-LearningLabs/tree/main/spring-boot3-fastexcel