From 2a17919caabd8cf257be31b43f91bc94252f8fb1 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 18 Jan 2023 11:02:29 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E6=B5=8B=E8=AF=95big?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../analysis/v07/handlers/CellTagHandler.java | 2 +- .../easyexcel/test/temp/Lock2Test.java | 221 ++++++++++++++++-- 2 files changed, 207 insertions(+), 16 deletions(-) diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java index ce84d5e2..67218348 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java @@ -88,7 +88,7 @@ public class CellTagHandler extends AbstractXlsxTagHandler { break; } tempCellData.setType(CellDataTypeEnum.NUMBER); - tempCellData.setNumberValue(BigDecimal.valueOf(Double.parseDouble(tempDataString))); + tempCellData.setNumberValue(new BigDecimal(tempDataString)); break; default: throw new IllegalStateException("Cannot set values now"); 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..9841d2b2 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,45 @@ package com.alibaba.easyexcel.test.temp; import java.io.File; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.text.ParseException; +import java.text.SimpleDateFormat; 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 +50,10 @@ 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/Downloads/number1x.xls") + //.useDefaultListener(false) + .sheet(0) + .headRowNumber(0).doReadSync(); LOGGER.info("数据:{}", list.size()); for (Object data : list) { LOGGER.info("返回数据:{}", CollectionUtils.size(data)); @@ -109,17 +125,7 @@ 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 { @@ -151,10 +157,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 +168,191 @@ 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(); + }); + + } + + 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; + } } From b92c40554704ae3182847ad4a9938b052744c800 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 18 Jan 2023 23:23:14 +0800 Subject: [PATCH 2/2] =?UTF-8?q?*=20=E4=BF=AE=E5=A4=8D=E9=83=A8=E5=88=86xls?= =?UTF-8?q?x=E8=AF=BB=E5=8F=96=E6=97=A5=E6=9C=9F=E5=8F=AF=E8=83=BD?= =?UTF-8?q?=E7=9B=B8=E5=B7=AE1=E7=A7=92=E7=9A=84bug=20[Issue=20#1956](http?= =?UTF-8?q?s://github.com/alibaba/easyexcel/issues/1956)=20*=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E9=83=A8=E5=88=86=E6=95=B0=E6=8D=AE=E7=B2=BE=E5=BA=A6?= =?UTF-8?q?=E5=92=8Cexcel=E4=B8=8D=E5=8C=B9=E9=85=8D=E7=9A=84bug=20[Issue?= =?UTF-8?q?=20#2805](https://github.com/alibaba/easyexcel/issues/2805)=20*?= =?UTF-8?q?=20=E4=B8=8D=E5=88=9B=E5=BB=BA=E5=AF=B9=E8=B1=A1=E7=9A=84?= =?UTF-8?q?=E8=AF=BB=E6=94=AF=E6=8C=81=E8=AF=BB=E5=8F=96=E9=9D=9E`String`?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E7=9A=84=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- .../v03/handlers/FormulaRecordHandler.java | 5 +- .../v03/handlers/NumberRecordHandler.java | 3 +- .../analysis/v07/handlers/CellTagHandler.java | 5 +- .../excel/constant/EasyExcelConstants.java | 19 ++++ .../converters/date/DateNumberConverter.java | 9 +- .../LocalDateNumberConverter.java | 5 +- .../string/StringNumberConverter.java | 5 +- .../excel/enums/ReadDefaultReturnEnum.java | 40 +++++++ .../alibaba/excel/metadata/data/CellData.java | 3 +- .../excel/metadata/data/ReadCellData.java | 37 +++++- .../excel/metadata/format/DataFormatter.java | 8 +- .../read/builder/ExcelReaderBuilder.java | 12 ++ .../listener/ModelBuildEventListener.java | 69 +++++++++-- .../excel/read/metadata/ReadWorkbook.java | 12 +- .../metadata/holder/ReadWorkbookHolder.java | 17 +++ .../alibaba/excel/util/ConverterUtils.java | 46 ++++++-- .../com/alibaba/excel/util/DateUtils.java | 71 ++++++++++++ .../core/compatibility/CompatibilityTest.java | 52 +++++++++ .../test/core/nomodel/NoModelDataTest.java | 52 ++++++++- .../easyexcel/test/demo/write/DemoData.java | 1 + .../easyexcel/test/temp/DemoData2.java | 35 ++++++ .../easyexcel/test/temp/DemoData3.java | 24 ++++ .../easyexcel/test/temp/Lock2Test.java | 107 ++++++++++++++++-- .../src/test/resources/compatibility/t05.xlsx | Bin 0 -> 3647 bytes .../src/test/resources/compatibility/t06.xlsx | Bin 0 -> 9332 bytes .../src/test/resources/compatibility/t07.xlsx | Bin 0 -> 19790 bytes pom.xml | 2 +- update.md | 6 + 29 files changed, 598 insertions(+), 49 deletions(-) create mode 100644 easyexcel-core/src/main/java/com/alibaba/excel/constant/EasyExcelConstants.java create mode 100644 easyexcel-core/src/main/java/com/alibaba/excel/enums/ReadDefaultReturnEnum.java create mode 100644 easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/DemoData2.java create mode 100644 easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/DemoData3.java create mode 100644 easyexcel-test/src/test/resources/compatibility/t05.xlsx create mode 100644 easyexcel-test/src/test/resources/compatibility/t06.xlsx create mode 100644 easyexcel-test/src/test/resources/compatibility/t07.xlsx diff --git a/README.md b/README.md index 960ec63e..7987c16c 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ easyexcel重写了poi对07版Excel的解析,一个3M的excel用POI sax解析 com.alibaba easyexcel - 3.1.5 + 3.2.0 ``` diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/handlers/FormulaRecordHandler.java b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/handlers/FormulaRecordHandler.java index 09188cb2..dcf7f548 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/handlers/FormulaRecordHandler.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/handlers/FormulaRecordHandler.java @@ -5,6 +5,7 @@ import java.util.Map; import com.alibaba.excel.analysis.v03.IgnorableXlsRecordHandler; import com.alibaba.excel.constant.BuiltinFormats; +import com.alibaba.excel.constant.EasyExcelConstants; import com.alibaba.excel.context.xls.XlsReadContext; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.RowTypeEnum; @@ -56,7 +57,9 @@ public class FormulaRecordHandler extends AbstractXlsRecordHandler implements Ig break; case NUMERIC: tempCellData.setType(CellDataTypeEnum.NUMBER); - tempCellData.setNumberValue(BigDecimal.valueOf(frec.getValue())); + tempCellData.setOriginalNumberValue(BigDecimal.valueOf(frec.getValue())); + tempCellData.setNumberValue( + tempCellData.getOriginalNumberValue().round(EasyExcelConstants.EXCEL_MATH_CONTEXT)); int dataFormat = xlsReadContext.xlsReadWorkbookHolder().getFormatTrackingHSSFListener().getFormatIndex(frec); DataFormatData dataFormatData = new DataFormatData(); diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/handlers/NumberRecordHandler.java b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/handlers/NumberRecordHandler.java index 1573b8e7..031b895f 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/handlers/NumberRecordHandler.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/handlers/NumberRecordHandler.java @@ -4,6 +4,7 @@ import java.math.BigDecimal; import com.alibaba.excel.analysis.v03.IgnorableXlsRecordHandler; import com.alibaba.excel.constant.BuiltinFormats; +import com.alibaba.excel.constant.EasyExcelConstants; import com.alibaba.excel.context.xls.XlsReadContext; import com.alibaba.excel.enums.RowTypeEnum; import com.alibaba.excel.metadata.data.DataFormatData; @@ -22,7 +23,7 @@ public class NumberRecordHandler extends AbstractXlsRecordHandler implements Ign @Override public void processRecord(XlsReadContext xlsReadContext, Record record) { NumberRecord nr = (NumberRecord)record; - ReadCellData cellData = ReadCellData.newInstance(BigDecimal.valueOf(nr.getValue()), nr.getRow(), + ReadCellData cellData = ReadCellData.newInstanceOriginal(BigDecimal.valueOf(nr.getValue()), nr.getRow(), (int)nr.getColumn()); short dataFormat = (short)xlsReadContext.xlsReadWorkbookHolder().getFormatTrackingHSSFListener().getFormatIndex( nr); diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java index 67218348..75e86aab 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java @@ -2,6 +2,7 @@ package com.alibaba.excel.analysis.v07.handlers; import java.math.BigDecimal; +import com.alibaba.excel.constant.EasyExcelConstants; import com.alibaba.excel.constant.ExcelXmlConstants; import com.alibaba.excel.context.xlsx.XlsxReadContext; import com.alibaba.excel.enums.CellDataTypeEnum; @@ -88,7 +89,9 @@ public class CellTagHandler extends AbstractXlsxTagHandler { break; } tempCellData.setType(CellDataTypeEnum.NUMBER); - tempCellData.setNumberValue(new BigDecimal(tempDataString)); + tempCellData.setOriginalNumberValue(new BigDecimal(tempDataString)); + tempCellData.setNumberValue( + tempCellData.getOriginalNumberValue().round(EasyExcelConstants.EXCEL_MATH_CONTEXT)); break; default: throw new IllegalStateException("Cannot set values now"); diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/constant/EasyExcelConstants.java b/easyexcel-core/src/main/java/com/alibaba/excel/constant/EasyExcelConstants.java new file mode 100644 index 00000000..cdc414fa --- /dev/null +++ b/easyexcel-core/src/main/java/com/alibaba/excel/constant/EasyExcelConstants.java @@ -0,0 +1,19 @@ +package com.alibaba.excel.constant; + +import java.math.MathContext; +import java.math.RoundingMode; + +/** + * Used to store constant + * + * @author Jiaju Zhuang + */ +public class EasyExcelConstants { + + /** + * Excel by default with 15 to store Numbers, and the double in Java can use to store number 17, led to the accuracy + * will be a problem. So you need to set up 15 to deal with precision + */ + public static final MathContext EXCEL_MATH_CONTEXT = new MathContext(15, RoundingMode.HALF_UP); + +} diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/converters/date/DateNumberConverter.java b/easyexcel-core/src/main/java/com/alibaba/excel/converters/date/DateNumberConverter.java index 34bb7536..02ba26aa 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/converters/date/DateNumberConverter.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/converters/date/DateNumberConverter.java @@ -9,6 +9,7 @@ import com.alibaba.excel.metadata.GlobalConfiguration; import com.alibaba.excel.metadata.data.ReadCellData; import com.alibaba.excel.metadata.data.WriteCellData; import com.alibaba.excel.metadata.property.ExcelContentProperty; +import com.alibaba.excel.util.DateUtils; import org.apache.poi.ss.usermodel.DateUtil; @@ -33,11 +34,11 @@ public class DateNumberConverter implements Converter { public Date convertToJavaData(ReadCellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null) { - return DateUtil.getJavaDate(cellData.getNumberValue().doubleValue(), - globalConfiguration.getUse1904windowing(), null); + return DateUtils.getJavaDate(cellData.getNumberValue().doubleValue(), + globalConfiguration.getUse1904windowing()); } else { - return DateUtil.getJavaDate(cellData.getNumberValue().doubleValue(), - contentProperty.getDateTimeFormatProperty().getUse1904windowing(), null); + return DateUtils.getJavaDate(cellData.getNumberValue().doubleValue(), + contentProperty.getDateTimeFormatProperty().getUse1904windowing()); } } diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/converters/localdatetime/LocalDateNumberConverter.java b/easyexcel-core/src/main/java/com/alibaba/excel/converters/localdatetime/LocalDateNumberConverter.java index f57f0bdc..4542fd08 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/converters/localdatetime/LocalDateNumberConverter.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/converters/localdatetime/LocalDateNumberConverter.java @@ -9,6 +9,7 @@ import com.alibaba.excel.metadata.GlobalConfiguration; import com.alibaba.excel.metadata.data.ReadCellData; import com.alibaba.excel.metadata.data.WriteCellData; import com.alibaba.excel.metadata.property.ExcelContentProperty; +import com.alibaba.excel.util.DateUtils; import org.apache.poi.ss.usermodel.DateUtil; @@ -33,10 +34,10 @@ public class LocalDateNumberConverter implements Converter { public LocalDateTime convertToJavaData(ReadCellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null) { - return DateUtil.getLocalDateTime(cellData.getNumberValue().doubleValue(), + return DateUtils.getLocalDateTime(cellData.getNumberValue().doubleValue(), globalConfiguration.getUse1904windowing()); } else { - return DateUtil.getLocalDateTime(cellData.getNumberValue().doubleValue(), + return DateUtils.getLocalDateTime(cellData.getNumberValue().doubleValue(), contentProperty.getDateTimeFormatProperty().getUse1904windowing()); } } diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/converters/string/StringNumberConverter.java b/easyexcel-core/src/main/java/com/alibaba/excel/converters/string/StringNumberConverter.java index 0d0813d0..ff96317d 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/converters/string/StringNumberConverter.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/converters/string/StringNumberConverter.java @@ -37,9 +37,8 @@ public class StringNumberConverter implements Converter { GlobalConfiguration globalConfiguration) { // If there are "DateTimeFormat", read as date if (contentProperty != null && contentProperty.getDateTimeFormatProperty() != null) { - return DateUtils.format( - DateUtil.getJavaDate(cellData.getNumberValue().doubleValue(), - contentProperty.getDateTimeFormatProperty().getUse1904windowing(), null), + return DateUtils.format(cellData.getNumberValue(), + contentProperty.getDateTimeFormatProperty().getUse1904windowing(), contentProperty.getDateTimeFormatProperty().getFormat()); } // If there are "NumberFormat", read as number diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/enums/ReadDefaultReturnEnum.java b/easyexcel-core/src/main/java/com/alibaba/excel/enums/ReadDefaultReturnEnum.java new file mode 100644 index 00000000..c0340d83 --- /dev/null +++ b/easyexcel-core/src/main/java/com/alibaba/excel/enums/ReadDefaultReturnEnum.java @@ -0,0 +1,40 @@ +package com.alibaba.excel.enums; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.HashMap; +import java.util.Map; + +import com.alibaba.excel.metadata.data.CellData; +import com.alibaba.excel.util.StringUtils; + +/** + * Read not to {@code com.alibaba.excel.metadata.BasicParameter#clazz} value, the default will return type. + * + * @author Jiaju Zhuang + */ +public enum ReadDefaultReturnEnum { + /** + * default.The content of cells into string, is the same as you see in the excel. + */ + STRING, + + /** + * Returns the actual type. + * Will be automatically selected according to the cell contents what return type, will return the following class: + *
    + *
  1. {@link BigDecimal}
  2. + *
  3. {@link Boolean}
  4. + *
  5. {@link String}
  6. + *
  7. {@link LocalDateTime}
  8. + *
      + */ + ACTUAL_DATA, + + /** + * Return to {@link com.alibaba.excel.metadata.data.ReadCellData}, can decide which field you need. + */ + READ_CELL_DATA, + ; + +} diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/metadata/data/CellData.java b/easyexcel-core/src/main/java/com/alibaba/excel/metadata/data/CellData.java index 2f74ea9b..e70228f7 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/metadata/data/CellData.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/metadata/data/CellData.java @@ -1,6 +1,7 @@ package com.alibaba.excel.metadata.data; import java.math.BigDecimal; +import java.time.LocalDateTime; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.AbstractCell; @@ -57,6 +58,7 @@ public class CellData extends AbstractCell { } switch (type) { case STRING: + case DIRECT_STRING: case ERROR: if (StringUtils.isEmpty(stringValue)) { type = CellDataTypeEnum.EMPTY; @@ -76,5 +78,4 @@ public class CellData 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 + *

        + *
      1. + * 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` + *
      2. + *
      3. + * 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` + *
      4. + *
          + * {@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 9841d2b2..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 @@ -2,9 +2,13 @@ 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; @@ -50,7 +54,8 @@ 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/number1x.xls") + List list = EasyExcel.read( + "/Users/zhuangjiaju/IdeaProjects/easyexcel/easyexcel-test/target/test-classes/simpleWrite1674051907397.xlsx") //.useDefaultListener(false) .sheet(0) .headRowNumber(0).doReadSync(); @@ -125,8 +130,6 @@ public class Lock2Test { return list; } - - @Test public void testc() throws Exception { LOGGER.info("reslut:{}", JSON.toJSONString(new CellReference("B3"))); @@ -288,13 +291,13 @@ public class Lock2Test { 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") + 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); + 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))); @@ -317,10 +320,98 @@ public class Lock2Test { 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() { + private List data() { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); List list = new ArrayList(); @@ -338,7 +429,7 @@ public class Lock2Test { return list; } - private List data2() { + private List data2() { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); List list = new ArrayList(); 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 0000000000000000000000000000000000000000..248ec7d1747ee016017363a7c9ca1a109f045d21 GIT binary patch literal 3647 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..b27be0279f226f78c59bb433c300574343e5830b GIT binary patch literal 9332 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..a7b0eac7486ad385679944783eb82f5acb1de624 GIT binary patch literal 19790 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 literal 0 HcmV?d00001 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开头的标签