diff --git a/common-tara/pom.xml b/common-tara/pom.xml
index dada12b..f00bd13 100644
--- a/common-tara/pom.xml
+++ b/common-tara/pom.xml
@@ -9,12 +9,12 @@
+ * number eg:{"2",""}(2, ),{"2","5"},{"","5"} + * date eg:{"2019-08-01 12:00:00",""},{"2019-08-01 12:00:00","2019-10-01 12:00:00"} + *
*/ - private Double min; + private String[] range; /** - * 最大值 + * range type {@link FieldRangeType} ,default is {@link FieldRangeType#RANGE_CLOSE} */ - private Double max; + private FieldRangeType rangeType; } diff --git a/excel-tara/src/main/java/com/sondertara/excel/enums/FieldRangeType.java b/excel-tara/src/main/java/com/sondertara/excel/enums/FieldRangeType.java new file mode 100644 index 0000000..fd59d3b --- /dev/null +++ b/excel-tara/src/main/java/com/sondertara/excel/enums/FieldRangeType.java @@ -0,0 +1,27 @@ +package com.sondertara.excel.enums; + +public enum FieldRangeType { + /** + * range[] + */ + RANGE_CLOSE(1), + /** + * range() + */ + RANGE_OPEN(2), + /** + * range(] + */ + RANGE_LEFT_OPEN(3), + /** + * range[) + */ + RANGE_RIGHT_OPEN(4), + ; + + private Integer type; + + FieldRangeType(Integer type) { + this.type = type; + } +} diff --git a/excel-tara/src/main/java/com/sondertara/excel/factory/ExcelMappingFactory.java b/excel-tara/src/main/java/com/sondertara/excel/factory/ExcelMappingFactory.java index 31ade03..829c270 100644 --- a/excel-tara/src/main/java/com/sondertara/excel/factory/ExcelMappingFactory.java +++ b/excel-tara/src/main/java/com/sondertara/excel/factory/ExcelMappingFactory.java @@ -41,8 +41,8 @@ public static ExcelEntity loadImportExcelClass(Class clazz) { .regexMessage(importField.regexMessage().trim()) .scale(importField.scale()) .roundingMode(importField.roundingMode()) - .min(importField.min()) - .max(importField.max()) + .range(importField.range()) + .rangeType(importField.rangeType()) .build(); propertyList.add(excelPropertyEntity); } diff --git a/excel-tara/src/main/java/com/sondertara/excel/parser/ExcelReader.java b/excel-tara/src/main/java/com/sondertara/excel/parser/ExcelReader.java index d6d300e..10ab8c9 100644 --- a/excel-tara/src/main/java/com/sondertara/excel/parser/ExcelReader.java +++ b/excel-tara/src/main/java/com/sondertara/excel/parser/ExcelReader.java @@ -10,6 +10,7 @@ import com.sondertara.excel.entity.ErrorEntity; import com.sondertara.excel.entity.ExcelEntity; import com.sondertara.excel.entity.ExcelPropertyEntity; +import com.sondertara.excel.enums.FieldRangeType; import com.sondertara.excel.exception.AllEmptyRowException; import com.sondertara.excel.exception.ExcelTaraException; import com.sondertara.excel.function.ImportFunction; @@ -501,6 +502,7 @@ private Object convertCellValue(ExcelPropertyEntity mappingProperty, Object cell */ private ErrorEntity checkCellValue(Integer cellIndex, ExcelPropertyEntity mappingProperty, Object cellValue) throws Exception { + // is required Boolean required = mappingProperty.getRequired(); if (null != required && required) { if (null == cellValue || StringUtil.isBlank(cellValue)) { @@ -509,21 +511,8 @@ private ErrorEntity checkCellValue(Integer cellIndex, ExcelPropertyEntity mappin , currentSheetIndex + 1, currentRowIndex + 1, cellIndex + 1); return buildErrorMsg(cellIndex, cellValue, validErrorMessage); } - if (Double.MIN_VALUE != mappingProperty.getMin() || Double.MAX_VALUE != mappingProperty.getMax()) { - final Double v = NumberUtil.toDouble(cellValue); - if (null == v) { - String validErrorMessage = String.format("The sheet[{}],row[{}],column[{}] is empty after converted!" - , currentSheetIndex + 1, currentRowIndex + 1, cellIndex + 1); - return buildErrorMsg(cellIndex, cellValue, validErrorMessage); - } else if (v > mappingProperty.getMax() || v < mappingProperty.getMin()) { - String validErrorMessage = String.format("The sheet[{}],row[{}],column[{}],cell value[%s] not pass the number range validation!" - , currentSheetIndex + 1, currentRowIndex + 1, cellIndex + 1, cellValue); - return buildErrorMsg(cellIndex, cellValue, validErrorMessage); - - } - } } - + //regex String regex = mappingProperty.getRegex(); if (!StringUtil.isBlank(cellValue) && !StringUtils.isBlank(regex)) { boolean matches = RegexUtil.isMatch(regex, cellValue.toString()); @@ -534,8 +523,29 @@ private ErrorEntity checkCellValue(Integer cellIndex, ExcelPropertyEntity mappin return buildErrorMsg(cellIndex, cellValue, validErrorMessage); } } - - + // value range + Class filedClazz = mappingProperty.getFieldEntity().getType(); + String[] range = mappingProperty.getRange(); + if (range.length == 0) { + return null; + } else if (StringUtil.isEmpty(range[0]) && StringUtil.isEmpty(range[1])) { + return null; + } else if (range.length != 2) { + throw new Exception("the ImportFiled annotation attribute[range] should a string[] with two elements!"); + } + String simpleName = filedClazz.getSimpleName(); + + if ("Date".equals(simpleName)) { + return checkRangeDate(cellIndex, filedClazz, range, cellValue, mappingProperty.getRangeType()); + } else if ("Integer".equals(simpleName) + || "double".equals(simpleName.toLowerCase()) + || "BigDecimal".equals(simpleName) + || "float".equals(simpleName.toLowerCase()) + || "int".equals(simpleName) + || "short".equals(simpleName.toLowerCase()) + || "long".equals(simpleName.toLowerCase())) { + return checkRangeNumber(cellIndex, filedClazz, range, cellValue, mappingProperty.getRangeType()); + } return null; } @@ -600,6 +610,214 @@ private String fillChar(String str, int len, char let, boolean isPre) { return str; } + /** + * if the field is date check date range + * + * @param cellIndex + * @param filedClazz + * @param range + * @param cellValue + * @param rangeType + * @return error entity + * @throws Exception + */ + private ErrorEntity checkRangeDate(Integer cellIndex, Class filedClazz, String[] range, Object cellValue, FieldRangeType rangeType) throws Exception { + final Date min = DateUtil.parse(range[0]); + final Date max = DateUtil.parse(range[1]); + if (null == min && null == max) { + throw new Exception("The ImportFiled annotation attribute[range] value must be date string[]"); + } else if (null != max && null != min && max.getTime() <= min.getTime()) { + throw new Exception(String.format("The ImportFiled annotation attribute[range] value %s is illegal!", Arrays.toString(range))) + ; + } + Date v = null; + try { + v = DateUtil.parse(String.valueOf(cellValue)); + } catch (ExecutionException e) { + String validErrorMessage = String.format("The sheet[%s],row[%s],column[%s],cell value[%s] must can be parsed to a date!" + , currentSheetIndex + 1, currentRowIndex + 1, cellIndex + 1, cellValue, range[0], range[1]); + return buildErrorMsg(cellIndex, cellValue, validErrorMessage); + } + if (null == v) { + String validErrorMessage = String.format("The sheet[%s],row[%s],column[%s] is empty after converted!" + , currentSheetIndex + 1, currentRowIndex + 1, cellIndex + 1); + return buildErrorMsg(cellIndex, cellValue, validErrorMessage); + } + switch (rangeType) { + case RANGE_CLOSE: + if (null == max && v.getTime() < min.getTime()) { + String validErrorMessage = String.format("The sheet[%s],row[%s],column[%s],cell value[%s] not pass the date range '[%s,]' validation!" + , currentSheetIndex + 1, currentRowIndex + 1, cellIndex + 1, cellValue, range[0]); + return buildErrorMsg(cellIndex, cellValue, validErrorMessage); + } else if (null == min && v.getTime() > max.getTime()) { + String validErrorMessage = String.format("The sheet[%s],row[%s],column[%s],cell value[%s] not pass the date range '[,%s]' validation!" + , currentSheetIndex + 1, currentRowIndex + 1, cellIndex + 1, cellValue, range[1]); + return buildErrorMsg(cellIndex, cellValue, validErrorMessage); + } else if (v.getTime() > max.getTime() || v.getTime() < min.getTime()) { + String validErrorMessage = String.format("The sheet[%s],row[%s],column[%s],cell value[%s] not pass the date range '[%s,%s]' validation!" + , currentSheetIndex + 1, currentRowIndex + 1, cellIndex + 1, cellValue, range[0], range[1]); + return buildErrorMsg(cellIndex, cellValue, validErrorMessage); + } + break; + case RANGE_OPEN: + if (null == max && v.getTime() <= min.getTime()) { + String validErrorMessage = String.format("The sheet[%s],row[%s],column[%s],cell value[%s] not pass the number range '(%s,)' validation!" + , currentSheetIndex + 1, currentRowIndex + 1, cellIndex + 1, cellValue, range[0]); + return buildErrorMsg(cellIndex, cellValue, validErrorMessage); + } else if (null == min && v.getTime() >= max.getTime()) { + String validErrorMessage = String.format("The sheet[%s],row[%s],column[%s],cell value[%s] not pass the number range '(,%s)' validation!" + , currentSheetIndex + 1, currentRowIndex + 1, cellIndex + 1, cellValue, range[1]); + return buildErrorMsg(cellIndex, cellValue, validErrorMessage); + } else if (v.getTime() >= max.getTime() || v.getTime() <= min.getTime()) { + String validErrorMessage = String.format("The sheet[%s],row[%s],column[%s],cell value[%s] not pass the number range '(%s,%s)' validation!" + , currentSheetIndex + 1, currentRowIndex + 1, cellIndex + 1, cellValue, range[0], range[1]); + return buildErrorMsg(cellIndex, cellValue, validErrorMessage); + } + break; + case RANGE_LEFT_OPEN: + if (null == max && v.getTime() <= min.getTime()) { + String validErrorMessage = String.format("The sheet[%s],row[%s],column[%s],cell value[%s] not pass the number range '(%s,]' validation!" + , currentSheetIndex + 1, currentRowIndex + 1, cellIndex + 1, cellValue, range[0]); + return buildErrorMsg(cellIndex, cellValue, validErrorMessage); + } else if (null == min && v.getTime() > max.getTime()) { + String validErrorMessage = String.format("The sheet[%s],row[%s],column[%s],cell value[%s] not pass the number range '(,%s]' validation!" + , currentSheetIndex + 1, currentRowIndex + 1, cellIndex + 1, cellValue, range[1]); + return buildErrorMsg(cellIndex, cellValue, validErrorMessage); + } else if (v.getTime() > max.getTime() || v.getTime() <= min.getTime()) { + String validErrorMessage = String.format("The sheet[%s],row[%s],column[%s],cell value[%s] not pass the number range '(%s,%s]' validation!" + , currentSheetIndex + 1, currentRowIndex + 1, cellIndex + 1, cellValue, range[0], range[1]); + return buildErrorMsg(cellIndex, cellValue, validErrorMessage); + } + break; + case RANGE_RIGHT_OPEN: + if (null == max && v.getTime() < min.getTime()) { + String validErrorMessage = String.format("The sheet[%s],row[%s],column[%s],cell value[%s] not pass the number range '[%s,)' validation!" + , currentSheetIndex + 1, currentRowIndex + 1, cellIndex + 1, cellValue, range[0]); + return buildErrorMsg(cellIndex, cellValue, validErrorMessage); + } else if (null == min && v.getTime() >= max.getTime()) { + String validErrorMessage = String.format("The sheet[%s],row[%s],column[%s],cell value[%s] not pass the number range '[,%s)' validation!" + , currentSheetIndex + 1, currentRowIndex + 1, cellIndex + 1, cellValue, range[1]); + return buildErrorMsg(cellIndex, cellValue, validErrorMessage); + } else if (v.getTime() >= max.getTime() || v.getTime() < min.getTime()) { + String validErrorMessage = String.format("The sheet[%s],row[%s],column[%s],cell value[%s] not pass the number range '[%s,%s)' validation!" + , currentSheetIndex + 1, currentRowIndex + 1, cellIndex + 1, cellValue, range[0], range[1]); + return buildErrorMsg(cellIndex, cellValue, validErrorMessage); + } + break; + default: + } + return null; + + } + + /** + * if the field is number check range + * + * @param cellIndex + * @param filedClazz + * @param range + * @param cellValue + * @param rangeType + * @return error entity + * @throws Exception + */ + private ErrorEntity checkRangeNumber(Integer cellIndex, Class filedClazz, String[] range, Object cellValue, FieldRangeType rangeType) throws Exception { + + Double min = null; + Double max = null; + try { + min = NumberUtil.toDouble(range[0]); + max = NumberUtil.toDouble(range[1]); + } catch (Exception e) { + throw new Exception("the ImportFiled annotation attribute[range] value must be number string[]"); + } + Double v = null; + try { + v = NumberUtil.toDouble(cellValue); + } catch (Exception e) { + } + if (null == min && null == max) { + throw new Exception("the ImportFiled annotation attribute[range] value must be number string[]"); + } else if (null != max && null != min && max <= min) { + throw new Exception(String.format("The ImportFiled annotation attribute[range] value %s is illegal!", Arrays.toString(range))); + } + if (null == v) { + String validErrorMessage = String.format("The sheet[%s],row[%s],column[%s] is empty after converted!" + , currentSheetIndex + 1, currentRowIndex + 1, cellIndex + 1); + return buildErrorMsg(cellIndex, cellValue, validErrorMessage); + } + switch (rangeType) { + case RANGE_CLOSE: + if (null == max && v < min) { + String validErrorMessage = String.format("The sheet[%s],row[%s],column[%s],cell value[%s] not pass the number range '[%s,]' validation!" + , currentSheetIndex + 1, currentRowIndex + 1, cellIndex + 1, cellValue, range[0]); + return buildErrorMsg(cellIndex, cellValue, validErrorMessage); + + } else if (null == min && v > max) { + String validErrorMessage = String.format("The sheet[%s],row[%s],column[%s],cell value[%s] not pass the number range '[,%s]' validation!" + , currentSheetIndex + 1, currentRowIndex + 1, cellIndex + 1, cellValue, range[1]); + return buildErrorMsg(cellIndex, cellValue, validErrorMessage); + } else if (v > max || v < min) { + String validErrorMessage = String.format("The sheet[%s],row[%s],column[%s],cell value[%s] not pass the number range '[%s,%s]' validation!" + , currentSheetIndex + 1, currentRowIndex + 1, cellIndex + 1, cellValue, range[0], range[1]); + return buildErrorMsg(cellIndex, cellValue, validErrorMessage); + } + break; + case RANGE_OPEN: + if (null == max && v <= min) { + String validErrorMessage = String.format("The sheet[%s],row[%s],column[%s],cell value[%s] not pass the number range '(%s,]' validation!" + , currentSheetIndex + 1, currentRowIndex + 1, cellIndex + 1, cellValue, range[0]); + return buildErrorMsg(cellIndex, cellValue, validErrorMessage); + + } else if (null == min && v >= max) { + String validErrorMessage = String.format("The sheet[%s],row[%s],column[%s],cell value[%s] not pass the number range '[,%s)' validation!" + , currentSheetIndex + 1, currentRowIndex + 1, cellIndex + 1, cellValue, range[1]); + return buildErrorMsg(cellIndex, cellValue, validErrorMessage); + } else if (v >= max || v <= min) { + String validErrorMessage = String.format("The sheet[%s],row[%s],column[%s],cell value[%s] not pass the number range '(%s,%s)' validation!" + , currentSheetIndex + 1, currentRowIndex + 1, cellIndex + 1, cellValue, range[0], range[1]); + return buildErrorMsg(cellIndex, cellValue, validErrorMessage); + } + break; + case RANGE_LEFT_OPEN: + if (null == max && v <= min) { + String validErrorMessage = String.format("The sheet[%s],row[%s],column[%s],cell value[%s] not pass the number range '(%s,]' validation!" + , currentSheetIndex + 1, currentRowIndex + 1, cellIndex + 1, cellValue, range[0]); + return buildErrorMsg(cellIndex, cellValue, validErrorMessage); + + } else if (null == min && v > min) { + String validErrorMessage = String.format("The sheet[%s],row[%s],column[%s],cell value[%s] not pass the number range '(,%s]' validation!" + , currentSheetIndex + 1, currentRowIndex + 1, cellIndex + 1, cellValue, range[1]); + return buildErrorMsg(cellIndex, cellValue, validErrorMessage); + + } else if (v > max || v <= min) { + String validErrorMessage = String.format("The sheet[%s],row[%s],column[%s],cell value[%s] not pass the number range '(%s,%s]' validation!" + , currentSheetIndex + 1, currentRowIndex + 1, cellIndex + 1, cellValue, range[0], range[1]); + return buildErrorMsg(cellIndex, cellValue, validErrorMessage); + + } + break; + case RANGE_RIGHT_OPEN: + if (null == max && v < min) { + String validErrorMessage = String.format("The sheet[%s],row[%s],column[%s],cell value[%s] not pass the number range '[%s,)' validation!" + , currentSheetIndex + 1, currentRowIndex + 1, cellIndex + 1, cellValue, range[0]); + return buildErrorMsg(cellIndex, cellValue, validErrorMessage); + } else if (null == min && v >= max) { + String validErrorMessage = String.format("The sheet[%s],row[%s],column[%s],cell value[%s] not pass the number range '[,%s)' validation!" + , currentSheetIndex + 1, currentRowIndex + 1, cellIndex + 1, cellValue, range[1]); + return buildErrorMsg(cellIndex, cellValue, validErrorMessage); + } else if (v >= max || v < min) { + String validErrorMessage = String.format("The sheet[%s],row[%s],column[%s],cell value[%s] not pass the number range '[%s,%s)' validation!" + , currentSheetIndex + 1, currentRowIndex + 1, cellIndex + 1, cellValue, range[0], range[1]); + return buildErrorMsg(cellIndex, cellValue, validErrorMessage); + } + break; + default: + } + return null; + } + + /** * cell type */ diff --git a/excel-tara/src/test/java/com/sondertara/ExcelTaraTest.java b/excel-tara/src/test/java/com/sondertara/ExcelTaraTest.java index 3305632..2b70960 100644 --- a/excel-tara/src/test/java/com/sondertara/ExcelTaraTest.java +++ b/excel-tara/src/test/java/com/sondertara/ExcelTaraTest.java @@ -80,7 +80,7 @@ public void importTest() throws Exception { CSVPrinter errorPrinter = CSVFormat.EXCEL.print(errorWriter); - ExcelTara.builder(new FileInputStream(new File("/Users/huangxiaohu/Desktop/保费结算导入结果/error.xlsx")), ImportParam.class) + ExcelTara.builder(new FileInputStream(new File("/Users/huangxiaohu/Desktop/7-9导入服务费金额有误数据.xlsx")), ImportParam.class) .importExcel(true, new ImportFunction