springboot通过 EasyExcel.read()方法解析csv(excel)文件中的数据用list接收

springboot通过 EasyExcel.read()方法解析csv(excel)文件中的数据用list接收


文章目录


前言


一、EasyExcel是什么?

EasyExcel是阿里巴巴开源的一个excel处理框架,以使用简单、节省内存著称。

EasyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中。

而是从磁盘上一行行读取数据,逐个解析。

EasyExcel采用一行一行的解析模式,并将一行的解析结果以观察者模式通知处理(AnalysisEventListener)。

二、使用步骤

1.引入库

代码如下(示例):

c 复制代码
<dependencies>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>easyexcel</artifactId>
        <version>3.1.2</version>
    </dependency>
</dependencies>

2.接收数据的实体类

c 复制代码
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class UserVO extends BaseEntity {


    @ExcelIgnore
    private Integer id;


    /**
     * 编码
     */
    @ExcelIgnore
    private String code;


    /**
     * 英文名
     */
    @ExcelProperty(value = "英文名")
    private String name;

    /**
     * 中文名
     */
    @ExcelProperty(value = "中文名")
    private String nameCn;

    /**
     * 数据类型
     */
    @ExcelProperty(value = "类型")
    private String type;

    /**
     * 长度
     */
    @ExcelProperty(value = "长度")
    private Integer length;


    /**
     * 性别(0:男,1:女)(字典值需单独处理)
     */
    @ExcelProperty(value = "性别",converter = ExcelDictConverter.class)
    private Integer sex;

}

3.处理字典值ExcelDictConverter

java 复制代码
public class ExcelDictConverter implements Converter<Integer> {

    @Override
    public Class<?> supportJavaTypeKey() {
        return Number.class;
    }

    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        return CellDataTypeEnum.NUMBER;
    }


    @Override
    public Integer convertToJavaData(ReadConverterContext<?> context) {
        ReadCellData<?> readCellData = context.getReadCellData();
        String stringValue = readCellData.getStringValue();
        if ("男".equals(stringValue)) {
            return 0;
        } else if ("女".equals(stringValue)) {
            return 1;
        } else {
            return null;
        }
    }
}

4.把文件中的数据解析出来放入list中getDataImport

java 复制代码
/**
     * 把文件中的数据解析出来放入list中
     * @param file
     * @return
     */
    @Override
    public List<UserVO> getDataImport(MultipartFile file) {
        Optional.ofNullable(file).orElseThrow(() -> new BizException("文件不能为空"));
        InputStream is = null;
        List<UserVO> userVOS = new ArrayList<>();
        try {
            //获取输入流
            is = file.getInputStream();
            /**
             *  调用方法EasyExcel.read():read方法指定文件名名称、使用哪个实体类解析、使用哪个监听器类处
             *  sheet方法指定读取哪个sheet的数据
             *  doRead() 方法发起最终的读取操作
             *  其中使用内部类的方式直接创建监听器
             */

            EasyExcel.read(is, UserVO.class, new ReadListener<UserVO>() {
                @Override
                public void invoke(UserVO user, AnalysisContext context) {
                    //把解析到的每一行数据都存入list中
                    userVOS.add(user);
                }

                @Override
                public void doAfterAllAnalysed(AnalysisContext context) {

                }
            }).charset(StandardCharsets.UTF_8).excelType(ExcelTypeEnum.CSV).sheet().doRead();

        } catch (Exception e) {
            e.printStackTrace();
            String errorMsg = null;
            if (e instanceof ExcelDataConvertException) {
                ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException) e;
                String cellMsg = "";
                CellData<?> cellData = excelDataConvertException.getCellData();
                //这里有一个celldatatype的枚举值,用来判断CellData的数据类型
                CellDataTypeEnum type = cellData.getType();
                if (type.equals(CellDataTypeEnum.NUMBER)) {
                    cellMsg = cellData.getNumberValue().toString();
                } else if (type.equals(CellDataTypeEnum.STRING)) {
                    cellMsg = cellData.getStringValue();
                } else if (type.equals(CellDataTypeEnum.BOOLEAN)) {
                    cellMsg = cellData.getBooleanValue().toString();
                }
                errorMsg = String.format("excel表格:第%s行,第%s列,数据值为:%s,该数据值不符合要求,请检验后重新导入!请检查其他的记录是否有同类型的错误!", excelDataConvertException.getRowIndex() + 1, excelDataConvertException.getColumnIndex() + 1, cellMsg);
                log.error(errorMsg);
            }
            throw new BizException(errorMsg);
        } finally {
            IoUtil.close(is);
        }
        return userVOS;

    }

总结

只要excel(csv)中的表头和实体类表头上的注解说明一致,则可以方便快捷的读取文件中的数据

相关推荐
bjzhang7511 分钟前
SpringBoot开发——集成Tess4j实现OCR图像文字识别
spring boot·ocr·tess4j
flying jiang16 分钟前
Spring Boot 入门面试五道题
spring boot
小菜yh17 分钟前
关于Redis
java·数据库·spring boot·redis·spring·缓存
ahauedu1 小时前
案例分析-Stream List 中取出值最大的前 5 个和最小的 5 个值
数据结构·list
爱上语文2 小时前
Springboot的三层架构
java·开发语言·spring boot·后端·spring
荆州克莱2 小时前
springcloud整合nacos、sentinal、springcloud-gateway,springboot security、oauth2总结
spring boot·spring·spring cloud·css3·技术
serve the people2 小时前
springboot 单独新建一个文件实时写数据,当文件大于100M时按照日期时间做文件名进行归档
java·spring boot·后端
罗政7 小时前
[附源码]超简洁个人博客网站搭建+SpringBoot+Vue前后端分离
vue.js·spring boot·后端
Java小白笔记10 小时前
关于使用Mybatis-Plus 自动填充功能失效问题
spring boot·后端·mybatis
小哇66610 小时前
Spring Boot,在应用程序启动后执行某些 SQL 语句
数据库·spring boot·sql