/**
* 大文件读取
*
* @param file 文件
* @param handler 通用处理器
*/
public void readExcel(File file,
XSSFSheetXMLHandler.SheetContentsHandler handler) {
try (FileInputStream inputStream = new FileInputStream(file)) {
OPCPackage pck = OPCPackage.open(inputStream);
XSSFReader reader = new XSSFReader(pck);
StylesTable styles = reader.getStylesTable();
XSSFEventBasedExcelExtractor extractor = new XSSFBEventBasedExcelExtractor(pck);
final Iterator<InputStream> sheets = reader.getSheetsData();
while (sheets.hasNext()) {
extractor.processSheet(
handler,
styles,
null,
reader.getSharedStringsTable(),
sheets.next()
);
}
} catch (Exception e) {
e.printStackTrace();
}
}
通用文件处理器
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler;
import org.apache.poi.xssf.usermodel.XSSFComment;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;
/**
* 通用导入读取处理
*
* @param <T> 对象
*/
@Log4j2
public class CommonImportSheetHandler<T> implements XSSFSheetXMLHandler.SheetContentsHandler {
/**
* 转换后的每行数据JavaBean实例
*/
private T rowBean;
/**
* 行数据的JavaBean类型
*/
private final Class<T> rowClass;
/**
* 读取sheet中的一行数据
*/
private final Consumer<T> data;
/**
* 第一行数据的行索引。从0开始
*/
private final int firstDataRowIndex;
/**
* 行数据映射的Java类中所有的字段的集合Map
* Key: 列头A,B,C....
* Value: 对应Java类中的字段名
*/
private final Map<String, Field> rowBeanFieldMap;
public CommonImportSheetHandler(Class<T> rowClass, Consumer<T> data,
int firstDataRowIndex) {
this.rowClass = rowClass;
this.data = data;
this.firstDataRowIndex = firstDataRowIndex;
Field[] declaredFields = rowClass.getDeclaredFields();
this.rowBeanFieldMap = new HashMap<>(declaredFields.length);
for (int i = 0; i < declaredFields.length; i++) {
Field field = declaredFields[i];
rowBeanFieldMap.put(CellReference.convertNumToColString(i), field);
}
}
public CommonImportSheetHandler(Class<T> rowClass,
Consumer<T> data) {
this(rowClass, data, 0);
}
@Override
public void startRow(int rowIndex) {
if (rowIndex >= firstDataRowIndex) {
try {
this.rowBean = this.rowClass.getDeclaredConstructor().newInstance();
} catch (ReflectiveOperationException e) {
e.printStackTrace();
}
}
}
@Override
public void endRow(int rowNum) {
if (Objects.nonNull(this.rowBean)) {
// 保存信息
this.data.accept(rowBean);
}
this.rowBean = null;
}
@Override
public void cell(String cellReference, String formattedValue, XSSFComment comment) {
if (Objects.isNull(rowBean) || StringUtils.isBlank(formattedValue)) {
return;
}
Field field = getField(cellReference, this.rowBeanFieldMap);
try {
if (Objects.nonNull(field)) {
field.setAccessible(true);
Object fieldValue = getCellValue(formattedValue, field);
ReflectionUtils.setField(field, rowBean, fieldValue);
}
} catch (Exception e) {
log.error("filed [{}] ref's cell [{}] value error", field.getName(), cellReference, e);
}
}
private Object getCellValue(String cellValue, Field field) {
if (StringUtils.isBlank(cellValue)) {
return null;
}
String value = convertCellValue(cellValue, field);
if (String.class.isAssignableFrom(field.getType())) {
return value;
}
if (Integer.class.isAssignableFrom(field.getType())) {
return Integer.parseInt(value);
}
if (Long.class.isAssignableFrom(field.getType())) {
return Long.parseLong(value);
}
return cellValue;
}
private String convertCellValue(String cellValue, Field field) {
return cellValue;
}
private Field getField(String cellAddress, Map<String, Field> rowBeanFieldMap) {
String columnCode = getColumnCode(cellAddress);
return rowBeanFieldMap.get(columnCode);
}
/**
* 获取单元格的列头代码
*
* @param cellAddress A1,B1,C1...
*/
private String getColumnCode(String cellAddress) {
return cellAddress.replaceAll("\\d+$", "");
}
}