extends AbstractCell {
}
}
-
}
diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/metadata/data/ReadCellData.java b/easyexcel-core/src/main/java/com/alibaba/excel/metadata/data/ReadCellData.java
index e1bb57ca..9432e994 100644
--- a/easyexcel-core/src/main/java/com/alibaba/excel/metadata/data/ReadCellData.java
+++ b/easyexcel-core/src/main/java/com/alibaba/excel/metadata/data/ReadCellData.java
@@ -1,7 +1,9 @@
package com.alibaba.excel.metadata.data;
import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import com.alibaba.excel.constant.EasyExcelConstants;
import com.alibaba.excel.enums.CellDataTypeEnum;
import lombok.EqualsAndHashCode;
@@ -11,6 +13,7 @@ import lombok.Setter;
/**
* read cell data
+ *
*
* @author Jiaju Zhuang
*/
@@ -19,6 +22,29 @@ import lombok.Setter;
@EqualsAndHashCode
@NoArgsConstructor
public class ReadCellData extends CellData {
+
+ /**
+ * originalNumberValue vs numberValue
+ *
+ *
+ * NUMBER:
+ * originalNumberValue: Original data and the accuracy of his is 17, but in fact the excel only 15 precision to
+ * process the data
+ * numberValue: After correction of the data and the accuracy of his is 15
+ * for example, originalNumberValue = `2087.0249999999996` , numberValue = `2087.03`
+ *
+ *
+ * DATE:
+ * originalNumberValue: Storage is a data type double, accurate to milliseconds
+ * dateValue: Based on double converted to a date format, he will revised date difference, accurate to seconds
+ * for example, originalNumberValue = `44729.99998836806` ,time is:`2022-06-17 23:59:58.995`,
+ * But in excel is displayed:` 2022-06-17 23:59:59`, dateValue = `2022-06-17 23:59:59`
+ *
+ *
+ * {@link CellDataTypeEnum#NUMBER} {@link CellDataTypeEnum#DATE}
+ */
+ private BigDecimal originalNumberValue;
+
/**
* data format.
*/
@@ -107,11 +133,21 @@ public class ReadCellData extends CellData {
return cellData;
}
+ public static ReadCellData> newInstanceOriginal(BigDecimal numberValue, Integer rowIndex, Integer columnIndex) {
+ ReadCellData> cellData = new ReadCellData<>(numberValue);
+ cellData.setRowIndex(rowIndex);
+ cellData.setColumnIndex(columnIndex);
+ cellData.setOriginalNumberValue(numberValue);
+ cellData.setNumberValue(numberValue.round(EasyExcelConstants.EXCEL_MATH_CONTEXT));
+ return cellData;
+ }
+
@Override
public ReadCellData clone() {
ReadCellData readCellData = new ReadCellData<>();
readCellData.setType(getType());
readCellData.setNumberValue(getNumberValue());
+ readCellData.setOriginalNumberValue(getOriginalNumberValue());
readCellData.setStringValue(getStringValue());
readCellData.setBooleanValue(getBooleanValue());
readCellData.setData(getData());
@@ -123,5 +159,4 @@ public class ReadCellData extends CellData {
}
return readCellData;
}
-
}
diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/metadata/format/DataFormatter.java b/easyexcel-core/src/main/java/com/alibaba/excel/metadata/format/DataFormatter.java
index ba8fee47..1bd591e3 100644
--- a/easyexcel-core/src/main/java/com/alibaba/excel/metadata/format/DataFormatter.java
+++ b/easyexcel-core/src/main/java/com/alibaba/excel/metadata/format/DataFormatter.java
@@ -212,10 +212,10 @@ public class DataFormatter {
CellFormat cfmt = CellFormat.getInstance(locale, formatStr);
// CellFormat requires callers to identify date vs not, so do so
Object cellValueO = data;
- if (DateUtil.isADateFormat(dataFormat, formatStr) &&
+ if (DateUtils.isADateFormat(dataFormat, formatStr) &&
// don't try to handle Date value 0, let a 3 or 4-part format take care of it
data.doubleValue() != 0.0) {
- cellValueO = DateUtil.getJavaDate(data, use1904windowing);
+ cellValueO = DateUtils.getJavaDate(data, use1904windowing);
}
// Wrap and return (non-cachable - CellFormat does that)
return new CellFormatResultWrapper(cfmt.apply(cellValueO));
@@ -243,6 +243,8 @@ public class DataFormatter {
return format;
}
+
+
private Format createFormat(Short dataFormat, String dataFormatString) {
String formatStr = dataFormatString;
@@ -628,7 +630,7 @@ public class DataFormatter {
// Hint about the raw excel value
((ExcelStyleDateFormatter)dateFormat).setDateToBeFormatted(data);
}
- return performDateFormatting(DateUtil.getJavaDate(data, use1904windowing), dateFormat);
+ return performDateFormatting(DateUtils.getJavaDate(data, use1904windowing), dateFormat);
}
/**
diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/read/builder/ExcelReaderBuilder.java b/easyexcel-core/src/main/java/com/alibaba/excel/read/builder/ExcelReaderBuilder.java
index d2a24b44..59fd7e1f 100644
--- a/easyexcel-core/src/main/java/com/alibaba/excel/read/builder/ExcelReaderBuilder.java
+++ b/easyexcel-core/src/main/java/com/alibaba/excel/read/builder/ExcelReaderBuilder.java
@@ -13,6 +13,7 @@ import com.alibaba.excel.cache.ReadCache;
import com.alibaba.excel.cache.selector.ReadCacheSelector;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.enums.CellExtraTypeEnum;
+import com.alibaba.excel.enums.ReadDefaultReturnEnum;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.event.SyncReadListener;
import com.alibaba.excel.read.listener.ModelBuildEventListener;
@@ -198,6 +199,17 @@ public class ExcelReaderBuilder extends AbstractExcelReaderParameterBuilder> cellDataMap, ReadSheetHolder readSheetHolder,
+ private Object buildNoModel(Map> cellDataMap, ReadSheetHolder readSheetHolder,
AnalysisContext context) {
int index = 0;
- Map map = MapUtils.newLinkedHashMapWithExpectedSize(cellDataMap.size());
+ Map map = MapUtils.newLinkedHashMapWithExpectedSize(cellDataMap.size());
for (Map.Entry> entry : cellDataMap.entrySet()) {
Integer key = entry.getKey();
ReadCellData> cellData = entry.getValue();
@@ -48,9 +57,23 @@ public class ModelBuildEventListener implements IgnoreExceptionReadListener convertedReadCellData = convertReadCellData(cellData,
+ context.readWorkbookHolder().getReadDefaultReturn(), readSheetHolder, context, key);
+ if (readDefaultReturn == ReadDefaultReturnEnum.READ_CELL_DATA) {
+ map.put(key, convertedReadCellData);
+ } else {
+ map.put(key, convertedReadCellData.getData());
+ }
+ }
}
// fix https://github.com/alibaba/easyexcel/issues/2014
int headSize = calculateHeadSize(readSheetHolder);
@@ -61,6 +84,38 @@ public class ModelBuildEventListener implements IgnoreExceptionReadListener cellData, ReadDefaultReturnEnum readDefaultReturn,
+ ReadSheetHolder readSheetHolder, AnalysisContext context, Integer columnIndex) {
+ Class> classGeneric;
+ switch (cellData.getType()) {
+ case STRING:
+ case DIRECT_STRING:
+ case ERROR:
+ case EMPTY:
+ classGeneric = String.class;
+ break;
+ case BOOLEAN:
+ classGeneric = Boolean.class;
+ break;
+ case NUMBER:
+ DataFormatData dataFormatData = cellData.getDataFormatData();
+ if (dataFormatData != null && DateUtils.isADateFormat(dataFormatData.getIndex(),
+ dataFormatData.getFormat())) {
+ classGeneric = LocalDateTime.class;
+ } else {
+ classGeneric = BigDecimal.class;
+ }
+ break;
+ default:
+ classGeneric = ConverterUtils.defaultClassGeneric;
+ break;
+ }
+
+ return (ReadCellData)ConverterUtils.convertToJavaObject(cellData, null, ReadCellData.class,
+ classGeneric, null, readSheetHolder.converterMap(), context, context.readRowHolder().getRowIndex(),
+ columnIndex);
+ }
+
private int calculateHeadSize(ReadSheetHolder readSheetHolder) {
if (readSheetHolder.excelReadHeadProperty().getHeadMap().size() > 0) {
return readSheetHolder.excelReadHeadProperty().getHeadMap().size();
diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/ReadWorkbook.java b/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/ReadWorkbook.java
index 4f3a3aab..a3713d7c 100644
--- a/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/ReadWorkbook.java
+++ b/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/ReadWorkbook.java
@@ -11,6 +11,7 @@ import com.alibaba.excel.cache.ReadCache;
import com.alibaba.excel.cache.selector.ReadCacheSelector;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.enums.CellExtraTypeEnum;
+import com.alibaba.excel.enums.ReadDefaultReturnEnum;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.read.listener.ModelBuildEventListener;
import com.alibaba.excel.support.ExcelTypeEnum;
@@ -62,7 +63,6 @@ public class ReadWorkbook extends ReadBasicParameter {
/**
* This object can be read in the Listener {@link AnalysisEventListener#invoke(Object, AnalysisContext)}
* {@link AnalysisContext#getCustom()}
- *
*/
private Object customObject;
/**
@@ -96,8 +96,18 @@ public class ReadWorkbook extends ReadBasicParameter {
* Whether to use the default listener, which is used by default.
*
* The {@link ModelBuildEventListener} is loaded by default to convert the object.
+ * defualt is true.
*/
private Boolean useDefaultListener;
+
+ /**
+ * Read not to {@code com.alibaba.excel.metadata.BasicParameter#clazz} value, the default will return type.
+ * Is only effective when set `useDefaultListener=true` or `useDefaultListener=null`.
+ *
+ * @see ReadDefaultReturnEnum
+ */
+ private ReadDefaultReturnEnum readDefaultReturn;
+
/**
* Read some additional fields. None are read by default.
*
diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/ReadWorkbookHolder.java b/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/ReadWorkbookHolder.java
index a84cc315..63f8c1bf 100644
--- a/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/ReadWorkbookHolder.java
+++ b/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/ReadWorkbookHolder.java
@@ -14,6 +14,7 @@ import com.alibaba.excel.cache.selector.SimpleReadCacheSelector;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.enums.CellExtraTypeEnum;
import com.alibaba.excel.enums.HolderEnum;
+import com.alibaba.excel.enums.ReadDefaultReturnEnum;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelAnalysisException;
import com.alibaba.excel.read.metadata.ReadSheet;
@@ -64,10 +65,20 @@ public class ReadWorkbookHolder extends AbstractReadHolder {
* if false, Will transfer 'inputStream' to temporary files to improve efficiency
*/
private Boolean mandatoryUseInputStream;
+
/**
* Default true
*/
private Boolean autoCloseStream;
+
+ /**
+ * Read not to {@code com.alibaba.excel.metadata.BasicParameter#clazz} value, the default will return type.
+ * Is only effective when set `useDefaultListener=true` or `useDefaultListener=null`.
+ *
+ * @see ReadDefaultReturnEnum
+ */
+ private ReadDefaultReturnEnum readDefaultReturn;
+
/**
* Excel type
*/
@@ -146,6 +157,12 @@ public class ReadWorkbookHolder extends AbstractReadHolder {
this.autoCloseStream = readWorkbook.getAutoCloseStream();
}
+ if (readWorkbook.getReadDefaultReturn() == null) {
+ this.readDefaultReturn = ReadDefaultReturnEnum.STRING;
+ } else {
+ this.readDefaultReturn = readWorkbook.getReadDefaultReturn();
+ }
+
this.customObject = readWorkbook.getCustomObject();
if (readWorkbook.getIgnoreEmptyRow() == null) {
this.ignoreEmptyRow = Boolean.TRUE;
diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/util/ConverterUtils.java b/easyexcel-core/src/main/java/com/alibaba/excel/util/ConverterUtils.java
index 02ea4a00..6359a99d 100644
--- a/easyexcel-core/src/main/java/com/alibaba/excel/util/ConverterUtils.java
+++ b/easyexcel-core/src/main/java/com/alibaba/excel/util/ConverterUtils.java
@@ -84,24 +84,52 @@ public class ConverterUtils {
public static Object convertToJavaObject(ReadCellData> cellData, Field field,
ExcelContentProperty contentProperty, Map> converterMap, AnalysisContext context,
Integer rowIndex, Integer columnIndex) {
- Class> clazz;
- if (field == null) {
- clazz = String.class;
- } else {
- clazz = field.getType();
+ return convertToJavaObject(cellData, field, null, null, contentProperty, converterMap, context, rowIndex,
+ columnIndex);
+ }
+
+ /**
+ * Convert it into a Java object
+ *
+ * @param cellData
+ * @param field
+ * @param clazz
+ * @param contentProperty
+ * @param converterMap
+ * @param context
+ * @param rowIndex
+ * @param columnIndex
+ * @return
+ */
+ public static Object convertToJavaObject(ReadCellData> cellData, Field field, Class> clazz,
+ Class> classGeneric, ExcelContentProperty contentProperty, Map> converterMap,
+ AnalysisContext context, Integer rowIndex, Integer columnIndex) {
+ if (clazz == null) {
+ if (field == null) {
+ clazz = String.class;
+ } else {
+ clazz = field.getType();
+ }
}
if (clazz == CellData.class || clazz == ReadCellData.class) {
- Class> classGeneric = getClassGeneric(field.getGenericType());
ReadCellData cellDataReturn = cellData.clone();
- cellDataReturn.setData(doConvertToJavaObject(cellData, classGeneric, contentProperty, converterMap,
- context, rowIndex, columnIndex));
+ cellDataReturn.setData(
+ doConvertToJavaObject(cellData, getClassGeneric(field, classGeneric), contentProperty,
+ converterMap, context, rowIndex, columnIndex));
return cellDataReturn;
}
return doConvertToJavaObject(cellData, clazz, contentProperty, converterMap, context, rowIndex,
columnIndex);
}
- private static Class> getClassGeneric(Type type) {
+ private static Class> getClassGeneric(Field field, Class> classGeneric) {
+ if (classGeneric != null) {
+ return classGeneric;
+ }
+ if (field == null) {
+ return defaultClassGeneric;
+ }
+ Type type = field.getGenericType();
if (!(type instanceof ParameterizedType)) {
return defaultClassGeneric;
}
diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/util/DateUtils.java b/easyexcel-core/src/main/java/com/alibaba/excel/util/DateUtils.java
index 22d7f3d9..fb19a105 100644
--- a/easyexcel-core/src/main/java/com/alibaba/excel/util/DateUtils.java
+++ b/easyexcel-core/src/main/java/com/alibaba/excel/util/DateUtils.java
@@ -1,9 +1,11 @@
package com.alibaba.excel.util;
+import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
+import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
@@ -11,6 +13,8 @@ import java.util.Locale;
import java.util.Map;
import java.util.regex.Pattern;
+import org.apache.poi.ss.usermodel.DateUtil;
+
/**
* Date utils
*
@@ -184,6 +188,33 @@ public class DateUtils {
}
}
+ /**
+ * Format date
+ *
+ * @param date
+ * @param dateFormat
+ * @return
+ */
+ public static String format(LocalDateTime date, String dateFormat) {
+ return format(date, dateFormat, null);
+ }
+
+ /**
+ * Format date
+ *
+ * @param date
+ * @param dateFormat
+ * @return
+ */
+ public static String format(BigDecimal date, Boolean use1904windowing, String dateFormat) {
+ if (date == null) {
+ return null;
+ }
+ LocalDateTime localDateTime = DateUtil.getLocalDateTime(date.doubleValue(),
+ BooleanUtils.isTrue(use1904windowing), true);
+ return format(localDateTime, dateFormat);
+ }
+
private static DateFormat getCacheDateFormat(String dateFormat) {
Map dateFormatMap = DATE_FORMAT_THREAD_LOCAL.get();
if (dateFormatMap == null) {
@@ -200,6 +231,46 @@ public class DateUtils {
return simpleDateFormat;
}
+ /**
+ * Given an Excel date with either 1900 or 1904 date windowing,
+ * converts it to a java.util.Date.
+ *
+ * Excel Dates and Times are stored without any timezone
+ * information. If you know (through other means) that your file
+ * uses a different TimeZone to the system default, you can use
+ * this version of the getJavaDate() method to handle it.
+ *
+ * @param date The Excel date.
+ * @param use1904windowing true if date uses 1904 windowing,
+ * or false if using 1900 date windowing.
+ * @return Java representation of the date, or null if date is not a valid Excel date
+ */
+ public static Date getJavaDate(double date, boolean use1904windowing) {
+ //To calculate the Date, in the use of `org.apache.poi.ss.usermodel.DateUtil.getJavaDate(double, boolean,
+ // java.util.TimeZone, boolean), Date when similar `2023-01-01 00:00:00.500`, returns the`2023-01-01
+ // 00:00:01`, but excel in fact shows the `2023-01-01 00:00:00`.
+ // `org.apache.poi.ss.usermodel.DateUtil.getLocalDateTime(double, boolean, boolean)` There is no problem.
+ return Date.from(getLocalDateTime(date, use1904windowing).atZone(ZoneId.systemDefault()).toInstant());
+ }
+
+ /**
+ * Given an Excel date with either 1900 or 1904 date windowing,
+ * converts it to a java.time.LocalDateTime.
+ *
+ * Excel Dates and Times are stored without any timezone
+ * information. If you know (through other means) that your file
+ * uses a different TimeZone to the system default, you can use
+ * this version of the getJavaDate() method to handle it.
+ *
+ * @param date The Excel date.
+ * @param use1904windowing true if date uses 1904 windowing,
+ * or false if using 1900 date windowing.
+ * @return Java representation of the date, or null if date is not a valid Excel date
+ */
+ public static LocalDateTime getLocalDateTime(double date, boolean use1904windowing) {
+ return DateUtil.getLocalDateTime(date, use1904windowing, true);
+ }
+
/**
* Determine if it is a date format.
*
diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/compatibility/CompatibilityTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/compatibility/CompatibilityTest.java
index eadfd0a8..f4aae4a8 100644
--- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/compatibility/CompatibilityTest.java
+++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/compatibility/CompatibilityTest.java
@@ -1,10 +1,13 @@
package com.alibaba.easyexcel.test.core.compatibility;
+import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import com.alibaba.easyexcel.test.util.TestFileUtil;
import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.constant.EasyExcelConstants;
+import com.alibaba.excel.enums.ReadDefaultReturnEnum;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
@@ -64,4 +67,53 @@ public class CompatibilityTest {
Map row0 = list.get(0);
Assert.assertEquals("QQSJK28F152A012242S0081", row0.get(5));
}
+
+ @Test
+ public void t05() {
+ // https://github.com/alibaba/easyexcel/issues/1956
+ // Excel read date needs to be rounded
+ List> list = EasyExcel
+ .read(TestFileUtil.getPath() + "compatibility/t05.xlsx")
+ .sheet()
+ .doReadSync();
+ log.info("data:{}", JSON.toJSONString(list));
+ Assert.assertEquals("2023-01-01 00:00:00", list.get(0).get(0));
+ Assert.assertEquals("2023-01-01 00:00:00", list.get(1).get(0));
+ Assert.assertEquals("2023-01-01 00:00:00", list.get(2).get(0));
+ Assert.assertEquals("2023-01-01 00:00:01", list.get(3).get(0));
+ Assert.assertEquals("2023-01-01 00:00:01", list.get(4).get(0));
+ }
+
+ @Test
+ public void t06() {
+ // Keep error precision digital format
+ List> list = EasyExcel
+ .read(TestFileUtil.getPath() + "compatibility/t06.xlsx")
+ .headRowNumber(0)
+ .sheet()
+ .doReadSync();
+ log.info("data:{}", JSON.toJSONString(list));
+ Assert.assertEquals("2087.03", list.get(0).get(2));
+ }
+
+ @Test
+ public void t07() {
+ // https://github.com/alibaba/easyexcel/issues/2805
+ // Excel read date needs to be rounded
+ List> list = EasyExcel
+ .read(TestFileUtil.getPath() + "compatibility/t07.xlsx")
+ .readDefaultReturn(ReadDefaultReturnEnum.ACTUAL_DATA)
+ .sheet()
+ .doReadSync();
+ log.info("data:{}", JSON.toJSONString(list));
+ Assert.assertEquals(0, new BigDecimal("24.1998124").compareTo((BigDecimal)list.get(0).get(11)));
+
+ list = EasyExcel
+ .read(TestFileUtil.getPath() + "compatibility/t07.xlsx")
+ .sheet()
+ .doReadSync();
+ log.info("data:{}", JSON.toJSONString(list));
+ Assert.assertEquals("24.20", list.get(0).get(11));
+ }
+
}
diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/nomodel/NoModelDataTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/nomodel/NoModelDataTest.java
index 262ae35d..5abbcba7 100644
--- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/nomodel/NoModelDataTest.java
+++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/nomodel/NoModelDataTest.java
@@ -1,14 +1,20 @@
package com.alibaba.easyexcel.test.core.nomodel;
import java.io.File;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.alibaba.easyexcel.test.util.TestFileUtil;
import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.enums.ReadDefaultReturnEnum;
+import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.util.DateUtils;
+import com.alibaba.fastjson2.JSON;
+import lombok.extern.slf4j.Slf4j;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
@@ -19,6 +25,7 @@ import org.junit.runners.MethodSorters;
* @author Jiaju Zhuang
*/
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@Slf4j
public class NoModelDataTest {
private static File file07;
@@ -28,7 +35,6 @@ public class NoModelDataTest {
private static File fileRepeat03;
private static File fileRepeatCsv;
-
@BeforeClass
public static void init() {
file07 = TestFileUtil.createNewFile("noModel07.xlsx");
@@ -41,20 +47,20 @@ public class NoModelDataTest {
@Test
public void t01ReadAndWrite07() throws Exception {
- readAndWrite(file07, fileRepeat07);
+ readAndWrite(file07, fileRepeat07, false);
}
@Test
public void t02ReadAndWrite03() throws Exception {
- readAndWrite(file03, fileRepeat03);
+ readAndWrite(file03, fileRepeat03, false);
}
@Test
public void t03ReadAndWriteCsv() throws Exception {
- readAndWrite(fileCsv, fileRepeatCsv);
+ readAndWrite(fileCsv, fileRepeatCsv, true);
}
- private void readAndWrite(File file, File fileRepeat) throws Exception {
+ private void readAndWrite(File file, File fileRepeat, boolean isCsv) throws Exception {
EasyExcel.write(file).sheet().doWrite(data());
List> result = EasyExcel.read(file).headRowNumber(0).sheet().doReadSync();
Assert.assertEquals(10, result.size());
@@ -63,6 +69,42 @@ public class NoModelDataTest {
Assert.assertEquals("109", data10.get(1));
Assert.assertEquals("2020-01-01 01:01:01", data10.get(2));
+ List> actualDataList = EasyExcel.read(file)
+ .headRowNumber(0)
+ .readDefaultReturn(ReadDefaultReturnEnum.ACTUAL_DATA)
+ .sheet()
+ .doReadSync();
+ log.info("actualDataList:{}", JSON.toJSONString(actualDataList));
+ Assert.assertEquals(10, actualDataList.size());
+ Map actualData10 = actualDataList.get(9);
+ Assert.assertEquals("string19", actualData10.get(0));
+ if (isCsv) {
+ // CSV only string type
+ Assert.assertEquals("109", actualData10.get(1));
+ Assert.assertEquals("2020-01-01 01:01:01", actualData10.get(2));
+ } else {
+ Assert.assertEquals(0, new BigDecimal("109").compareTo((BigDecimal)actualData10.get(1)));
+ Assert.assertEquals(LocalDateTime.of(2020, 1, 1, 1, 1, 1), actualData10.get(2));
+ }
+
+ List>> readCellDataList = EasyExcel.read(file)
+ .headRowNumber(0)
+ .readDefaultReturn(ReadDefaultReturnEnum.READ_CELL_DATA)
+ .sheet()
+ .doReadSync();
+ log.info("readCellDataList:{}", JSON.toJSONString(readCellDataList));
+ Assert.assertEquals(10, readCellDataList.size());
+ Map> readCellData10 = readCellDataList.get(9);
+ Assert.assertEquals("string19", readCellData10.get(0).getData());
+ if (isCsv) {
+ // CSV only string type
+ Assert.assertEquals("109", readCellData10.get(1).getData());
+ Assert.assertEquals("2020-01-01 01:01:01", readCellData10.get(2).getData());
+ } else {
+ Assert.assertEquals(0, new BigDecimal("109").compareTo((BigDecimal)readCellData10.get(1).getData()));
+ Assert.assertEquals(LocalDateTime.of(2020, 1, 1, 1, 1, 1), readCellData10.get(2).getData());
+ }
+
EasyExcel.write(fileRepeat).sheet().doWrite(result);
result = EasyExcel.read(fileRepeat).headRowNumber(0).sheet().doReadSync();
Assert.assertEquals(10, result.size());
diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/DemoData.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/DemoData.java
index 76b50584..fc3079a1 100644
--- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/DemoData.java
+++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/DemoData.java
@@ -24,6 +24,7 @@ public class DemoData {
private Date date;
@ExcelProperty("数字标题")
private Double doubleData;
+
/**
* 忽略这个字段
*/
diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/DemoData2.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/DemoData2.java
new file mode 100644
index 00000000..98693438
--- /dev/null
+++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/DemoData2.java
@@ -0,0 +1,35 @@
+package com.alibaba.easyexcel.test.temp;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.ExcelProperty;
+
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 基础数据类
+ *
+ * @author Jiaju Zhuang
+ **/
+@Getter
+@Setter
+@EqualsAndHashCode
+public class DemoData2 {
+ @ExcelProperty("字符串标题")
+ private String string;
+ @ExcelProperty("日期标题")
+ private Date date;
+ @ExcelProperty("数字标题")
+ private Double doubleData;
+ @ExcelProperty("数字标题2")
+ private BigDecimal bigDecimal;
+ /**
+ * 忽略这个字段
+ */
+ @ExcelIgnore
+ private String ignore;
+}
diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/DemoData3.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/DemoData3.java
new file mode 100644
index 00000000..0be8ec7a
--- /dev/null
+++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/DemoData3.java
@@ -0,0 +1,24 @@
+package com.alibaba.easyexcel.test.temp;
+
+import java.time.LocalDateTime;
+import java.util.Date;
+
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.ExcelProperty;
+
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 基础数据类
+ *
+ * @author Jiaju Zhuang
+ **/
+@Getter
+@Setter
+@EqualsAndHashCode
+public class DemoData3 {
+ @ExcelProperty("日期时间标题")
+ private LocalDateTime localDateTime;
+}
diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/Lock2Test.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/Lock2Test.java
index 63141ba4..8a782bbe 100644
--- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/Lock2Test.java
+++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/Lock2Test.java
@@ -1,32 +1,49 @@
package com.alibaba.easyexcel.test.temp;
import java.io.File;
+import java.math.BigDecimal;
+import java.math.MathContext;
+import java.math.RoundingMode;
+import java.text.DecimalFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
+import java.util.Map;
import com.alibaba.easyexcel.test.demo.write.DemoData;
import com.alibaba.easyexcel.test.util.TestFileUtil;
import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.metadata.data.ReadCellData;
+import com.alibaba.excel.util.NumberDataFormatterUtils;
+import com.alibaba.excel.util.NumberUtils;
import com.alibaba.excel.util.PositionUtils;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.fastjson.JSON;
+import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.hssf.util.CellReference;
+import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.IndexedColors;
+import org.junit.Assert;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.util.StringUtils;
/**
* 临时测试
*
* @author Jiaju Zhuang
**/
+@Slf4j
public class Lock2Test {
private static final Logger LOGGER = LoggerFactory.getLogger(Lock2Test.class);
@@ -37,7 +54,11 @@ public class Lock2Test {
// File file = TestFileUtil.readUserHomeFile("test/test6.xls");
File file = new File("/Users/zhuangjiaju/IdeaProjects/easyexcel/src/test/resources/converter/converter07.xlsx");
- List list = EasyExcel.read("/Users/zhuangjiaju/Downloads/测试格式.xlsx").sheet(0).headRowNumber(0).doReadSync();
+ List list = EasyExcel.read(
+ "/Users/zhuangjiaju/IdeaProjects/easyexcel/easyexcel-test/target/test-classes/simpleWrite1674051907397.xlsx")
+ //.useDefaultListener(false)
+ .sheet(0)
+ .headRowNumber(0).doReadSync();
LOGGER.info("数据:{}", list.size());
for (Object data : list) {
LOGGER.info("返回数据:{}", CollectionUtils.size(data));
@@ -109,18 +130,6 @@ public class Lock2Test {
return list;
}
- private List data() {
- List list = new ArrayList();
- for (int i = 0; i < 10; i++) {
- DemoData data = new DemoData();
- data.setString("字符串" + i);
- data.setDate(new Date());
- data.setDoubleData(0.56);
- list.add(data);
- }
- return list;
- }
-
@Test
public void testc() throws Exception {
LOGGER.info("reslut:{}", JSON.toJSONString(new CellReference("B3")));
@@ -151,10 +160,9 @@ public class Lock2Test {
@Test
public void test335() throws Exception {
-
- LOGGER.info("reslut:{}", PositionUtils.getCol("A10",null));
+ LOGGER.info("reslut:{}", PositionUtils.getCol("A10", null));
LOGGER.info("reslut:{}", PositionUtils.getRow("A10"));
- LOGGER.info("reslut:{}", PositionUtils.getCol("AB10",null));
+ LOGGER.info("reslut:{}", PositionUtils.getCol("AB10", null));
LOGGER.info("reslut:{}", PositionUtils.getRow("AB10"));
//LOGGER.info("reslut:{}", PositionUtils2.getCol("A10",null));
@@ -163,5 +171,279 @@ public class Lock2Test {
//LOGGER.info("reslut:{}", PositionUtils2.getRow("AB10"));
}
+ @Test
+ public void numberforamt() throws Exception {
+ SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+
+ //LOGGER.info("date:{}",
+ // NumberDataFormatterUtils.format(BigDecimal.valueOf(44727.99998842592), (short)200, "yyyy-MM-dd HH:mm:ss",
+ // null,
+ // null, null));
+ //
+ //LOGGER.info("date:{}",
+ // NumberDataFormatterUtils.format(BigDecimal.valueOf(44728.99998842592), (short)200, "yyyy-MM-dd HH:mm:ss",
+ // null,
+ // null, null));
+ //
+ //LOGGER.info("date:{}",
+ // NumberDataFormatterUtils.format(BigDecimal.valueOf(44729.99998836806), (short)200, "yyyy-MM-dd HH:mm:ss",
+ // null,
+ // null, null));
+ //
+ //LOGGER.info("date:{}",
+ // NumberDataFormatterUtils.format(BigDecimal.valueOf(44727.99998842592).setScale(10, RoundingMode
+ // .HALF_UP), (short)200, "yyyy-MM-dd HH:mm:ss",
+ // null,
+ // null, null));
+ //
+ //LOGGER.info("date:{}",
+ // NumberDataFormatterUtils.format(BigDecimal.valueOf(44728.99998842592).setScale(10, RoundingMode
+ // .HALF_UP), (short)200, "yyyy-MM-dd HH:mm:ss",
+ // null,
+ // null, null));
+
+ //44729.9999883681
+ //44729.999988368058
+ //LOGGER.info("date:{}",
+ // NumberDataFormatterUtils.format(BigDecimal.valueOf(44729.999988368058).setScale(10, RoundingMode
+ // .HALF_UP), (short)200, "yyyy-MM-dd HH:mm:ss",
+ // null,
+ // null, null));
+ //LOGGER.info("date:{}",BigDecimal.valueOf(44729.999988368058).setScale(10, RoundingMode.HALF_UP).doubleValue
+ // ());
+
+ // 2022/6/17 23:59:59
+ // 期望 44729.99998842592
+ //LOGGER.info("data:{}", DateUtil.getJavaDate(44729.9999883681, true));
+ LOGGER.info("data4:{}", DateUtil.getJavaDate(BigDecimal.valueOf(44729.999988368058)
+ .setScale(4, RoundingMode.HALF_UP).doubleValue(), false));
+ LOGGER.info("data5:{}", DateUtil.getJavaDate(BigDecimal.valueOf(44729.999988368058)
+ .setScale(5, RoundingMode.HALF_UP).doubleValue(), false));
+ LOGGER.info("data6:{}", DateUtil.getJavaDate(BigDecimal.valueOf(44729.999988368058)
+ .setScale(6, RoundingMode.HALF_UP).doubleValue(), false));
+ LOGGER.info("data7:{}", DateUtil.getJavaDate(BigDecimal.valueOf(44729.999988368058)
+ .setScale(7, RoundingMode.HALF_UP).doubleValue(), false));
+ LOGGER.info("data8:{}", DateUtil.getJavaDate(BigDecimal.valueOf(44729.999988368058)
+ .setScale(8, RoundingMode.HALF_UP).doubleValue(), false));
+
+ LOGGER.info("data:{}", format.format(DateUtil.getJavaDate(44729.999988368058, false)));
+ LOGGER.info("data:{}", format.format(DateUtil.getJavaDate(44729.9999883681, false)));
+
+ LOGGER.info("data:{}", DateUtil.getJavaDate(Double.parseDouble("44729.999988368058"), false));
+ LOGGER.info("data:{}", DateUtil.getJavaDate(Double.parseDouble("44729.9999883681"), false));
+
+ // 44729.999976851854
+ // 44729.999988368058
+ LOGGER.info("data:{}", DateUtil.getExcelDate(format.parse("2022-06-17 23:59:58")));
+ // 44729.99998842592
+ LOGGER.info("data:{}", DateUtil.getExcelDate(format.parse("2022-06-17 23:59:59")));
+
+ LOGGER.info("data:{}", DateUtil.getJavaDate(BigDecimal.valueOf(44729.999976851854)
+ .setScale(10, RoundingMode.HALF_UP).doubleValue(), false));
+ LOGGER.info("data:{}", DateUtil.getJavaDate(BigDecimal.valueOf(44729.99998842592)
+ .setScale(10, RoundingMode.HALF_UP).doubleValue(), false));
+
+ LOGGER.info("data:{}", DateUtil.getJavaDate(BigDecimal.valueOf(44729.999976851854)
+ .setScale(5, RoundingMode.HALF_UP).doubleValue(), false));
+ LOGGER.info("data:{}", DateUtil.getJavaDate(BigDecimal.valueOf(44729.99998842592)
+ .setScale(5, RoundingMode.HALF_UP).doubleValue(), false));
+ }
+
+ @Test
+ public void testDate() throws Exception {
+ SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ log.info("TT:{}", format.format(new Date(100L)));
+ log.info("TT:{}", new Date().getTime());
+ }
+
+ @Test
+ public void testDateAll() throws Exception {
+ SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ SimpleDateFormat format2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+
+ long dateTime = 0L;
+ while (true) {
+ Date date = new Date(dateTime);
+ double excelDate = DateUtil.getExcelDate(date);
+
+ Assert.assertEquals("测试基本转换错误" + dateTime, format.format(date),
+ format.format(DateUtil.getJavaDate(excelDate, false)));
+ Assert.assertEquals("测试精度5转换错误" + dateTime, format.format(date),
+ format.format(DateUtil.getJavaDate(BigDecimal.valueOf(excelDate)
+ .setScale(10, RoundingMode.HALF_UP).doubleValue(), false)));
+ LOGGER.info("date:{}", format2.format(DateUtil.getJavaDate(BigDecimal.valueOf(excelDate)
+ .setScale(10, RoundingMode.HALF_UP).doubleValue())));
+ dateTime += 1000L;
+ // 30天输出
+ if (dateTime % (24 * 60 * 60 * 1000) == 0) {
+ log.info("{}成功", format.format(date));
+ }
+ if (dateTime > 1673957544750L) {
+ log.info("结束啦");
+ break;
+ }
+ }
+ log.info("结束啦");
+
+ }
+
+ @Test
+ public void numberforamt3() throws Exception {
+ SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+
+ List> list = EasyExcel.read("/Users/zhuangjiaju/Downloads/date3.xlsx")
+ .useDefaultListener(false)
+ .sheet(0)
+ .headRowNumber(0).doReadSync();
+ LOGGER.info("数据:{}", list.size());
+ for (Map readCellDataMap : list) {
+ ReadCellData data = readCellDataMap.get(0);
+ LOGGER.info("data:{}", format.format(
+ DateUtil.getJavaDate(data.getNumberValue().setScale(10, RoundingMode.HALF_UP).doubleValue(), false)));
+
+ }
+ //
+ //LOGGER.info("data:{}", format.format(DateUtil.getJavaDate(44727.999988425923, false)));
+ //LOGGER.info("data:{}", format.format(DateUtil.getJavaDate(44729.999988368058, false)));
+
+ }
+
+ @Test
+ public void numberforamt4() throws Exception {
+ String fileName = TestFileUtil.getPath() + "simpleWrite" + System.currentTimeMillis() + ".xlsx";
+ // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
+ // 如果这里想使用03 则 传入excelType参数即可
+ EasyExcel.write(fileName, DemoData.class)
+ .sheet("模板")
+ .doWrite(() -> {
+ // 分页查询数据
+ return data2();
+ });
+
+ }
+
+ @Test
+ public void numberforamt77() throws Exception {
+ String fileName = TestFileUtil.getPath() + "simpleWrite" + System.currentTimeMillis() + ".xlsx";
+ // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
+ // 如果这里想使用03 则 传入excelType参数即可
+ EasyExcel.write(fileName, DemoData3.class)
+ .sheet("模板")
+ .doWrite(() -> {
+ List list = new ArrayList<>();
+ DemoData3 demoData3 = new DemoData3();
+ demoData3.setLocalDateTime(LocalDateTime.of(2023, 1, 1, 0, 0, 0, 400000000));
+ list.add(demoData3);
+ demoData3 = new DemoData3();
+ demoData3.setLocalDateTime(LocalDateTime.of(2023, 1, 1, 0, 0, 0, 499000000));
+ list.add(demoData3);
+ demoData3 = new DemoData3();
+ demoData3.setLocalDateTime(LocalDateTime.of(2023, 1, 1, 0, 0, 0, 500000000));
+ list.add(demoData3);
+ demoData3 = new DemoData3();
+ demoData3.setLocalDateTime(LocalDateTime.of(2023, 1, 1, 0, 0, 0, 501000000));
+ list.add(demoData3);
+ demoData3 = new DemoData3();
+ demoData3.setLocalDateTime(LocalDateTime.of(2023, 1, 1, 0, 0, 0, 995000000));
+ list.add(demoData3);
+ return list;
+ });
+
+ }
+
+ @Test
+ public void numberforamt99() throws Exception {
+ LocalDateTime localDateTime=LocalDateTime.of(2023, 1, 1, 0, 0, 0, 995000000);
+ log.info("date:{}",localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")));
+
+
+ }
+
+ @Test
+ public void numberforamt5() throws Exception {
+ String fileName = TestFileUtil.getPath() + "simpleWrite" + System.currentTimeMillis() + ".xlsx";
+ // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
+ // 如果这里想使用03 则 传入excelType参数即可
+ EasyExcel.write(fileName, DemoData.class)
+ .sheet("模板")
+ .doWrite(() -> {
+ // 分页查询数据
+ return data3();
+ });
+
+ }
+
+ @Test
+ public void numberforamt6() throws Exception {
+ DecimalFormat decimalFormat = new DecimalFormat("#.#");
+ BigDecimal bigDecimal = new BigDecimal(3101011021236149800L);
+ log.info("b:{}", bigDecimal);
+ log.info("b:{}", bigDecimal.setScale(-4, RoundingMode.HALF_UP));
+ log.info("b:{}", decimalFormat.format(bigDecimal.setScale(-4, RoundingMode.HALF_UP)));
+
+ }
+
+ @Test
+ public void numberforamt7() throws Exception {
+ DecimalFormat decimalFormat = new DecimalFormat("#.#");
+ BigDecimal bigDecimal = new BigDecimal(3.1010110212361498E+18).round(new MathContext(15, RoundingMode.HALF_UP));
+ //bigDecimal.
+
+ // bigDecimal
+ log.info("b:{}", bigDecimal);
+ log.info("b:{}", bigDecimal.setScale(-4, RoundingMode.HALF_UP));
+ log.info("b:{}", decimalFormat.format(bigDecimal.setScale(-4, RoundingMode.HALF_UP)));
+ log.info("b:{}", decimalFormat.format(bigDecimal));
+
+ }
+
+ private List data3() {
+ SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+
+ List list = new ArrayList<>();
+ for (int i = 0; i < 10; i++) {
+ DemoData2 data = new DemoData2();
+ data.setString("字符串" + i);
+ data.setDoubleData(0.56);
+ data.setBigDecimal(BigDecimal.valueOf(3101011021236149800L));
+ list.add(data);
+ }
+ return list;
+ }
+
+ private List data() {
+ SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+ List list = new ArrayList();
+ for (int i = 0; i < 10; i++) {
+ DemoData data = new DemoData();
+ data.setString("字符串" + i);
+ try {
+ data.setDate(format.parse("2032-01-18 09:00:01.995"));
+ } catch (ParseException e) {
+ throw new RuntimeException(e);
+ }
+ data.setDoubleData(0.56);
+ list.add(data);
+ }
+ return list;
+ }
+
+ private List data2() {
+ SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+
+ List list = new ArrayList();
+ for (int i = 0; i < 10; i++) {
+ DemoData data = new DemoData();
+ data.setString("字符串" + i);
+ try {
+ data.setDate(format.parse("2032-01-18 09:00:00."));
+ } catch (ParseException e) {
+ throw new RuntimeException(e);
+ }
+ data.setDoubleData(0.56);
+ list.add(data);
+ }
+ return list;
+ }
}
diff --git a/easyexcel-test/src/test/resources/compatibility/t05.xlsx b/easyexcel-test/src/test/resources/compatibility/t05.xlsx
new file mode 100644
index 00000000..248ec7d1
Binary files /dev/null and b/easyexcel-test/src/test/resources/compatibility/t05.xlsx differ
diff --git a/easyexcel-test/src/test/resources/compatibility/t06.xlsx b/easyexcel-test/src/test/resources/compatibility/t06.xlsx
new file mode 100644
index 00000000..b27be027
Binary files /dev/null and b/easyexcel-test/src/test/resources/compatibility/t06.xlsx differ
diff --git a/easyexcel-test/src/test/resources/compatibility/t07.xlsx b/easyexcel-test/src/test/resources/compatibility/t07.xlsx
new file mode 100644
index 00000000..a7b0eac7
Binary files /dev/null and b/easyexcel-test/src/test/resources/compatibility/t07.xlsx differ
diff --git a/pom.xml b/pom.xml
index de5d0681..70153a8e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -20,7 +20,7 @@
- 3.1.5
+ 3.2.0
UTF-8
1.8
true
diff --git a/update.md b/update.md
index 782e7a80..36c98000 100644
--- a/update.md
+++ b/update.md
@@ -1,3 +1,9 @@
+# 3.2.0
+
+* 修复部分xlsx读取日期可能相差1秒的bug [Issue #1956](https://github.com/alibaba/easyexcel/issues/1956)
+* 修复部分数据精度和excel不匹配的bug [Issue #2805](https://github.com/alibaba/easyexcel/issues/2805)
+* 不创建对象的读支持读取原始的数据类型
+
# 3.1.5
* 提高xlsx读取兼容性:兼用ns2开头的标签