快速、简单避免OOM的java处理Excel工具 EasyExcel

环境

 <dependency>
	  <groupId>com.alibaba</groupId>
	  <artifactId>easyexcel</artifactId>
	  <version>2.2.5</version>
 </dependency>

创建 需要映射 excel 字段的实体

@Data
public class PatientExcel {

    @ExcelProperty("姓名")
    private String name;

    @ExcelProperty(index = 2, converter = CustomItemInfoConverter.class)
    private ItemInfo genderType;

    @ExcelProperty(index = 3)
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date birthday;

    @ExcelIgnore
    private String phone ;
}

@ExcelProperty(“姓名”) 根据 excel 列的名字 匹配 名字重复,会导致只有一个字段读取到数据

@ExcelProperty(index = 2) 根据 excel 列的的索引读取

@JsonFormat(pattern = “yyyy-MM-dd”) 序列化字段 时间格式化

@ExcelIgnore 忽略此字段 ,不参与 excel 列的匹配

@ExcelProperty(index = 2, converter= CustomItemInfoConverter.class) 自定义 序列化 excel 解析 机制

public class CustomItemInfoConverter  implements Converter<ItemInfo> {
    @Override
    public Class supportJavaTypeKey() {
        return null;
    }

    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        return null;
    }
	// 对象转换 写在这里面
    @Override
    public ItemInfo convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
        String stringValue = cellData.getStringValue();
        ItemInfo itemInfo = new ItemInfo();
        if ("男".equals(stringValue)) {
            itemInfo.setCode(1);
            itemInfo.setInput("");
            itemInfo.setName("男");
        }
        if ("女".equals(stringValue)) {
            itemInfo.setCode(1);
            itemInfo.setInput("");
            itemInfo.setName("女");
        }

        if ("本地".equals(stringValue)) {
            itemInfo.setCode(1);
            itemInfo.setInput("");
            itemInfo.setName("户籍");
        }
        if ("流动".equals(stringValue)) {
            itemInfo.setCode(2);
            itemInfo.setInput("");
            itemInfo.setName("非户籍");
        }
        return itemInfo;
    }
 }

解析excel

 /**
     * 解析excel 内容转换成 entity
     *
     * @param file
     * @param index
     * @return
     */
    protected List<PatientExcel> readAll(File file, int index) {

        log.info("开始读取Excel文件: {}", file.getAbsolutePath());
        List<PatientExcel> all = Lists.newArrayList();
        ExcelReader excelReader = EasyExcel.read(file, PatientExcel.class, new PatientListener(all::addAll)).build();
        ReadSheet readSheet = EasyExcel.readSheet(0).headRowNumber(index).build();
        excelReader.read(readSheet);
        excelReader.finish();
        log.info("已读取Excel文件: {} ", file.getAbsolutePath());
        return all;
    }

    /**
     * 解析excel 的监听器
     */
    private class PatientListener extends AnalysisEventListener<PatientExcel> {

        private List<PatientExcel> list = new ArrayList<>();
        private Consumer<List<PatientExcel>> consumer;

        public PatientListener(Consumer<List<PatientExcel>> consumer) {
            this.consumer = consumer;
        }

        /**
         * 这个每一条数据解析都会来调用
         *
         * @param data    one row value. Is is same as {@link AnalysisContext#readRowHolder()}
         * @param context
         *  BATCH_COUNT 界定符 ,例子 假如我只需要读到200条数据 BATCH_COUNT=200
         */ 
        @Override
        public void invoke(PatientExcel data, AnalysisContext context) {
            if (list.size() >= BATCH_COUNT) return;

            list.add(data);
        }

        /**
         * 所有数据解析完成了 都会来调用
         *
         * @param context
         */
        @Override
        public void doAfterAllAnalysed(AnalysisContext context) {
            // 这里也要保存数据,确保最后遗留的数据也存储到数据库
            this.consumer.accept(list);
            log.info("所有数据解析完成!");
        }

        /**
         * 报错 调用
         *
         * @param exception
         * @param context
         * @throws Exception
         */
        @Override
        public void onException(Exception exception, AnalysisContext context) throws Exception {
            log.error("解析失败,但是继续解析下一行:{}", exception.getMessage());
            // 如果是某一个单元格的转换异常 能获取到具体行号
            // 如果要获取头的信息 配合invokeHeadMap使用
            if (exception instanceof ExcelDataConvertException) {
                ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException) exception;
                log.error("第{}行,第{}列解析异常", excelDataConvertException.getRowIndex(),
                        excelDataConvertException.getColumnIndex());
            }
        }
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值