springboot通过 EasyExcel.read()方法解析csv(excel)文件中的数据用list接收
文章目录
- 前言
- 一、EasyExcel是什么?
- 二、使用步骤
- 1.引入库
- 2.接收数据的实体类
- 3.处理字典值ExcelDictConverter
- 4.把文件中的数据解析出来放入list中getDataImport
- 总结
前言
一、EasyExcel是什么?
EasyExcel是阿里巴巴开源的一个excel处理框架,以使用简单、节省内存著称。
EasyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中。
而是从磁盘上一行行读取数据,逐个解析。
EasyExcel采用一行一行的解析模式,并将一行的解析结果以观察者模式通知处理(AnalysisEventListener)。
二、使用步骤
1.引入库
代码如下(示例):
<dependencies><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.1.2</version></dependency>
</dependencies>
2.接收数据的实体类
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class UserVO extends BaseEntity {@ExcelIgnoreprivate Integer id;/*** 编码*/@ExcelIgnoreprivate 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
public class ExcelDictConverter implements Converter<Integer> {@Overridepublic Class<?> supportJavaTypeKey() {return Number.class;}@Overridepublic CellDataTypeEnum supportExcelTypeKey() {return CellDataTypeEnum.NUMBER;}@Overridepublic 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
/*** 把文件中的数据解析出来放入list中* @param file* @return*/@Overridepublic 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>() {@Overridepublic void invoke(UserVO user, AnalysisContext context) {//把解析到的每一行数据都存入list中userVOS.add(user);}@Overridepublic 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)中的表头和实体类表头上的注解说明一致,则可以方便快捷的读取文件中的数据