未合并的单元格excel文件
/**
* 转换用户上传的excel文件为java对象
*
* @param file 用户上传的文件
* @param clazz 将被解析的类
* @param <T> 泛型,任意类型
* @return 返回解析数据的List形式
* @throws IOException 文件读取异常
* @throws EquipmentException 自定义异常
*/
public static <T> List<T> fromSimpleFile(final MultipartFile file, final Class<T> clazz) throws IOException, EquipmentException {
return filterNullRow(
EasyExcel.read(file.getInputStream(), clazz, null)
.ignoreEmptyRow(true)
.autoTrim(true)
.autoCloseStream(true)
.doReadAllSync()
);
}
合并单元格的excel文件,readListener为解析合并单元格的类
/**
* 转换用户上传的excel文件为java对象,包含合并行
*
* @param file 用户上传的文件
* @param clazz 将被解析的类
* @param <T> 泛型,任意类型
* @param readListener 解决合并行
* @return 返回解析数据的List形式
* @throws IOException 文件读取异常
* @throws EquipmentException 自定义异常
*/
public static <T> List<T> fromMergeFile(final MultipartFile file,
final Class<T> clazz,
final ReadListener<T> readListener
) throws IOException, EquipmentException {
return filterNullRow(
EasyExcel.read(file.getInputStream(), clazz, readListener)
.extraRead(CellExtraTypeEnum.MERGE)
.ignoreEmptyRow(true)
.autoTrim(true)
.autoCloseStream(true)
.doReadAllSync()
);
}
解析合并单元格函数,其实合并后就是excel的第一行有数据,其余为空行,把第一行的数据赋值给空行就可以了
public class OriginProtocolResolver <T> extends AnalysisEventListener<T> {
/**
* 解析出的数据
*/
private final LinkedHashMap<Integer, T> row2DataMap = new LinkedHashMap<>(256);
/**
* 合并单元格
*/
private final List<CellExtra> extraMergeInfoList = new ArrayList<>();
@SneakyThrows
@Override
public void invoke(OriginProtocol rowData, AnalysisContext analysisContext) {
//读取到的每行数据,其key是以0开始的索引,可在这对每行都有的数据进行异常判定
row2DataMap.put(analysisContext.readRowHolder().getRowIndex(), rowData);
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
//所有行都解析完成
this.explainMergeData(row2DataMap, extraMergeInfoList);
}
/**
* 某行的数据解析失败
*/
@Override
public void onException(Exception exception, AnalysisContext context) {
System.err.println("解析失败,但是继续解析下一行: " + exception.getMessage());
// 如果是某一个单元格的转换异常 能获取到具体行号
if (exception instanceof ExcelDataConvertException) {
ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException) exception;
System.err.println("第{}行,第{}列解析异常" + excelDataConvertException.getRowIndex() +
excelDataConvertException.getColumnIndex());
}
}
@Override
public void extra(CellExtra extra, AnalysisContext context) {
switch (extra.getType()) {
case MERGE: {
extraMergeInfoList.add(extra);
break;
}
case HYPERLINK: {
break;
}
case COMMENT: {
}
default: {
}
}
}
/**
* 处理合并单元格
*
* @param data 解析数据
* @param extraMergeInfoList 合并单元格信息
*/
private void explainMergeData(Map<Integer, T> data, List<CellExtra> extraMergeInfoList) {
//循环所有合并单元格信息
extraMergeInfoList.forEach(new Consumer<CellExtra>() {
@SneakyThrows
@Override
public void accept(CellExtra cellExtra) {
int firstRowIndex = cellExtra.getFirstRowIndex();
int lastRowIndex = cellExtra.getLastRowIndex();
// 获取第一个不为空的,可在这对第一行就是数据完整的行进行错误判定
T first = data.get(firstRowIndex);
// 把剩下几个填充进去
for (int i = firstRowIndex + 1; i <= lastRowIndex; i++) {
T value= data.get(i);
// 在这里把第一行的数据赋值给其他空行
}
}
});
}
}