Easyexcel 简介与使用

alilibaba 开源的读写 excel 比较好用的工具类,相较之前常用的 POI 使用方式更简便,且防止了 OOM 产生

Github 项目地址:https://github.com/alibaba/easyexcel

POM 依赖

<!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>2.2.7</version>
</dependency>

写入 Excel

/** 根据实体类自动生成表头*/
@Data
// 忽略所有没有添加注释的字段
@ExcelIgnoreUnannotated
public class DemoData {
    // 其中的值就是表头
    @ExcelProperty("字符串")
    private String string;
    @ExcelProperty("日期")
    private Date date;
    @ExcelProperty("数字")
    private Double doubleData;
    // 忽略这个字段
    @ExcelIgnore
    private String ignore;
}

// 写入 Excel
public void simpleWrite() {
    String fileName = "路径//....xlsx";
    /** 写法一 */
    // 指定用哪个 class 去写,写到第一个 sheet 并命名为模板。文件流会自动关闭(导出为 03 版 excel 需传入 excelType 参数)
    EasyExcel.write(fileName, DemoData.class).sheet("模板").doWrite(data());

    /** 写法二(两种写法效果完全一样)*/
    ExcelWriter excelWriter = null;
    try {
        excelWriter = EasyExcel.write(fileName, DemoData.class).build();
        WriteSheet writeSheet = EasyExcel.writerSheet("模板").build();
        excelWriter.write(data(), writeSheet);
    } finally {
        // 手动关闭流
        if (excelWriter != null) {
            excelWriter.finish();
        }
    }
}

写入 Excel 时做数据转换

// 自定义转换器
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.converters.WriteConverterContext;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.data.WriteCellData;

import java.util.HashMap;
import java.util.Map;

public class UserIdConverter implements Converter<Integer> {

    // 自定义的转出规则 map
    private static Map<Integer, String> converRule = new HashMap<>();
    static {
        converRule.put(2, "哈啊啊");
        converRule.put(3, "哈呀呀");
    }

    @Override
    public Class<?> supportJavaTypeKey() {
        // 实体类中属性的类
        return Integer.class;
    }

    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        // Excel 中数据对应的类
        return CellDataTypeEnum.STRING;
    }

    /**
     * 将实体类属性值转换为数据表中的数据
     *
     * @param value 实体类属性值
     * @return 包含了数据表中转换后的数据
     */
    @Override
    public WriteCellData<?> convertToExcelData(Integer value, ExcelContentProperty contentProperty
    	, GlobalConfiguration globalConfiguration) {
        return new WriteCellData<>(converRule.get(value) == null ? "" : converRule.get(value));
    }
}

// 在实体类属性值上指定转换器
@ExcelProperty(value = "用户ID", converter = UserIdConverter.class)
private Integer id;

读取 Excel

读取一个 Excel 并将其中的所有数据存储到数据库中

  1. 编写监听器
// DemoDataListener 不能被 spring 管理,每次读取 excel 时都要 new ,里面用到 bean 时可以通过构造方法传进去
@Slf4j
@Data
public class DemoDataListener extends AnalysisEventListener<DemoData> {
    
    // 每隔 5 条存储数据库,实际使用中可以 3000 条,然后清理 list ,方便内存回收
    private static final int BATCH_COUNT = 5;
    
    // 定义数据存储 list
    List<DemoData> list = new ArrayList<DemoData>();

    // 通过构造方法将这个被 Spring 管理的类对象传进来并赋值
    private DemoDAO demoDAO;
    
    public DemoDataListener(DemoDAO demoDAO) {
        this.demoDAO = demoDAO;
    }
    
    /**
     * 存储数据库的方法
     */
    private void saveData() {
        log.info("{} 条数据,开始存储数据库!", list.size());
        demoDAO.save(list);
        log.info("存储数据库成功!");
    }
    
    /**
     * excel 表中的每一条数据解析时都会来调用 invoke 方法,通过表头名和属性名对应上来构造数据
     */
    @Override
    public void invoke(DemoData data, AnalysisContext context) {
        log.info("解析到一条数据:{}", data);
        list.add(data);
        // 达到 BATCH_COUNT 时去存储一次数据库,防止过多数据在内存造成 OOM
        if (list.size() >= BATCH_COUNT) {
            saveData();
            // 存储完成后清理 list
            list.clear();
        }
    }
    
    /**
     * 所有数据都解析完成后会来调用
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 确保最后不满 BATCH_COUNT 条数的数据也存储到数据库
        saveData();
        log.info("所有数据存储完毕!");
    }
}
  1. 程序中读取 excel
DemoDataListener demoDataListener = new DemoDataListener();
EasyExcel.read(file, demoDataListener).sheet().headRowNumber(0).doRead();
  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值