在日常写解析Excel业务中,可能会遇到在解析一个Excel表时,表中的数据不能全被一个对象接收,这时候可能需要定义一个大对象去接收数据,但是我们知道,Excel中一行数据就是一个对象,所以这种方式是行不通的。
如下图:圈出来的数据是不能被一个对象接收并解析的
解决办法:可以将Excel内容进行分割
思路:比如表格中的“指标名称”字符串内容是固定的,我就可以以它为分割行进行划分
项目用到的依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.1.4</version>
</dependency>
Excel 数据监听类:
public class ExcelDataListener<T> extends AnalysisEventListener<T> {
private List<T> dataList = new ArrayList<>();
@Override
public void invoke(T t, AnalysisContext analysisContext) {
dataList.add(t);
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
}
public List<T> getDataList() {
return this.dataList;
}
}
输入流读取Excel数据
public class ExcelParse {
public static <T> List<T> simpleRead(InputStream inputStream) {
// sheet文件流会自动关闭
ExcelDataListenerdataListener = new ExcelDataListener();
EasyExcel.read(inputStream, dataListener).sheet().doRead();
return dataListener.getDataList();
}
// 如果传入类,会自动映射
public static <T> List<T> simpleRead(InputStream inputStream, Class<T> clazz) {
ExcelDataListener<T> dataListener = new ExcelDataListener<>();
EasyExcel.read(inputStream, clazz, dataListener).sheet().doRead();
return dataListener.getDataList();
}
}
分割处理(这里只是演示,建议封装成工具类更好)
@PostMapping("/parseExcel")
public void getExcelContent(@RequestParam("file") MultipartFile file) throws IOException {
InputStream is = file.getInputStream();
List<Map<Integer, String>> all = ExcelParse.simpleRead(is);
Map<Integer, String> map = null;
// 从哪一行进行分割,因为是要在lambda读取splitHeadNum原子操作
AtomicInteger splitHeadNum = new AtomicInteger();
AtomicInteger splitTailNum = new AtomicInteger();
// 将Excel进行分割(企业信息与内容进行分割)
for (int i = 0; i < all.size(); i++) {
int temp = i;
map = all.get(i);
map.forEach((k, v) -> {
if (v != null) {
if ("指标名称".equals(v)) {
// 获取头部要分割的行数
splitHeadNum.set(temp);
}
if ("负责人".contains(v)) {
// 获取尾部要分割的行数
splitTailNum.set(temp);
}
}
});
}
// Excel头信息解析
for (int i = 0; i < splitHeadNum.get(); i++) {
map = all.get(i);
// 删除null元素(导入的时候表格如有null列,只能这样删除null元素了。。。有好方法再TODO)
map.entrySet().removeIf(entry -> entry.getValue() == null);
System.out.println(map);
}
System.out.println("=================================");
// 解析Excel数据
for (int i = splitHeadNum.get(); i < splitTailNum.get(); i++) {
map = all.get(i);
// 删除null元素(导入的时候表格如有null列,只能这样删除null元素了。。。有好方法再TODO)
map.entrySet().removeIf(entry -> entry.getValue() == null);
System.out.println(map);
}
}
成功分割~