集成EasyExcel自定义封装读取解析Excel文件流数据

1、读取Excel,暂只支持读取文件流方式,之后按需扩展

使用说明:现封装读取excel方法只支持读取业务规定的模版结构,第一列为中文表头,第二列是数据库字段,模版由前端提供,用户下载后填充数据。
        默认读取第二列作为key(数据字段)。

实现方式:以行维度读取数据后组装集合,使用反射装配数据结构,返回泛型集合List

2、代码

      <dependency>
          <groupId>com.alibabagroupId>
          <artifactId>easyexcelartifactId>
          <version>3.1.2version>
      dependency>
      <dependency>
		<groupId>cn.hutoolgroupId>
		<artifactId>hutool-allartifactId>
		<version>5.8.0version>
		<scope>compilescope>
	dependency>
/**
 * excelReader监听器
 *
 * @author smallNorth_Lee
 * @date 2022/12/1
 */
public class ExcelReadListener extends AnalysisEventListener<Map<Integer, String>> {

    /**
     * 表头数据(存储所有的表头数据)
     */
    private final List<Map<Integer, String>> headList = new ArrayList<>();
    /**
     * 数据体
     */
    private final List<Map<Integer, String>> dataList = new ArrayList<>();

    /**
     * 默认invoke从excel第二行开始读数据,第一行为中文表头,第二行为字段名称
     * 如只需要从第一行读取,请使用invokeHeadMap方法
     */
    @Override
    public void invoke(Map<Integer, String> data, AnalysisContext analysisContext) {
        if (1 == analysisContext.readRowHolder().getRowIndex()) {
            headList.add(data);
        } else {
            dataList.add(data);
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
    }

    public List<Map<Integer, String>> getHeadList() {
        return headList;
    }

    public List<Map<Integer, String>> getDataList() {
        return dataList;
    }

}
/**
 * 导出excel,支持全字段导入以及自定义字段导出
 *
 * @author smallNorth_Lee
 * @date 2022/8/10
 */
public class EasyExcelUtil {
/**
     * 读取excel模版数据
     *
     * @param file   文件流
     * @param target 转换对象
     * @param     泛型结构
     * @return List
     */
    public static <T> List<T> readExcel(MultipartFile file, Class<T> target) {
        try {
            ExcelReadListener excelReadListener = new ExcelReadListener();
            EasyExcelFactory.read(file.getInputStream(), excelReadListener).sheet().doRead();
            List<Map<Integer, String>> headList = excelReadListener.getHeadList();
            if (CollectionUtils.isEmpty(headList)) {
                throw new RuntimeException("表格中未包含表头信息!");
            }
            List<Map<Integer, String>> dataList = excelReadListener.getDataList();
            if (CollectionUtils.isEmpty(dataList)) {
                throw new RuntimeException("表格中包含错误数据,请调整后上传!");
            }
            //封装数据体
            List<Map<String, Object>> excelDataList = new ArrayList<>();
            for (Map<Integer, String> headMap : headList) {
                for (Map<Integer, String> dataRow : dataList) {
                    Map<String, Object> rowData = new LinkedHashMap<>();
                    headMap.forEach((key, value) -> rowData.put(value, dataRow.get(key)));
                    excelDataList.add(rowData);
                }
            }
            //字段转驼峰
            excelDataList = excelDataList.stream().map(MapUtil::toCamelCaseMap).collect(Collectors.toList());
            return ConvertUtils.setList(excelDataList, target);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return Collections.emptyList();
    }
 }
/**
 * 类型转换器
 *
 */
public class ConvertUtils {
/**
     * List> 到 List 数据转换
     */
    public static <T> List<T> setList(List<Map<String, Object>> srcList, Class<T> clazz) {
        List<T> list = new ArrayList<>();
        srcList.forEach(x -> {
            try {
                T t = clazz.newInstance();
                Field[] fields = t.getClass().getDeclaredFields();
                for (Field field : fields) {
                    if (!"serialVersionUID".equals(field.getName())) {
                        //设置对象的访问权限,保证对private的属性的访问
                        field.setAccessible(true);
                        //读取配置转换字段名,并从map中取出数据
                        Object v = x.get(field.getName());
                        field.set(t, convert(v, field.getType()));
                    }
                }
                list.add(t);
            } catch (Exception e) {

            }
        });
        return list;
    }
 }

后端使用方式

@ApiOperation(value = "读取excel")
@PostMapping("/reader/excel")
public ResultVo<List<ExcelFieldDemo>> readExcel(@RequestBody MultipartFile file) {
    List<ExcelFieldDemo> readExcelList = EasyExcelUtil.readExcel(file, ExcelFieldDemo.class);
    //入库或其它业务操作
    return new ResultVo<>(readExcelList);
}

你可能感兴趣的:(SpringBoot,excel,java,开发语言,easyexcel,读取excel)