湘潭网站建设 多少费用磐石网络,为企业进行网站建设方案,青岛专业网站建设价格,化妆品网站设计系统需求的策划书普通的excel列表#xff0c;easyexcel读取是没有什么问题的。但是#xff0c;如果有合并单元格#xff0c;那么它读取的时候#xff0c;能获取数据#xff0c;但是数据是不完整的。如下所示的单元格数据#xff1a; 我们通过简单的异步读取#xff0c;最后查看数据内容easyexcel读取是没有什么问题的。但是如果有合并单元格那么它读取的时候能获取数据但是数据是不完整的。如下所示的单元格数据 我们通过简单的异步读取最后查看数据内容 ExcelData.java
package com.example.model;import com.alibaba.excel.annotation.ExcelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;Data
AllArgsConstructor
NoArgsConstructor
public class ExcelData {ExcelProperty(学生姓名)private String name;ExcelProperty(年龄)private int age;ExcelProperty(性别)private String gender;ExcelProperty({课程, 课程名称})private String courseName;ExcelProperty({课程, 分数})private double score;
}ExcelRead.java
package com.example.service;import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.example.model.ExcelData;
import lombok.extern.slf4j.Slf4j;import java.util.ArrayList;
import java.util.List;Slf4j
public class ExcelRead {private static final String FILEPATH e:\\test\\student.xlsx;public ListExcelData list() {ListExcelData excelDataList new ArrayList();EasyExcel.read(FILEPATH, ExcelData.class, new AnalysisEventListenerExcelData() {Overridepublic void invoke(ExcelData excelData, AnalysisContext analysisContext) {log.info(read data {}, excelData);excelDataList.add(excelData);}Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {}}).sheet().doRead();return excelDataList;}
} ExcelTest.java
package com.example.service;import com.example.model.ExcelData;import java.util.List;public class ExcelTest {public static void main(String[] args) {ExcelRead excelRead new ExcelRead();ListExcelData list excelRead.list();System.out.println(list.size());}
}运行程序打印日志信息如下 获取了6个数据没错但是每一个合并单元格记录里面都有一个数据获取是空的。 解决办法就是需要在异步读取数据监听器里面读取合并单元格的额外数据并把这部分数据给补充上。 需要修改的地方 1、实体需要增加注解索引值
Data
AllArgsConstructor
NoArgsConstructor
public class ExcelData {ExcelProperty(value 学生姓名, index 0)private String name;ExcelProperty(value 年龄, index 1)private int age;ExcelProperty(value 性别, index 2)private String gender;ExcelProperty(value {课程, 课程名称}, index 3)private String courseName;ExcelProperty(value {课程, 分数}, index 4)private double score;
} 2、自定义监听器读取合并单元格数据
package com.example.service;import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.enums.CellExtraTypeEnum;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.metadata.CellExtra;
import com.example.model.ExcelData;
import lombok.extern.slf4j.Slf4j;import java.util.ArrayList;
import java.util.List;Slf4j
public class CustomAnalysisEventListener extends AnalysisEventListenerExcelData {private int headRowNum;public CustomAnalysisEventListener(int headRowNum) {this.headRowNum headRowNum;}private ListExcelData list new ArrayList();private ListCellExtra cellExtraList new ArrayList();Overridepublic void invoke(ExcelData excelData, AnalysisContext analysisContext) {log.info( data - {}, excelData);list.add(excelData);}Overridepublic void extra(CellExtra extra, AnalysisContext context) {CellExtraTypeEnum type extra.getType();switch (type) {case MERGE: {if (extra.getRowIndex() headRowNum) {cellExtraList.add(extra);}break;}default:{}}}Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {}public ListExcelData getList() {return list;}public ListCellExtra getCellExtraList() {return cellExtraList;}
}3、通过监听器读取数据通过监听器获取数据和合并单元格数据然后设置单元格数据。 package com.example.service;import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.enums.CellExtraTypeEnum;
import com.alibaba.excel.metadata.CellExtra;
import com.example.model.ExcelData;
import lombok.extern.slf4j.Slf4j;import java.lang.reflect.Field;
import java.util.List;Slf4j
public class ExcelRead {private static final int HEAD_ROW_NUM 2;private static final String FILEPATH e:\\test\\student.xlsx;public ListExcelData list() {ListExcelData excelDataList;CustomAnalysisEventListener listener new CustomAnalysisEventListener(HEAD_ROW_NUM);EasyExcel.read(FILEPATH, ExcelData.class, listener).extraRead(CellExtraTypeEnum.MERGE).sheet().doRead();excelDataList listener.getList();ListCellExtra cellExtraList listener.getCellExtraList();if (cellExtraList ! null cellExtraList.size() 0) {mergeExcelData(excelDataList, cellExtraList, HEAD_ROW_NUM);}return excelDataList;}private void mergeExcelData(ListExcelData excelDataList, ListCellExtra cellExtraList, int headRowNum) {cellExtraList.forEach(cellExtra - {int firstRowIndex cellExtra.getFirstRowIndex() - headRowNum;int lastRowIndex cellExtra.getLastRowIndex() - headRowNum;int firstColumnIndex cellExtra.getFirstColumnIndex();int lastColumnIndex cellExtra.getLastColumnIndex();//获取初始值Object initValue getInitValueFromList(firstRowIndex, firstColumnIndex, excelDataList);//设置值for (int i firstRowIndex; i lastRowIndex; i) {for (int j firstColumnIndex; j lastColumnIndex; j) {setInitValueToList(initValue, i, j, excelDataList);}}});}private void setInitValueToList(Object filedValue, Integer rowIndex, Integer columnIndex, ListExcelData data) {ExcelData object data.get(rowIndex);for (Field field : object.getClass().getDeclaredFields()) {field.setAccessible(true);ExcelProperty annotation field.getAnnotation(ExcelProperty.class);if (annotation ! null) {if (annotation.index() columnIndex) {try {field.set(object, filedValue);break;} catch (IllegalAccessException e) {log.error(设置合并单元格的值异常{}, e.getMessage());}}}}}private Object getInitValueFromList(Integer firstRowIndex, Integer firstColumnIndex, ListExcelData data) {Object filedValue null;ExcelData object data.get(firstRowIndex);for (Field field : object.getClass().getDeclaredFields()) {field.setAccessible(true);ExcelProperty annotation field.getAnnotation(ExcelProperty.class);if (annotation ! null) {if (annotation.index() firstColumnIndex) {try {filedValue field.get(object);break;} catch (IllegalAccessException e) {log.error(设置合并单元格的初始值异常{}, e.getMessage());}}}}return filedValue;}
} 有个小细节需要注意我们在通过监听器读取的时候还需要额外读取合并单元格部分。
EasyExcel.read(FILEPATH, ExcelData.class, listener).extraRead(CellExtraTypeEnum.MERGE).sheet().doRead(); 还有个小细节就是我们的表格一般都是有头的头的内容可能是2行可能是1行在进行合并单元格处理的时候需要考虑这个行数。我们定义了一个常量HEAD_ROW_NUM来记录这个行数最后进行单元格值计算的时候传入。 我在处理excel数据中发现如果这个单元格合并是由我们的程序自己做的那么它读取的时候是没有问题的。在上面为null的地方它其实都有值 但是在实际中我们的excel不能保证不被人为编辑那么就很有可能我们在进行合并单元格的时候把有值和无值合并到一起最后就出现前面提到的读取合并单元格出现数据缺失的问题。 而我们期望合并单元格部分他们的数据应该是一样的。所以今天的解决方案是一种保险的做法不管你的表格是否有合并单元格是否人为修改最终都能把合并单元格缺失的数据进行恢复。