夜雨聆风学习资料网

ARTICLE · 1030513

Fesod:下一代高性能 Java Excel 读写库

Fesod:下一代高性能 Java Excel 读写库
Spring Boot 3实战案例锦集PDF电子书已更新至130篇!
🎉🎉《Spring Boot实战案例合集》目前已更新235个案例,我们将持续不断的更新。文末有电子书目录。→ 现在就订阅合集

环境:Spring Boot 3.5.0


1. 简介

Apache Fesod (Incubating) 是一个高性能、内存高效的 Java 库,用于读写电子表格文件,旨在简化开发并确保可靠性。

Apache Fesod (Incubating) 可以为开发者和企业提供极大的自由度和灵活性。我们计划在未来引入更多新功能,以持续提升用户体验和工具可用性。

名称 fesod(发音为 /ˈfɛsɒd/),是 "fast easy spreadsheet and other documents"(快速简单的电子表格和其他文档)的首字母缩写,表达了项目的起源、背景和愿景。

特性

  • 高性能读写:Apache Fesod 专注于性能优化,能够高效处理大规模电子表格数据。与一些传统的电子表格处理库相比,它可以显著减少内存消耗

  • 简单易用:该库提供了简单直观的 API,使开发者能够轻松将其集成到项目中,无论是简单的电子表格操作还是复杂的数据处理

  • 流式操作:Apache Fesod 支持流式读取,最大程度地减少一次性加载大量数据的问题。这一设计在处理数十万甚至数百万行数据时尤其重要。

2.实战案例
2.1 引入依赖

Apache Fesod 需要 Java 1.8 或更高版本。建议使用最新的 LTS 版本的 Java。我们强烈建议使用最新版本的 Apache Fesod,因为最新版本中的性能优化、错误修复和新功能将提升你的使用体验。

目前,Apache Fesod 使用 POI 作为底层包。如果您的项目已包含 POI 相关组件,您需要手动排除 POI 相关的 jar 文件。

<dependency>  <groupId>org.apache.fesod</groupId>  <artifactId>fesod-sheet</artifactId>  <version>2.0.2-incubating</version></dependency>

2.2 快速入门

读Excel

public class UserDataListener implements ReadListener<User> {  @Override  public void invoke(User user, AnalysisContext context) {    System.out.println("解析数据: %s".formatted(user));  }  @Override  public void doAfterAllAnalysed(AnalysisContext context) {    System.out.println("所有数据解析完成!");  }}String fileName = "f:/user.xlsx";// 读取电子表格文件FesodSheet.read(fileName, User.classnew UserDataListener())  .sheet()  .doRead();
输出结果
解析数据: User [id=1, name=张三, age=22, email=zhangsan@qq.com]解析数据: User [id=2, name=李四, age=33, email=lisi@gmail.com]解析数据: User [id=3, name=王五, age=44, email=wangwu@163.com]所有数据解析完成!
写Excel
// 模型类public class User {  @ExcelProperty("编号")  private Long id;  @ExcelProperty("姓名")  private String name ;  @ExcelProperty("年龄")  private Integer age;  @ExcelProperty("邮箱")  private String email;  @ExcelIgnore  private String profile ;}// 写数据private static List<Userdata() {  List<User> list = new ArrayList<>();  for (int i = 4; i <= 10; i++) {    User user = new User(        i + 0L,         "姓名 - " + i, new Random().nextInt(100),         i + "@qq.com",          "profile - " + i) ;    list.add(user) ;  }  return list;}public static void main(String[] args) {  String fileName = "f:/user.xlsx";  // 创建一个名为 "Template" 的工作表并写入数据  FesodSheet.write(fileName, User.class).sheet("Template").doWrite(data());}
生成的excel文件内容:
2.3 与Spring集成
上传Excel
public class UploadUserListener extends AnalysisEventListener<User> {  private static final Logger log = LoggerFactory.getLogger(UploadUserListener.class) ;  private final List<User> list = new ArrayList<>();  @Override  public void invoke(User user, AnalysisContext context) {    list.add(user);    // 如果数据量大,那么这里进行批次保存操作  }  @Override  public void doAfterAllAnalysed(AnalysisContext context) {    log.info("所有数据读取完成!");    // 在此处可以进行数据的存储操作,如保存到数据库  }}// Controller接口定义@PostMapping("/upload")public ResponseEntity<Stringupload(@RequestParam("file"MultipartFile file) {  if (file.isEmpty()) {    return ResponseEntity.badRequest().body("请选择一个文件上传!");  }  try {    FesodSheet.read(file.getInputStream(), User.classnew UploadUserListener()).sheet().doRead();    return ResponseEntity.ok("文件上传并处理成功!");  } catch (IOException e) {    e.printStackTrace() ;    return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("文件处理失败!");  }}
写Excel
@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("user""UTF-8").replaceAll("\\+""%20");    response.setHeader("Content-disposition""attachment;filename*=utf-8''" + fileName + ".xlsx");    FesodSheet.write(response.getOutputStream(), User.class)            .sheet("Sheet")            .doWrite(data());}
2.4 超大文件写入

导出大型数据集(如数据库转储、日志分析)时,一次性加载所有行会耗尽内存。Fesod 内部使用 Apache POI 的流式 API(SXSSF),但临时 XML 文件可能会占用大量磁盘空间。启用压缩可以减少磁盘占用,但会略微增加 CPU 消耗。

@Testpublic void largeFileWrite() {  String fileName = "largeFile" + System.currentTimeMillis() + ".xlsx";  try (ExcelWriter excelWriter = FesodSheet.write(fileName, User.class)      .registerWriteHandler(new WorkbookWriteHandler() {        @Override        public void afterWorkbookCreate(WorkbookWriteHandlerContext context) {          Workbook workbook = context.getWriteWorkbookHolder().getWorkbook();          if (workbook instanceof SXSSFWorkbook) {            ((SXSSFWorkbook) workbook).setCompressTempFiles(true);          }        }      }).build()) {    WriteSheet writeSheet = FesodSheet.writerSheet("模板").build();    // 分批写入数据 — 每次 data() 调用返回一个批次    for (int i = 0; i < 1000; i++) {      excelWriter.write(data(), writeSheet);    }  }}
架构
数据(内存中,分批处理)            Fesod          POI/SXSSF    │                              │                 │    ├─ 100 行批次 ───────────────▶ write() ──────▶ 临时 XML(压缩)    ├─ 100 行批次 ───────────────▶ write() ──────▶ 临时 XML(追加)    │  ...(1000 批次)              │                 │    └─ close() ──────────────────▶ 完成 ─────────▶ 最终 .xlsx
性能建议
  • 使用 ExcelWriter(try-with-resources)进行批量写入,而非通过 doWrite() 一次性加载全部数据

  • 在磁盘受限的环境中启用临时文件压缩

  • 根据行宽和可用内存调整批次大小(此处为 100 行)

  • 监控临时目录大小:FileUtils.getPoiFilesPath()

以上是本篇文章的全部内容,如对你有帮助帮忙点赞+转发+收藏
比Jackson性能高11倍!高性能,零依赖 JSON 脱敏库

Spring Boot 已过时的10个模式

千万级数据查询零 OOM:Spring Boot 流式查询终极实战方案

配置即接口:基于 Spring Boot 3 打造零代码动态网关组件

高级开发!实现一套通用 Controller/Service/DAO 效率提升300%

Spring Boot 二进制数据传输:从内存优化到流式处理与断点续传

一行代码搞定!Spring Boot 实现 Word 转 HTML 在线预览

告别Filter!Spring Boot 轻松实现 Request Body 重复读取

动态JSON不要再使用Map!Spring Boot + JsonNode完美解决

零侵入!Spring Boot 代理数据源详细记录SQL执行过程

企业级实践!Spring Boot 一个注解实现存储加密,支持MyBatis、JPA

相关学习资料