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 {
@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
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
/**
* 把文件中的数据解析出来放入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)中的表头和实体类表头上的注解说明一致,则可以方便快捷的读取文件中的数据