org.javafunk.excelparser.SheetParser Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of excel-parser Show documentation
Show all versions of excel-parser Show documentation
Annotations for Excel document parsing.
The newest version!
package org.javafunk.excelparser;
import org.javafunk.excelparser.annotations.ExcelField;
import org.javafunk.excelparser.annotations.ExcelObject;
import org.javafunk.excelparser.annotations.MappedExcelObject;
import org.javafunk.excelparser.annotations.ParseType;
import org.javafunk.excelparser.exception.ExcelParsingException;
import org.javafunk.excelparser.helper.HSSFHelper;
import lombok.AccessLevel;
import lombok.experimental.FieldDefaults;
import org.apache.poi.ss.usermodel.Sheet;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.OptionalInt;
import java.util.Set;
import java.util.function.Consumer;
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
public class SheetParser {
public List createEntity(Sheet sheet, Class clazz, Consumer errorHandler) {
List list = new ArrayList<>();
ExcelObject excelObject = getExcelObject(clazz, errorHandler);
if (excelObject.start() <= 0 || excelObject.end() < 0) {
return list;
}
int end = getEnd(sheet, clazz, excelObject);
for (int currentLocation = excelObject.start(); currentLocation <= end; currentLocation++) {
T object = getNewInstance(sheet, clazz, excelObject.parseType(), currentLocation, excelObject.zeroIfNull(),
errorHandler);
List mappedExcelFields = getMappedExcelObjects(clazz);
for (Field mappedField : mappedExcelFields) {
Class> fieldType = mappedField.getType();
Class> clazz1 = fieldType.equals(List.class) ? getFieldType(mappedField) : fieldType;
List> fieldValue = createEntity(sheet, clazz1, errorHandler);
if (fieldType.equals(List.class)) {
setFieldValue(mappedField, object, fieldValue);
} else if (!fieldValue.isEmpty()) {
setFieldValue(mappedField, object, fieldValue.get(0));
}
}
list.add(object);
}
return list;
}
private int getEnd(Sheet sheet, Class clazz, ExcelObject excelObject) {
int end = excelObject.end();
if (end > 0) {
return end;
}
return getRowOrColumnEnd(sheet, clazz);
}
/**
* @deprecated Pass an error handler lambda instead (see other signature)
*/
@Deprecated
public List createEntity(Sheet sheet, String sheetName, Class clazz) {
return createEntity(sheet, clazz, error -> {
throw error;
});
}
public int getRowOrColumnEnd(Sheet sheet, Class clazz) {
ExcelObject excelObject = getExcelObject(clazz, e -> {
throw e;
});
ParseType parseType = excelObject.parseType();
if (parseType == ParseType.ROW) {
return sheet.getLastRowNum() + 1;
}
Set positions = getExcelFieldPositionMap(clazz).keySet();
OptionalInt maxPosition = positions.stream().mapToInt((x) -> x).max();
OptionalInt minPosition = positions.stream().mapToInt((x) -> x).min();
int maxCellNumber = 0;
for (int i = minPosition.getAsInt(); i < maxPosition.getAsInt(); i++) {
int cellsNumber = sheet.getRow(i).getLastCellNum();
if (maxCellNumber < cellsNumber) {
maxCellNumber = cellsNumber;
}
}
return maxCellNumber;
}
private Class> getFieldType(Field field) {
Type type = field.getGenericType();
if (type instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) type;
return (Class>) pt.getActualTypeArguments()[0];
}
return null;
}
private List getMappedExcelObjects(Class clazz) {
List fieldList = new ArrayList<>();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
MappedExcelObject mappedExcelObject = field.getAnnotation(MappedExcelObject.class);
if (mappedExcelObject != null) {
field.setAccessible(true);
fieldList.add(field);
}
}
return fieldList;
}
private ExcelObject getExcelObject(Class clazz, Consumer errorHandler) {
ExcelObject excelObject = clazz.getAnnotation(ExcelObject.class);
if (excelObject == null) {
errorHandler.accept(new ExcelParsingException("Invalid class configuration - ExcelObject annotation missing - " + clazz.getSimpleName()));
}
return excelObject;
}
private T getNewInstance(Sheet sheet, Class clazz, ParseType parseType, Integer currentLocation, boolean zeroIfNull, Consumer errorHandler) {
T object = getInstance(clazz, errorHandler);
Map excelPositionMap = getExcelFieldPositionMap(clazz);
for (Integer position : excelPositionMap.keySet()) {
Field field = excelPositionMap.get(position);
Object cellValue;
if (ParseType.ROW == parseType) {
cellValue = HSSFHelper.getCellValue(sheet, field.getType(), currentLocation, position, zeroIfNull, errorHandler);
} else {
cellValue = HSSFHelper.getCellValue(sheet, field.getType(), position, currentLocation, zeroIfNull, errorHandler);
}
setFieldValue(field, object, cellValue);
}
return object;
}
private T getInstance(Class clazz, Consumer errorHandler) {
T object;
try {
Constructor constructor = clazz.getDeclaredConstructor();
constructor.setAccessible(true);
object = constructor.newInstance();
} catch (Exception e) {
errorHandler.accept(new ExcelParsingException("Exception occurred while instantiating the class " + clazz.getName(), e));
return null;
}
return object;
}
private void setFieldValue(Field field, T object, Object cellValue) {
try {
field.set(object, cellValue);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new ExcelParsingException("Exception occurred while setting field value ", e);
}
}
private Map getExcelFieldPositionMap(Class clazz) {
Map fieldMap = new HashMap<>();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
ExcelField excelField = field.getAnnotation(ExcelField.class);
if (excelField != null) {
field.setAccessible(true);
fieldMap.put(excelField.position(), field);
}
}
return fieldMap;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy