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)中的表头和实体类表头上的注解说明一致,则可以方便快捷的读取文件中的数据

相关推荐
后端小张6 小时前
基于飞算AI的图书管理系统设计与实现
spring boot
考虑考虑1 天前
Jpa使用union all
java·spring boot·后端
葡萄城技术团队1 天前
从100秒到10秒的性能优化,你真的掌握 Excel 的使用技巧了吗?
excel
阿杆1 天前
同事嫌参数校验太丑,我直接掏出了更优雅的 SpEL Validator
java·spring boot·后端
昵称为空C2 天前
SpringBoot3 http接口调用新方式RestClient + @HttpExchange像使用Feign一样调用
spring boot·后端
麦兜*2 天前
MongoDB Atlas 云数据库实战:从零搭建全球多节点集群
java·数据库·spring boot·mongodb·spring·spring cloud
麦兜*2 天前
MongoDB 在物联网(IoT)中的应用:海量时序数据处理方案
java·数据库·spring boot·物联网·mongodb·spring
汤姆yu2 天前
基于springboot的毕业旅游一站式定制系统
spring boot·后端·旅游
计算机毕业设计木哥2 天前
计算机毕设选题推荐:基于Java+SpringBoot物品租赁管理系统【源码+文档+调试】
java·vue.js·spring boot·mysql·spark·毕业设计·课程设计
凯子坚持 c2 天前
精通 Redis list:使用 redis-plus-plus 的现代 C++ 实践深度解析
c++·redis·list