Spring Boot3集成FastExcel实现百万级Excel导入(附源码)

什么是 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提供帮助!

源码地址:

https://github.com/Yning2333/SpringBoot3-LearningLabs
https://github.com/Yning2333/SpringBoot3-LearningLabs/tree/main/spring-boot3-fastexcel

posted @   程序员小羊  阅读(119)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 推荐几款开源且免费的 .NET MAUI 组件库
· 易语言 —— 开山篇
· 实操Deepseek接入个人知识库
· Trae初体验
点击右上角即可分享
微信分享提示