easyexcel实现excel读取

EasyExcel 实现 Excel 读取的核心思想是基于事件驱动的监听器模式。它不会一次性将所有数据加载到内存,而是逐行解析,并通过回调函数(监听器)来处理每一行数据,非常适合处理大数据量 Excel 文件。

以下是使用 EasyExcel 读取 Excel 的基本步骤和关键代码示例:


1. 引入依赖

首先,确保你的项目(如 Maven 或 Gradle)中引入了 EasyExcel 的依赖。

Maven 依赖示例:

xml 复制代码
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.3.3</version> </dependency>

2. 创建 Excel 数据对应的实体类 (Model)

创建一个 Java 类来映射 Excel 中的每一行数据。使用 @ExcelProperty 注解来指定属性对应 Excel 的哪一列。

java 复制代码
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data; // 推荐使用 Lombok 简化代码

@Data // 自动生成 Getter/Setter 等方法
public class DemoData {

    // 对应 Excel 的第一列(索引从 0 开始)
    @ExcelProperty(index = 0)
    private String name;

    // 对应 Excel 的第二列
    @ExcelProperty(index = 1)
    private Integer age;

    // 也可以通过列名来映射(如果 Excel 有表头)
    @ExcelProperty(value = "出生日期")
    private Date birthday;

    // 其它属性...
}

3. 实现数据读取监听器 (Listener)

创建一个监听器类,继承 AnalysisEventListener<T>,其中 T 就是你的实体类(如 DemoData)。在这个监听器中处理解析到的数据。

java 复制代码
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import java.util.ArrayList;
import java.util.List;

public class DemoDataListener extends AnalysisEventListener<DemoData> {

    /** 批量处理的数据量,可根据实际业务调整 */
    private static final int BATCH_COUNT = 100;
    private List<DemoData> cachedDataList = new ArrayList<>();

    /**
     * 每解析一行数据,这个方法会被调用一次
     * @param data 解析到的数据对象
     * @param context 分析上下文
     */
    @Override
    public void invoke(DemoData data, AnalysisContext context) {
        // System.out.println("解析到一条数据: " + data);
        cachedDataList.add(data);
        // 达到批量处理数量时,进行数据存储操作(例如:批量插入数据库)
        if (cachedDataList.size() >= BATCH_COUNT) {
            saveData();
            // 清理缓存列表
            cachedDataList = new ArrayList<>(BATCH_COUNT); 
        }
    }

    /**
     * 所有数据解析完成后,这个方法会被调用
     * @param context 分析上下文
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 处理剩余未达到 BATCH_COUNT 的数据
        saveData();
        System.out.println("所有数据解析完成!");
    }

    /**
     * 假设的批量存储数据方法
     */
    private void saveData() {
        // 在这里进行业务处理,比如将 cachedDataList 批量写入数据库
        System.out.println("批量存储数据" + cachedDataList.size() + "条!");
    }
}

4. 执行读取操作

使用 EasyExcel.read() 方法启动读取流程。

示例:异步(推荐)

这是处理大文件推荐的方式,它利用监听器模式逐行处理数据,内存占用小。

java 复制代码
import com.alibaba.excel.EasyExcel;
import java.io.File;

public class ExcelReadExample {

    public static void simpleRead(String fileName) {
        // fileName 可以是文件路径、File 对象、InputStream 等

        EasyExcel.read(
                fileName, 
                DemoData.class, // 实体类
                new DemoDataListener() // 监听器
        )
        .sheet() // 默认读取第一个 Sheet
        .headRowNumber(1) // 从 Excel 的第几行开始读取数据(默认表头占一行,即从第 2 行开始是数据)
        .doRead(); 

        System.out.println("读取任务已提交,等待监听器处理完成...");
    }
}

示例:同步读取 (不推荐大文件使用)

如果文件较小,也可以使用同步读取,它会一次性返回所有数据到一个 List 中,但可能会占用大量内存。

java 复制代码
import com.alibaba.excel.EasyExcel;
import java.util.List;
import java.util.Map;

public class ExcelReadExample {

    public static void synchronousRead(String fileName) {
        
        // 1. 读取为实体类列表
        List<DemoData> list = EasyExcel.read(fileName)
                .head(DemoData.class)
                .sheet()
                .doReadSync(); // 同步读取

        // 2. 也可以读取为 List<Map<Integer, String>>,不指定实体类
        List<Map<Integer, String>> listMap = EasyExcel.read(fileName)
                .sheet()
                .doReadSync();
                
        // 处理数据...
        System.out.println("同步读取到数据条数:" + list.size());
    }
}

总结要点:

  1. Model (实体类) :使用 @ExcelProperty 映射列。
  2. Listener (监听器) :实现 AnalysisEventListener,在 invoke() 中处理每行数据,在 doAfterAllAnalysed() 中进行收尾工作。
  3. Read (读取) :使用 EasyExcel.read() 指定文件、实体类和监听器,调用 .sheet().doRead().doReadSync() 启动。

使用 监听器模式(异步读取) 是 EasyExcel 推荐的方式,因为它能有效地避免 OOM(内存溢出)问题。

相关推荐
寻星探路4 小时前
【深度长文】万字攻克网络原理:从 HTTP 报文解构到 HTTPS 终极加密逻辑
java·开发语言·网络·python·http·ai·https
曹牧6 小时前
Spring Boot:如何测试Java Controller中的POST请求?
java·开发语言
爬山算法7 小时前
Hibernate(90)如何在故障注入测试中使用Hibernate?
java·后端·hibernate
kfyty7257 小时前
集成 spring-ai 2.x 实践中遇到的一些问题及解决方案
java·人工智能·spring-ai
猫头虎8 小时前
如何排查并解决项目启动时报错Error encountered while processing: java.io.IOException: closed 的问题
java·开发语言·jvm·spring boot·python·开源·maven
李少兄8 小时前
在 IntelliJ IDEA 中修改 Git 远程仓库地址
java·git·intellij-idea
忆~遂愿8 小时前
ops-cv 算子库深度解析:面向视觉任务的硬件优化与数据布局(NCHW/NHWC)策略
java·大数据·linux·人工智能
小韩学长yyds8 小时前
Java序列化避坑指南:明确这4种场景,再也不盲目实现Serializable
java·序列化
仟濹8 小时前
【Java基础】多态 | 打卡day2
java·开发语言