Skip to content

Commit

Permalink
Merge d9490e7 into 1ee23f5
Browse files Browse the repository at this point in the history
  • Loading branch information
ozlerhakan committed Oct 11, 2020
2 parents 1ee23f5 + d9490e7 commit d29f2ef
Show file tree
Hide file tree
Showing 12 changed files with 273 additions and 128 deletions.
11 changes: 8 additions & 3 deletions src/main/java/com/poiji/bind/mapping/HSSFUnmarshaller.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,19 @@
import com.poiji.util.AnnotationUtil;
import com.poiji.util.ReflectUtil;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.CellValue;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand All @@ -49,6 +52,7 @@ abstract class HSSFUnmarshaller extends PoijiWorkBook implements Unmarshaller {
private final Map<Integer, String> caseSensitiveTitlePerColumnIndex;
private final int limit;
private int internalCount;
private HSSFFormulaEvaluator hssfFormulaEvaluator;

HSSFUnmarshaller(PoijiOptions options) {
this.options = options;
Expand All @@ -65,6 +69,7 @@ public <T> void unmarshal(Class<T> type, Consumer<? super T> consumer) {
HSSFWorkbook workbook = (HSSFWorkbook) workbook();
Optional<String> maybeSheetName = this.getSheetName(type, options);

hssfFormulaEvaluator = HSSFFormulaEvaluator.create(workbook, null, null);
Sheet sheet = this.getSheetToProcess(workbook, options, maybeSheetName.orElse(null));

int skip = options.skip();
Expand Down Expand Up @@ -157,7 +162,7 @@ private <T> T tailSetFieldValue(Row currentRow, Class<? super T> type, T instanc
for (Field field : type.getDeclaredFields()) {
if (field.getAnnotation(ExcelRow.class) != null) {
final int rowNum = currentRow.getRowNum();
final Object data = casting.castValue(field.getType(), valueOf(rowNum), rowNum, -1, options);
final Object data = casting.castValue(field, valueOf(rowNum), rowNum, -1, options);
setFieldData(instance, field, data);
} else if (field.getAnnotation(ExcelCellRange.class) != null) {

Expand Down Expand Up @@ -228,8 +233,8 @@ private <T> void constructTypeValue(Row currentRow, T instance, Field field, Fie
if (annotationDetail.isDisabledCellFormat()) {
cell.setCellStyle(null);
}
String value = dataFormatter.formatCellValue(cell);
Object data = casting.castValue(field.getType(), value, currentRow.getRowNum(), annotationDetail.getColumn(), options);
String value = dataFormatter.formatCellValue(cell, hssfFormulaEvaluator);
Object data = casting.castValue(field, value, currentRow.getRowNum(), annotationDetail.getColumn(), options);
setFieldData(instance, field, data);
}
}
Expand Down
38 changes: 15 additions & 23 deletions src/main/java/com/poiji/bind/mapping/PoijiHandler.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.poiji.bind.mapping;

import com.poiji.annotation.DisableCellFormatXLS;
import com.poiji.annotation.ExcelCell;
import com.poiji.annotation.ExcelCellName;
import com.poiji.annotation.ExcelCellRange;
Expand Down Expand Up @@ -33,20 +32,20 @@
*/
final class PoijiHandler<T> implements SheetContentsHandler {
private T instance;
private Consumer<? super T> consumer;
private final Consumer<? super T> consumer;
private int internalRow;
private int internalCount;
private int limit;
private Class<T> type;
private PoijiOptions options;
private final int limit;
private final Class<T> type;
private final PoijiOptions options;
private final Casting casting;
private Map<String, Integer> columnIndexPerTitle;
private Map<Integer, String> titlePerColumnIndex;
private final Map<String, Integer> columnIndexPerTitle;
private final Map<Integer, String> titlePerColumnIndex;
// New maps used to speed up computing and handle inner objects
private Map<String, Object> fieldInstances;
private Map<Integer, Field> columnToField;
private Map<Integer, Field> columnToSuperClassField;
private Set<ExcelCellName> excelCellNames;
private final Map<Integer, Field> columnToField;
private final Map<Integer, Field> columnToSuperClassField;
private final Set<ExcelCellName> excelCellNames;

PoijiHandler(Class<T> type, PoijiOptions options, Consumer<? super T> consumer) {
this.type = type;
Expand Down Expand Up @@ -74,7 +73,7 @@ private void setFieldValue(String content, Class<? super T> subclass, int column
* Using this to hold inner objects that will be mapped to the main object
**/
private Object getInstance(Field field) {
Object ins = null;
Object ins;
if (fieldInstances.containsKey(field.getName())) {
ins = fieldInstances.get(field.getName());
} else {
Expand All @@ -90,13 +89,13 @@ private boolean setValue(String content, Class<? super T> type, int column) {
.forEach(field -> {
ExcelRow excelRow = field.getAnnotation(ExcelRow.class);
if (excelRow != null) {
Object o = casting.castValue(field.getType(), valueOf(internalRow), internalRow, column, options);
Object o = casting.castValue(field, valueOf(internalRow), internalRow, column, options);
ReflectUtil.setFieldData(field, o, instance);
columnToField.put(-1, field);
}
ExcelCellRange range = field.getAnnotation(ExcelCellRange.class);
if (range != null) {
Object ins = null;
Object ins;
ins = getInstance(field);
for (Field f : field.getType().getDeclaredFields()) {
if (setValue(f, column, content, ins)) {
Expand Down Expand Up @@ -133,7 +132,7 @@ private boolean setValue(String content, Class<? super T> type, int column) {
// For ExcelRow annotation
if (columnToField.containsKey(-1)) {
Field field = columnToField.get(-1);
Object o = casting.castValue(field.getType(), valueOf(internalRow), internalRow, column, options);
Object o = casting.castValue(field, valueOf(internalRow), internalRow, column, options);
ReflectUtil.setFieldData(field, o, instance);
}
if (columnToField.containsKey(column) && columnToSuperClassField.containsKey(column)) {
Expand All @@ -151,31 +150,24 @@ private boolean setValue(String content, Class<? super T> type, int column) {

private boolean setValue(Field field, int column, String content, Object ins) {
ExcelCell index = field.getAnnotation(ExcelCell.class);
DisableCellFormatXLS disableCellFormat = field.getAnnotation(DisableCellFormatXLS.class);
boolean isCloseCellFormat = false;
if (disableCellFormat != null) {
isCloseCellFormat = disableCellFormat.value();
}

if (index != null) {
Class<?> fieldType = field.getType();
if (column == index.value()) {
Object o = casting.castValue(fieldType, content, internalRow, column, options);
Object o = casting.castValue(field, content, internalRow, column, options);
ReflectUtil.setFieldData(field, o, ins);
return true;
}
} else {
ExcelCellName excelCellName = field.getAnnotation(ExcelCellName.class);
if (excelCellName != null) {
excelCellNames.add(excelCellName);
Class<?> fieldType = field.getType();
final String titleName = options.getCaseInsensitive()
? excelCellName.value().toLowerCase()
: excelCellName.value();
final Integer titleColumn = columnIndexPerTitle.get(titleName);
//Fix both columns mapped to name passing this condition below
if (titleColumn != null && titleColumn == column) {
Object o = casting.castValue(fieldType, content, internalRow, column, options);
Object o = casting.castValue(field, content, internalRow, column, options);
ReflectUtil.setFieldData(field, o, ins);
return true;
}
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/com/poiji/bind/mapping/PoijiLogCellFormat.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,15 @@ public void setCellType(String cellType) {
this.cellType = cellType;
}

@Override
public String toString() {
return "InternalCellFormat{" +
"cellType='" + cellType + '\'' +
", formatIndex=" + formatIndex +
", formatString='" + formatString + '\'' +
", cellStypeStr='" + cellStypeStr + '\'' +
", cellAddress=" + cellAddress +
'}';
}
}
}
4 changes: 3 additions & 1 deletion src/main/java/com/poiji/config/Casting.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

import com.poiji.option.PoijiOptions;

import java.lang.reflect.Field;

/**
* A casting interface to build a custom poiji configuration.
*
* Created by hakan on 22/01/2017.
*/
public interface Casting {

Object castValue(Class<?> fieldType, String value, int row, int column, PoijiOptions options);
Object castValue(Field fieldType, String value, int row, int column, PoijiOptions options);
}
60 changes: 55 additions & 5 deletions src/main/java/com/poiji/config/DefaultCasting.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
import com.poiji.parser.BooleanParser;
import com.poiji.parser.Parsers;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
Expand All @@ -16,6 +19,8 @@
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
* Created by hakan on 22/01/2017.
Expand Down Expand Up @@ -132,6 +137,14 @@ private BigDecimal bigDecimalValue(String value, String sheetName, int row, int
}
}

private String[] parseArrayList(String value, PoijiOptions options, String sheetName, int row, int col) {
try {
return value.split(options.getListDelimiter());
} catch (Exception e) {
return onError(value, sheetName, row, col, e, options.preferNullOverDefault() ? null : new String[]{});
}
}

private Date dateValue(String value, String sheetName, int row, int col, PoijiOptions options) {

//ISSUE #57
Expand Down Expand Up @@ -200,18 +213,54 @@ private Object enumValue(String value, String sheetName, int row, int col, Class
}

public Object castValue(Class<?> fieldType, String value, PoijiOptions options) {
return castValue(fieldType, value, -1, -1, options);
return getValueObject(null, -1, -1, options, value, fieldType);
}

private Object castListValue(String value, String sheetName, int row, int col, Field field, PoijiOptions options) {
final ParameterizedType genericType = (ParameterizedType) field.getGenericType();
final Type fieldType = genericType.getActualTypeArguments()[0];
String[] valueList = value.split(options.getListDelimiter());

if (fieldType == Integer.class) {
return Stream.of(valueList)
.map(rv -> primitiveIntegerValue(rv, sheetName, row, col))
.collect(Collectors.toList());
} else if (fieldType == BigDecimal.class) {
return Stream.of(valueList)
.map(rv -> bigDecimalValue(rv, sheetName, row, col, options))
.collect(Collectors.toList());
} else if (fieldType == Long.class) {
return Stream.of(valueList)
.map(rv -> longValue(rv, sheetName, row, col, options))
.collect(Collectors.toList());
} else if (fieldType == Double.class) {
return Stream.of(valueList)
.map(rv -> doubleValue(rv, sheetName, row, col, options))
.collect(Collectors.toList());
} else if (fieldType == Boolean.class) {
return Stream.of(valueList)
.map(rv -> booleanValue(rv, sheetName, row, col, options))
.collect(Collectors.toList());
} else if (fieldType == Float.class) {
return Stream.of(valueList)
.map(rv -> floatValue(rv, sheetName, row, col, options))
.collect(Collectors.toList());
} else {
return Arrays.asList(valueList);
}
}

@Override
public Object castValue(Class<?> fieldType, String rawValue, int row, int col, PoijiOptions options) {
public Object castValue(Field field, String rawValue, int row, int col, PoijiOptions options) {
Class<?> fieldType = field.getType();
return getValueObject(field, row, col, options, rawValue, fieldType);
}

private Object getValueObject(Field field, int row, int col, PoijiOptions options, String rawValue, Class<?> fieldType) {
String sheetName = options.getSheetName();

String value = options.trimCellValue() ? rawValue.trim() : rawValue;

Object o;

if (fieldType == int.class) {
o = primitiveIntegerValue(value, sheetName, row, col);

Expand Down Expand Up @@ -259,7 +308,8 @@ public Object castValue(Class<?> fieldType, String rawValue, int row, int col, P

} else if (value.isEmpty()) {
o = options.preferNullOverDefault() ? null : value;

} else if (fieldType == List.class) {
o = castListValue(value, sheetName, row, col, field, options);
} else {
o = value;

Expand Down
29 changes: 26 additions & 3 deletions src/main/java/com/poiji/option/PoijiOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public final class PoijiOptions {
private PoijiNumberFormat numberFormat;
private boolean namedHeaderMandatory;
private boolean disableXLSXNumberCellFormat;
private String listDelimiter;

public PoijiNumberFormat getPoijiNumberFormat() {
return numberFormat;
Expand Down Expand Up @@ -239,6 +240,15 @@ public boolean isDisableXLSXNumberCellFormat() {
return disableXLSXNumberCellFormat;
}

public String getListDelimiter() {
return listDelimiter;
}

private PoijiOptions setListDelimiter(String listDelimiter) {
this.listDelimiter = listDelimiter;
return this;
}

public static class PoijiOptionsBuilder {

private int sheetIndex;
Expand All @@ -262,6 +272,7 @@ public static class PoijiOptionsBuilder {
private boolean caseInsensitive;
private boolean namedHeaderMandatory;
private boolean disabledXLSXNumberCellFormat;
private String listDelimiter = ",";

private PoijiOptionsBuilder() {
}
Expand Down Expand Up @@ -357,7 +368,8 @@ public PoijiOptions build() {
.setPoijiNumberFormat(numberFormat)
.setCaseInsensitive(caseInsensitive)
.setNamedHeaderMandatory(namedHeaderMandatory)
.disableXLSXNumberCellFormat(disabledXLSXNumberCellFormat);
.disableXLSXNumberCellFormat(disabledXLSXNumberCellFormat)
.setListDelimiter(listDelimiter);
}

/**
Expand Down Expand Up @@ -417,7 +429,7 @@ public PoijiOptionsBuilder limit(int limit) {
/**
* set password for encrypted excel file, Default is null
*
* @param password
* @param password excel password
* @return this
*/
public PoijiOptionsBuilder password(String password) {
Expand Down Expand Up @@ -561,11 +573,22 @@ public PoijiOptionsBuilder namedHeaderMandatory(boolean namedHeaderMandatory) {
/**
* Disable the cell format of all the number cells of an excel file ending with xlsx
*
* @return this;
* @return this
*/
public PoijiOptionsBuilder disableXLSXNumberCellFormat() {
this.disabledXLSXNumberCellFormat = true;
return this;
}

/**
* Use different delimiter to split the list of items of a cell
*
* @param delimiter by default delimiter is ','
* @return this
*/
public PoijiOptionsBuilder addListDelimiter(String delimiter) {
this.listDelimiter = delimiter;
return this;
}
}
}
Loading

0 comments on commit d29f2ef

Please sign in to comment.