本质上来说,根据名称解析也是获取到名称对应的下标/索引进行解析,如果是根据索引进行解析,不需要名称对应转换步骤即可
使用方式为:new ExcelAnalysisHelper().getList(file, T.class);
@ExcelProperty(value = “序号”,index = 1),其中value为名称,index为索引
根据索引解析可参考(我也是参考别人的文档):根据索引解析
package com.meiyuan.controller.excel;
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.meiyuan.commons.tools.exception.ErrorCode;
import com.meiyuan.order.exception.OrdersException;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
/**
* * 模板的读取类
*
* @author syx
* @version 1.0.0
* @date 2020/12/21 9:44
*/
@Slf4j
public class ExcelAnalysisHelper<T> {
public List<T> getList(MultipartFile file, Class<T> clazz) {
return getList(file, clazz, 0, 1);
}
public List<T> getList(MultipartFile file, Class<T> clazz, Integer sheetNo, Integer headRowNumber) {
UploadDataListener<T> listener = new UploadDataListener<>(headRowNumber);
try {
EasyExcel.read(file.getInputStream(), clazz, listener).extraRead(CellExtraTypeEnum.MERGE).sheet(sheetNo).headRowNumber(headRowNumber).doRead();
} catch (IOException e) {
log.error(e.getMessage());
}
List<CellExtra> extraMergeInfoList = listener.getExtraMergeInfoList();
if (CollectionUtils.isEmpty(extraMergeInfoList)) {
return listener.getData();
}
List<T> data = explainMergeData(listener.getData(), extraMergeInfoList, headRowNumber, file);
return data;
}
/**
* 处理合并单元格
*
* @param data 解析数据
* @param extraMergeInfoList 合并单元格信息
* @param headRowNumber 起始行
* @return 填充好的解析数据
*/
private List<T> explainMergeData(List<T> data, List<CellExtra> extraMergeInfoList, Integer headRowNumber, MultipartFile file) {
XSSFWorkbook xssfWorkbook = null;
try {
xssfWorkbook = new XSSFWorkbook(file.getInputStream());
XSSFSheet sheetAt = xssfWorkbook.getSheetAt(0);
XSSFRow row = sheetAt.getRow(headRowNumber - 1);
List<String> columnNames = new ArrayList<>();
for (int rowNum = 0; rowNum <= row.getLastCellNum() - 1; rowNum++) {
columnNames.add(row.getCell(rowNum).getStringCellValue());
}
// 循环所有合并单元格信息
extraMergeInfoList.forEach(cellExtra -> {
int firstRowIndex = cellExtra.getFirstRowIndex() - headRowNumber;
int lastRowIndex = cellExtra.getLastRowIndex() - headRowNumber;
int firstColumnIndex = cellExtra.getFirstColumnIndex();
int lastColumnIndex = cellExtra.getLastColumnIndex();
// 获取初始值
if (firstRowIndex < data.size()) {
Object initValue = getInitValueFromList(firstRowIndex, firstColumnIndex, data, columnNames);
// 设置值
for (int i = firstRowIndex; i <= lastRowIndex; i++) {
for (int j = firstColumnIndex; j <= lastColumnIndex; j++) {
setInitValueToList(initValue, i, j, data, columnNames);
}
}
}
});
} catch (IOException e) {
log.error("文件【{}】解析失败【{}】", file, e);
}
return data;
}
/**
* 设置合并单元格的值
*
* @param filedValue 值
* @param rowIndex 行
* @param columnIndex 列
* @param data 解析数据
*/
public void setInitValueToList(Object filedValue, Integer rowIndex, Integer columnIndex, List<T> data, List<String> columnNames) {
T object = data.get(rowIndex);
for (Field field : object.getClass().getDeclaredFields()) {
//提升反射性能,关闭安全检查
field.setAccessible(true);
ExcelProperty annotation = field.getAnnotation(ExcelProperty.class);
if (annotation != null) {
String names = "";
for (String s : annotation.value()) {
names = names + s;
}
int index = columnNames.indexOf(names);
if (index == columnIndex) {
try {
field.set(object, filedValue);
break;
} catch (IllegalAccessException e) {
throw new OrdersException(ErrorCode.INTERNAL_SERVER_ERROR, "解析数据时发生异常!");
}
}
}
}
}
/**
* 获取合并单元格的初始值
* rowIndex对应list的索引
* columnIndex对应实体内的字段
*
* @param firstRowIndex 起始行
* @param firstColumnIndex 起始列
* @param data 列数据
* @param nameList excel表头名称
* @return 初始值
*/
private Object getInitValueFromList(Integer firstRowIndex, Integer firstColumnIndex, List<T> data, List<String> nameList) {
Object filedValue = null;
T object = data.get(firstRowIndex);
Field[] fields = object.getClass().getDeclaredFields();
for (Field field : fields) {
//提升反射性能,关闭安全检查
field.setAccessible(true);
ExcelProperty annotation = field.getAnnotation(ExcelProperty.class);
if (annotation != null) {
String names = "";
for (String s : annotation.value()) {
names = names + s;
}
int index = nameList.indexOf(names);
if (index == firstColumnIndex) {
try {
filedValue = field.get(object);
break;
} catch (IllegalAccessException e) {
throw new OrdersException(ErrorCode.INTERNAL_SERVER_ERROR, "解析数据时发生异常!");
}
}
}
}
return filedValue;
}
/**
* 将EXCEL中A,B,C,D,E列映射成0,1,2,3
*
* @param col
*/
private int getExcelCol(String col) {
col = col.toUpperCase();
// 从-1开始计算,字母重1开始运算。这种总数下来算数正好相同。
int count = -1;
char[] cs = col.toCharArray();
for (int i = 0; i < cs.length; i++) {
count += (cs[i] - 64) * Math.pow(26, cs.length - 1 - i);
}
return count;
}
}
package com.meiyuan.controller.excel;
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 lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.List;
/**
* * 模板的读取类
*
* @author syx
* @version 1.0.0
* @date 2020/12/21 9:44
*/
@Slf4j
public class UploadDataListener<T> extends AnalysisEventListener<T> {
/**
* 解析的数据
*/
List<T> list = new ArrayList<>();
/**
* 正文起始行
*/
private Integer headRowNumber;
/**
* 合并单元格
*/
private List<CellExtra> extraMergeInfoList = new ArrayList<>();
public UploadDataListener(Integer headRowNumber) {
this.headRowNumber = headRowNumber;
}
/**
* 这个每一条数据解析都会来调用
*
* @param data one row value. Is is same as {@link AnalysisContext#readRowHolder()}
* @param context context
*/
@Override
public void invoke(T data, AnalysisContext context) {
list.add(data);
}
/**
* 所有数据解析完成了 都会来调用
*
* @param context context
*/
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
log.info("所有数据解析完成!");
}
/**
* 加上存储数据库
*/
public List<T> getData() {
return list;
}
@Override
public void extra(CellExtra extra, AnalysisContext context) {
if (extra.getType() == CellExtraTypeEnum.MERGE) {
if (extra.getRowIndex() >= headRowNumber) {
extraMergeInfoList.add(extra);
}
}
}
public List<CellExtra> getExtraMergeInfoList() {
return extraMergeInfoList;
}
}