From 2895318a3dbe3e7633e5ca445d9442cf1b2a080b Mon Sep 17 00:00:00 2001 From: "shaojin.wensj" Date: Sat, 14 May 2022 13:41:04 +0800 Subject: [PATCH 01/25] =?UTF-8?q?=E5=8D=87=E7=BA=A7fastjson=E7=89=88?= =?UTF-8?q?=E6=9C=AC=EF=BC=8C=E5=8D=87=E7=BA=A7=E5=88=B0=E6=9C=80=E6=96=B0?= =?UTF-8?q?=E7=9A=842.0.3=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- easyexcel-test/pom.xml | 4 ++-- .../test/core/annotation/AnnotationDataListener.java | 2 +- .../core/annotation/AnnotationIndexAndNameDataListener.java | 2 +- .../easyexcel/test/core/celldata/CellDataDataListener.java | 2 +- .../test/core/converter/ConverterDataListener.java | 2 +- .../test/core/converter/ReadAllConverterDataListener.java | 2 +- .../easyexcel/test/core/encrypt/EncryptDataListener.java | 2 +- .../test/core/exception/ExceptionDataListener.java | 2 +- .../easyexcel/test/core/extra/ExtraDataListener.java | 2 +- .../easyexcel/test/core/head/ComplexDataListener.java | 2 +- .../easyexcel/test/core/head/ListHeadDataListener.java | 2 +- .../easyexcel/test/core/head/NoHeadDataListener.java | 2 +- .../easyexcel/test/core/large/LargeDataListener.java | 2 +- .../test/core/multiplesheets/MultipleSheetsListener.java | 2 +- .../easyexcel/test/core/noncamel/UnCamelDataListener.java | 2 +- .../test/core/parameter/ParameterDataListener.java | 2 +- .../test/core/repetition/RepetitionDataListener.java | 2 +- .../easyexcel/test/core/simple/SimpleDataListener.java | 2 +- .../test/core/simple/SimpleDataSheetNameListener.java | 2 +- .../easyexcel/test/core/style/StyleDataListener.java | 2 +- .../easyexcel/test/core/template/TemplateDataListener.java | 2 +- .../test/demo/read/CellDataDemoHeadDataListener.java | 2 +- .../easyexcel/test/demo/read/ConverterDataListener.java | 2 +- .../alibaba/easyexcel/test/demo/read/DemoDataListener.java | 2 +- .../easyexcel/test/demo/read/DemoExceptionListener.java | 2 +- .../alibaba/easyexcel/test/demo/read/DemoExtraListener.java | 2 +- .../easyexcel/test/demo/read/DemoHeadDataListener.java | 2 +- .../easyexcel/test/demo/read/IndexOrNameDataListener.java | 2 +- .../easyexcel/test/demo/read/NoModelDataListener.java | 2 +- .../java/com/alibaba/easyexcel/test/demo/read/ReadTest.java | 2 +- .../alibaba/easyexcel/test/demo/web/UploadDataListener.java | 2 +- .../java/com/alibaba/easyexcel/test/demo/web/WebTest.java | 2 +- .../java/com/alibaba/easyexcel/test/temp/Lock2Test.java | 2 +- .../com/alibaba/easyexcel/test/temp/LockDataListener.java | 2 +- .../test/java/com/alibaba/easyexcel/test/temp/LockTest.java | 2 +- .../java/com/alibaba/easyexcel/test/temp/StyleTest.java | 2 +- .../java/com/alibaba/easyexcel/test/temp/Xls03Test.java | 2 +- .../com/alibaba/easyexcel/test/temp/cache/CacheTest.java | 2 +- .../com/alibaba/easyexcel/test/temp/csv/CsvDataListeer.java | 2 +- .../com/alibaba/easyexcel/test/temp/csv/CsvReadTest.java | 2 +- .../easyexcel/test/temp/dataformat/DataFormatTest.java | 2 +- .../easyexcel/test/temp/issue2443/Issue2443Test.java | 2 +- .../easyexcel/test/temp/large/LargeDataListener.java | 2 +- .../easyexcel/test/temp/large/NoModelLargeDataListener.java | 2 +- .../com/alibaba/easyexcel/test/temp/poi/PoiWriteTest.java | 2 +- .../com/alibaba/easyexcel/test/temp/read/CommentTest.java | 2 +- .../com/alibaba/easyexcel/test/temp/read/HDListener.java | 2 +- .../com/alibaba/easyexcel/test/temp/read/HeadListener.java | 2 +- .../com/alibaba/easyexcel/test/temp/read/TestListener.java | 2 +- .../com/alibaba/easyexcel/test/temp/simple/HgListener.java | 2 +- .../java/com/alibaba/easyexcel/test/temp/simple/HgTest.java | 2 +- .../alibaba/easyexcel/test/temp/simple/RepeatListener.java | 2 +- .../java/com/alibaba/easyexcel/test/temp/simple/Wirte.java | 2 +- pom.xml | 6 +++--- 54 files changed, 57 insertions(+), 57 deletions(-) diff --git a/easyexcel-test/pom.xml b/easyexcel-test/pom.xml index f802f249..65a25e8b 100644 --- a/easyexcel-test/pom.xml +++ b/easyexcel-test/pom.xml @@ -30,8 +30,8 @@ test - com.alibaba - fastjson + com.alibaba.fastjson2 + fastjson2 test diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/annotation/AnnotationDataListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/annotation/AnnotationDataListener.java index 09bfc523..222d83b5 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/annotation/AnnotationDataListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/annotation/AnnotationDataListener.java @@ -12,7 +12,7 @@ import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.exception.ExcelCommonException; import com.alibaba.excel.util.DateUtils; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; /** * @author Jiaju Zhuang diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/annotation/AnnotationIndexAndNameDataListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/annotation/AnnotationIndexAndNameDataListener.java index 115b1b03..ea091f23 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/annotation/AnnotationIndexAndNameDataListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/annotation/AnnotationIndexAndNameDataListener.java @@ -9,7 +9,7 @@ import org.slf4j.LoggerFactory; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; /** * @author Jiaju Zhuang diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/celldata/CellDataDataListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/celldata/CellDataDataListener.java index 35829e0e..acafba47 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/celldata/CellDataDataListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/celldata/CellDataDataListener.java @@ -6,7 +6,7 @@ import java.util.List; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.support.ExcelTypeEnum; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; import org.junit.Assert; import org.slf4j.Logger; diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/converter/ConverterDataListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/converter/ConverterDataListener.java index fc353ba2..a7fbcf4b 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/converter/ConverterDataListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/converter/ConverterDataListener.java @@ -10,7 +10,7 @@ import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.exception.ExcelCommonException; import com.alibaba.excel.util.DateUtils; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; import org.junit.Assert; import org.slf4j.Logger; diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/converter/ReadAllConverterDataListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/converter/ReadAllConverterDataListener.java index 8516cd5b..f56eab46 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/converter/ReadAllConverterDataListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/converter/ReadAllConverterDataListener.java @@ -11,7 +11,7 @@ import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.exception.ExcelCommonException; import com.alibaba.excel.support.ExcelTypeEnum; import com.alibaba.excel.util.DateUtils; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; import org.junit.Assert; import org.slf4j.Logger; diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/encrypt/EncryptDataListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/encrypt/EncryptDataListener.java index 0fb603fb..545a5894 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/encrypt/EncryptDataListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/encrypt/EncryptDataListener.java @@ -9,7 +9,7 @@ import org.slf4j.LoggerFactory; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; /** * @author Jiaju Zhuang diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/exception/ExceptionDataListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/exception/ExceptionDataListener.java index d9c26e26..8009d4db 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/exception/ExceptionDataListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/exception/ExceptionDataListener.java @@ -9,7 +9,7 @@ import org.slf4j.LoggerFactory; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; /** * @author Jiaju Zhuang diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/extra/ExtraDataListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/extra/ExtraDataListener.java index 9039ab06..d58c4cdb 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/extra/ExtraDataListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/extra/ExtraDataListener.java @@ -7,7 +7,7 @@ import org.slf4j.LoggerFactory; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.metadata.CellExtra; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; /** * @author Jiaju Zhuang diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/head/ComplexDataListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/head/ComplexDataListener.java index a3441d5e..1eab8585 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/head/ComplexDataListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/head/ComplexDataListener.java @@ -9,7 +9,7 @@ import org.slf4j.LoggerFactory; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; /** * @author Jiaju Zhuang diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/head/ListHeadDataListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/head/ListHeadDataListener.java index 58660c90..3e0ba094 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/head/ListHeadDataListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/head/ListHeadDataListener.java @@ -7,7 +7,7 @@ import java.util.Map; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.metadata.data.ReadCellData; import com.alibaba.excel.read.listener.ReadListener; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; import org.junit.Assert; import org.slf4j.Logger; diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/head/NoHeadDataListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/head/NoHeadDataListener.java index f09c899b..ae07ab41 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/head/NoHeadDataListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/head/NoHeadDataListener.java @@ -9,7 +9,7 @@ import org.slf4j.LoggerFactory; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; /** * @author Jiaju Zhuang diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/large/LargeDataListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/large/LargeDataListener.java index dafe25fa..fd056a5c 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/large/LargeDataListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/large/LargeDataListener.java @@ -3,7 +3,7 @@ package com.alibaba.easyexcel.test.core.large; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.support.ExcelTypeEnum; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; import org.junit.Assert; import org.slf4j.Logger; diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/multiplesheets/MultipleSheetsListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/multiplesheets/MultipleSheetsListener.java index d7b41582..c078f20e 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/multiplesheets/MultipleSheetsListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/multiplesheets/MultipleSheetsListener.java @@ -9,7 +9,7 @@ import org.slf4j.LoggerFactory; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; /** * @author Jiaju Zhuang diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/noncamel/UnCamelDataListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/noncamel/UnCamelDataListener.java index b307ddb4..8c5e93c7 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/noncamel/UnCamelDataListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/noncamel/UnCamelDataListener.java @@ -6,7 +6,7 @@ import java.util.Map; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; import lombok.extern.slf4j.Slf4j; import org.junit.Assert; diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/parameter/ParameterDataListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/parameter/ParameterDataListener.java index 57cca660..f465e92c 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/parameter/ParameterDataListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/parameter/ParameterDataListener.java @@ -9,7 +9,7 @@ import org.slf4j.LoggerFactory; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; /** * @author Jiaju Zhuang diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/repetition/RepetitionDataListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/repetition/RepetitionDataListener.java index ff0a332e..4827f67a 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/repetition/RepetitionDataListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/repetition/RepetitionDataListener.java @@ -10,7 +10,7 @@ import org.slf4j.LoggerFactory; import com.alibaba.easyexcel.test.core.simple.SimpleDataListener; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; /** * @author Jiaju Zhuang diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/simple/SimpleDataListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/simple/SimpleDataListener.java index b8925f81..9dc708ae 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/simple/SimpleDataListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/simple/SimpleDataListener.java @@ -10,7 +10,7 @@ import org.slf4j.LoggerFactory; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; /** * @author Jiaju Zhuang diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/simple/SimpleDataSheetNameListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/simple/SimpleDataSheetNameListener.java index 72c4c151..59cfa64f 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/simple/SimpleDataSheetNameListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/simple/SimpleDataSheetNameListener.java @@ -9,7 +9,7 @@ import org.slf4j.LoggerFactory; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; /** * @author Jiaju Zhuang diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/style/StyleDataListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/style/StyleDataListener.java index 9246a10b..ee16e023 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/style/StyleDataListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/style/StyleDataListener.java @@ -10,7 +10,7 @@ import org.slf4j.LoggerFactory; import com.alibaba.easyexcel.test.core.simple.SimpleDataListener; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; /** * @author Jiaju Zhuang diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/template/TemplateDataListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/template/TemplateDataListener.java index 0286e2e3..e3b8b3cf 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/template/TemplateDataListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/template/TemplateDataListener.java @@ -10,7 +10,7 @@ import org.slf4j.LoggerFactory; import com.alibaba.easyexcel.test.core.simple.SimpleDataListener; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; /** * @author Jiaju Zhuang diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/CellDataDemoHeadDataListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/CellDataDemoHeadDataListener.java index b1ef3d7e..e04bc307 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/CellDataDemoHeadDataListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/CellDataDemoHeadDataListener.java @@ -5,7 +5,7 @@ import java.util.List; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.read.listener.ReadListener; import com.alibaba.excel.util.ListUtils; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; import lombok.extern.slf4j.Slf4j; diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/ConverterDataListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/ConverterDataListener.java index 9dabbc86..b7d144a5 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/ConverterDataListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/ConverterDataListener.java @@ -5,7 +5,7 @@ import java.util.List; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.read.listener.ReadListener; import com.alibaba.excel.util.ListUtils; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; import lombok.extern.slf4j.Slf4j; diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/DemoDataListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/DemoDataListener.java index 80d27b26..a6ddaf95 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/DemoDataListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/DemoDataListener.java @@ -5,7 +5,7 @@ import java.util.List; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.read.listener.ReadListener; import com.alibaba.excel.util.ListUtils; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; import lombok.extern.slf4j.Slf4j; diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/DemoExceptionListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/DemoExceptionListener.java index 26d1c8de..498725a0 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/DemoExceptionListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/DemoExceptionListener.java @@ -8,7 +8,7 @@ import com.alibaba.excel.exception.ExcelDataConvertException; import com.alibaba.excel.metadata.data.ReadCellData; import com.alibaba.excel.read.listener.ReadListener; import com.alibaba.excel.util.ListUtils; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; import lombok.extern.slf4j.Slf4j; diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/DemoExtraListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/DemoExtraListener.java index e9dcc199..24ebca01 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/DemoExtraListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/DemoExtraListener.java @@ -3,7 +3,7 @@ package com.alibaba.easyexcel.test.demo.read; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.metadata.CellExtra; import com.alibaba.excel.read.listener.ReadListener; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; import lombok.extern.slf4j.Slf4j; import org.junit.Assert; diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/DemoHeadDataListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/DemoHeadDataListener.java index ffde2b2c..7e9cf6c6 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/DemoHeadDataListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/DemoHeadDataListener.java @@ -8,7 +8,7 @@ import com.alibaba.excel.exception.ExcelDataConvertException; import com.alibaba.excel.metadata.data.ReadCellData; import com.alibaba.excel.read.listener.ReadListener; import com.alibaba.excel.util.ListUtils; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; import lombok.extern.slf4j.Slf4j; diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/IndexOrNameDataListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/IndexOrNameDataListener.java index d00d44df..77898d23 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/IndexOrNameDataListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/IndexOrNameDataListener.java @@ -5,7 +5,7 @@ import java.util.List; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.util.ListUtils; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; import lombok.extern.slf4j.Slf4j; diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/NoModelDataListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/NoModelDataListener.java index 13de38d2..ec387ca0 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/NoModelDataListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/NoModelDataListener.java @@ -6,7 +6,7 @@ import java.util.Map; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.util.ListUtils; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; import lombok.extern.slf4j.Slf4j; diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java index d621c300..86f57f2b 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java @@ -17,7 +17,7 @@ import com.alibaba.excel.read.listener.PageReadListener; import com.alibaba.excel.read.listener.ReadListener; import com.alibaba.excel.read.metadata.ReadSheet; import com.alibaba.excel.util.ListUtils; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; import lombok.extern.slf4j.Slf4j; import org.junit.Ignore; diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/web/UploadDataListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/web/UploadDataListener.java index 54218355..2096cd4d 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/web/UploadDataListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/web/UploadDataListener.java @@ -5,7 +5,7 @@ import java.util.List; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.read.listener.ReadListener; import com.alibaba.excel.util.ListUtils; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; import lombok.extern.slf4j.Slf4j; diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/web/WebTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/web/WebTest.java index 0260534f..f1c8e7c2 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/web/WebTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/web/WebTest.java @@ -11,7 +11,7 @@ import javax.servlet.http.HttpServletResponse; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.util.ListUtils; import com.alibaba.excel.util.MapUtils; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; 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..34e25d0d 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 @@ -12,7 +12,7 @@ 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 com.alibaba.fastjson2.JSON; import org.apache.commons.collections4.CollectionUtils; import org.apache.poi.hssf.util.CellReference; diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/LockDataListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/LockDataListener.java index 1a7dffb5..d7003f25 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/LockDataListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/LockDataListener.java @@ -9,7 +9,7 @@ import org.slf4j.LoggerFactory; import com.alibaba.easyexcel.test.demo.read.DemoDataListener; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; /** * 模板的读取类 diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/LockTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/LockTest.java index 07cb7989..8e4ec6c9 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/LockTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/LockTest.java @@ -5,7 +5,7 @@ import java.util.List; import java.util.Map; import com.alibaba.excel.EasyExcel; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; import org.junit.Ignore; import org.junit.Test; diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/StyleTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/StyleTest.java index c3a6654a..0f1f0832 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/StyleTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/StyleTest.java @@ -28,7 +28,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.excel.EasyExcel; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; /** * 临时测试 diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/Xls03Test.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/Xls03Test.java index ffb590ee..b7624599 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/Xls03Test.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/Xls03Test.java @@ -4,7 +4,7 @@ import java.util.List; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.util.BeanMapUtils; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; import org.junit.Ignore; import org.junit.Test; diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/cache/CacheTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/cache/CacheTest.java index adcef54a..22015457 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/cache/CacheTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/cache/CacheTest.java @@ -17,7 +17,7 @@ import org.slf4j.LoggerFactory; import com.alibaba.easyexcel.test.temp.poi.Poi2Test; import com.alibaba.excel.util.FileUtils; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; /** * diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/csv/CsvDataListeer.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/csv/CsvDataListeer.java index e3fdd695..78167563 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/csv/CsvDataListeer.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/csv/CsvDataListeer.java @@ -2,7 +2,7 @@ package com.alibaba.easyexcel.test.temp.csv; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; import lombok.extern.slf4j.Slf4j; diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/csv/CsvReadTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/csv/CsvReadTest.java index 91293019..2a6c69ce 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/csv/CsvReadTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/csv/CsvReadTest.java @@ -11,7 +11,7 @@ import java.util.List; import com.alibaba.easyexcel.test.util.TestFileUtil; import com.alibaba.excel.EasyExcel; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; import lombok.extern.slf4j.Slf4j; import org.apache.commons.csv.CSVFormat; diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/dataformat/DataFormatTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/dataformat/DataFormatTest.java index 4440f350..280a5046 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/dataformat/DataFormatTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/dataformat/DataFormatTest.java @@ -13,7 +13,7 @@ import com.alibaba.easyexcel.test.core.dataformat.DateFormatData; import com.alibaba.easyexcel.test.temp.Lock2Test; import com.alibaba.easyexcel.test.util.TestFileUtil; import com.alibaba.excel.EasyExcel; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.ss.usermodel.Cell; diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/issue2443/Issue2443Test.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/issue2443/Issue2443Test.java index 57484b74..b9e2c965 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/issue2443/Issue2443Test.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/issue2443/Issue2443Test.java @@ -5,7 +5,7 @@ import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.util.NumberUtils; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.read.listener.PageReadListener; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; import lombok.extern.slf4j.Slf4j; import org.junit.Ignore; import org.junit.Test; diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/large/LargeDataListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/large/LargeDataListener.java index 500cc85f..25176101 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/large/LargeDataListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/large/LargeDataListener.java @@ -5,7 +5,7 @@ import org.slf4j.LoggerFactory; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; /** * @author Jiaju Zhuang diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/large/NoModelLargeDataListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/large/NoModelLargeDataListener.java index aff72adf..2d532bb2 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/large/NoModelLargeDataListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/large/NoModelLargeDataListener.java @@ -7,7 +7,7 @@ import org.slf4j.LoggerFactory; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; /** * @author Jiaju Zhuang diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiWriteTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiWriteTest.java index 59330bbd..7ce3f587 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiWriteTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiWriteTest.java @@ -8,7 +8,7 @@ import java.math.BigDecimal; import java.net.URL; import java.util.regex.Pattern; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; import org.apache.poi.xssf.streaming.SXSSFCell; import org.apache.poi.xssf.streaming.SXSSFRow; diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/read/CommentTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/read/CommentTest.java index 48512b6c..780b1ce4 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/read/CommentTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/read/CommentTest.java @@ -11,7 +11,7 @@ import org.slf4j.LoggerFactory; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.metadata.data.CellData; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; /** * 临时测试 diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/read/HDListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/read/HDListener.java index 7835c51f..7ee174d9 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/read/HDListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/read/HDListener.java @@ -7,7 +7,7 @@ import org.slf4j.LoggerFactory; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; /** * 模板的读取类 diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/read/HeadListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/read/HeadListener.java index c0cd96dd..711e5b9b 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/read/HeadListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/read/HeadListener.java @@ -7,7 +7,7 @@ import org.slf4j.LoggerFactory; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; /** * 模板的读取类 diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/read/TestListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/read/TestListener.java index fb80a9a4..18927169 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/read/TestListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/read/TestListener.java @@ -2,7 +2,7 @@ package com.alibaba.easyexcel.test.temp.read; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; import lombok.extern.slf4j.Slf4j; diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/simple/HgListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/simple/HgListener.java index f687416e..161ccda5 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/simple/HgListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/simple/HgListener.java @@ -4,7 +4,7 @@ import java.util.Map; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/simple/HgTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/simple/HgTest.java index fbfde36f..fcb75f11 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/simple/HgTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/simple/HgTest.java @@ -12,7 +12,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.excel.EasyExcel; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; /** * 测试poi diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/simple/RepeatListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/simple/RepeatListener.java index 46182803..eab1e1ae 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/simple/RepeatListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/simple/RepeatListener.java @@ -10,7 +10,7 @@ import com.alibaba.easyexcel.test.demo.read.DemoDataListener; import com.alibaba.easyexcel.test.temp.LockData; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; /** * 模板的读取类 diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/simple/Wirte.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/simple/Wirte.java index 77c1285e..f284e3ac 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/simple/Wirte.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/simple/Wirte.java @@ -13,7 +13,7 @@ import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.util.BeanMapUtils; import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.excel.write.metadata.WriteTable; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; import lombok.extern.slf4j.Slf4j; import org.junit.Ignore; diff --git a/pom.xml b/pom.xml index 5a43e702..b8be96c7 100644 --- a/pom.xml +++ b/pom.xml @@ -143,9 +143,9 @@ 1.2.5 - com.alibaba - fastjson - 1.2.78 + com.alibaba.fastjson2 + fastjson2 + 2.0.3 org.springframework.boot From 477acbe84cbc3e0e301fb3ec91187de93def7216 Mon Sep 17 00:00:00 2001 From: zhangzq7 Date: Wed, 2 Nov 2022 10:37:31 +0800 Subject: [PATCH 02/25] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=EF=BC=8C=E7=A7=BB=E9=99=A4=E6=B2=A1=E6=9C=89=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E7=9A=84=E5=AF=B9=E8=B1=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../excel/analysis/v03/handlers/BoundSheetRecordHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/handlers/BoundSheetRecordHandler.java b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/handlers/BoundSheetRecordHandler.java index 685dcc65..ad475522 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/handlers/BoundSheetRecordHandler.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/handlers/BoundSheetRecordHandler.java @@ -16,6 +16,6 @@ public class BoundSheetRecordHandler extends AbstractXlsRecordHandler implements @Override public void processRecord(XlsReadContext xlsReadContext, Record record) { BoundSheetRecord bsr = (BoundSheetRecord)record; - xlsReadContext.xlsReadWorkbookHolder().getBoundSheetRecordList().add((BoundSheetRecord)record); + xlsReadContext.xlsReadWorkbookHolder().getBoundSheetRecordList().add(bsr); } } From 70094e87f13093aa7635a57a9bb304f7f2429d41 Mon Sep 17 00:00:00 2001 From: NicknamedCoco Date: Fri, 18 Nov 2022 11:44:07 +0800 Subject: [PATCH 03/25] Update DemoExtraListener.java MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改注释错误 --- .../com/alibaba/easyexcel/test/demo/read/DemoExtraListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/DemoExtraListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/DemoExtraListener.java index e9dcc199..4bfdbb82 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/DemoExtraListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/DemoExtraListener.java @@ -46,7 +46,7 @@ public class DemoExtraListener implements ReadListener { break; case MERGE: log.info( - "额外信息是超链接,而且覆盖了一个区间,在firstRowIndex:{},firstColumnIndex;{},lastRowIndex:{},lastColumnIndex:{}", + "额外信息是合并单元格,而且覆盖了一个区间,在firstRowIndex:{},firstColumnIndex;{},lastRowIndex:{},lastColumnIndex:{}", extra.getFirstRowIndex(), extra.getFirstColumnIndex(), extra.getLastRowIndex(), extra.getLastColumnIndex()); break; From ac1128eddbc38702db107f2ea2a3f3b5ad855350 Mon Sep 17 00:00:00 2001 From: ls9527 <364173778@qq.com> Date: Sun, 8 Jan 2023 18:26:31 +0800 Subject: [PATCH 04/25] =?UTF-8?q?=E5=88=86=E9=A1=B5=E8=AF=BB=E5=8F=96?= =?UTF-8?q?=E7=9B=91=E5=90=AC=E5=99=A8=E6=94=AF=E6=8C=81=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E5=88=86=E9=A1=B5=E6=9D=A1=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../alibaba/excel/read/listener/PageReadListener.java | 9 ++++++++- .../com/alibaba/easyexcel/test/demo/read/ReadTest.java | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/read/listener/PageReadListener.java b/easyexcel-core/src/main/java/com/alibaba/excel/read/listener/PageReadListener.java index becc1748..8c3fe782 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/read/listener/PageReadListener.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/read/listener/PageReadListener.java @@ -27,14 +27,21 @@ public class PageReadListener implements ReadListener { */ private final Consumer> consumer; + private final int pageSize; + public PageReadListener(Consumer> consumer) { + this(consumer, BATCH_COUNT); + } + + public PageReadListener(Consumer> consumer,int pageSize) { this.consumer = consumer; + this.pageSize = pageSize; } @Override public void invoke(T data, AnalysisContext context) { cachedDataList.add(data); - if (cachedDataList.size() >= BATCH_COUNT) { + if (cachedDataList.size() >= pageSize) { consumer.accept(cachedDataList); cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); } diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java index 527ca6dc..542fe463 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java @@ -52,7 +52,7 @@ public class ReadTest { for (DemoData demoData : dataList) { log.info("读取到一条数据{}", JSON.toJSONString(demoData)); } - })).sheet().doRead(); + },3)).sheet().doRead(); // 写法2: // 匿名内部类 不用额外写一个DemoDataListener From 844fbb54602ebfc9ea5faccb830b9adf79e909e9 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Thu, 2 Feb 2023 21:05:21 +0800 Subject: [PATCH 05/25] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=89=93=E5=8C=85url?= =?UTF-8?q?=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- easyexcel-core/pom.xml | 2 +- easyexcel-support/pom.xml | 1 + easyexcel-test/pom.xml | 1 + easyexcel/pom.xml | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/easyexcel-core/pom.xml b/easyexcel-core/pom.xml index d6e58002..9cfabb2a 100644 --- a/easyexcel-core/pom.xml +++ b/easyexcel-core/pom.xml @@ -3,7 +3,6 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.alibaba easyexcel-parent @@ -11,6 +10,7 @@ ../pom.xml + https://github.com/alibaba/easyexcel jar easyexcel-core easyexcel-core diff --git a/easyexcel-support/pom.xml b/easyexcel-support/pom.xml index db2dbd3f..23613040 100644 --- a/easyexcel-support/pom.xml +++ b/easyexcel-support/pom.xml @@ -11,6 +11,7 @@ ../pom.xml + https://github.com/alibaba/easyexcel jar easyexcel-support easyexcel-support diff --git a/easyexcel-test/pom.xml b/easyexcel-test/pom.xml index 80821db2..ebaea699 100644 --- a/easyexcel-test/pom.xml +++ b/easyexcel-test/pom.xml @@ -11,6 +11,7 @@ ../pom.xml + https://github.com/alibaba/easyexcel jar easyexcel-test easyexcel-test diff --git a/easyexcel/pom.xml b/easyexcel/pom.xml index 495552c0..2df8f71a 100644 --- a/easyexcel/pom.xml +++ b/easyexcel/pom.xml @@ -11,6 +11,7 @@ ../pom.xml + https://github.com/alibaba/easyexcel jar easyexcel easyexcel From d4ddaf9484de6ed6db1bd2f6365efcf2f0655c2e Mon Sep 17 00:00:00 2001 From: gongxuanzhang Date: Fri, 3 Feb 2023 09:28:35 +0800 Subject: [PATCH 06/25] modify the class name to correct word --- .../easyexcel/test/temp/simple/{Wirte.java => Write.java} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/simple/{Wirte.java => Write.java} (99%) diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/simple/Wirte.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/simple/Write.java similarity index 99% rename from easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/simple/Wirte.java rename to easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/simple/Write.java index 77c1285e..49ffa36d 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/simple/Wirte.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/simple/Write.java @@ -28,8 +28,8 @@ import org.slf4j.LoggerFactory; **/ @Ignore @Slf4j -public class Wirte { - private static final Logger LOGGER = LoggerFactory.getLogger(Wirte.class); +public class Write { + private static final Logger LOGGER = LoggerFactory.getLogger(Write.class); @Test public void simpleWrite1() { From 339d0edd7637bc04c8f6ad0f966aab1e27f0f6a8 Mon Sep 17 00:00:00 2001 From: gongxuanzhang Date: Fri, 3 Feb 2023 09:29:22 +0800 Subject: [PATCH 07/25] modify the comment to correct word --- .../java/com/alibaba/excel/metadata/data/WriteCellData.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/metadata/data/WriteCellData.java b/easyexcel-core/src/main/java/com/alibaba/excel/metadata/data/WriteCellData.java index f8ce9064..d4345fa9 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/metadata/data/WriteCellData.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/metadata/data/WriteCellData.java @@ -17,7 +17,7 @@ import lombok.Setter; import org.apache.poi.ss.usermodel.CellStyle; /** - * wirte cell data + * write cell data * * @author Jiaju Zhuang */ From 4f4fb34669685091a9a70d436c906e870713e00c Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Fri, 3 Feb 2023 09:55:26 +0800 Subject: [PATCH 08/25] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=A7=A6=E5=8F=91?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/sync2gitee.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sync2gitee.yml b/.github/workflows/sync2gitee.yml index cc88d581..5b48b08b 100644 --- a/.github/workflows/sync2gitee.yml +++ b/.github/workflows/sync2gitee.yml @@ -1,6 +1,6 @@ # 通过 Github action, 在仓库的每一次 commit 后自动同步到 Gitee 上 name: Mirror the Github organization repos to Gitee -on: [push, pull_request] +on: [push] jobs: repo-sync: From 592291de19f19cf97dcb73d52364d9c3551f9aad Mon Sep 17 00:00:00 2001 From: lonecloud Date: Wed, 8 Feb 2023 14:46:19 +0800 Subject: [PATCH 09/25] =?UTF-8?q?*=20=E4=BF=AE=E5=A4=8Dehcache=E7=BC=93?= =?UTF-8?q?=E5=AD=98=E5=9C=A8=E7=9B=AE=E5=BD=95/tmp=E8=A2=AB=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=E6=B8=85=E7=90=86=E5=AF=BC=E8=87=B4=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/alibaba/excel/cache/Ehcache.java | 22 ++++++++++++++++--- .../com/alibaba/excel/util/FileUtils.java | 2 +- .../test/core/large/LargeDataTest.java | 19 +++++++++++++++- 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/cache/Ehcache.java b/easyexcel-core/src/main/java/com/alibaba/excel/cache/Ehcache.java index b7b542ee..c69f0d0f 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/cache/Ehcache.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/cache/Ehcache.java @@ -35,6 +35,8 @@ public class Ehcache implements ReadCache { private static final CacheManager FILE_CACHE_MANAGER; private static final CacheConfiguration FILE_CACHE_CONFIGURATION; private static final CacheManager ACTIVE_CACHE_MANAGER; + private static final File CACHE_PATH_FILE; + private final CacheConfiguration activeCacheConfiguration; /** * Bulk storage data @@ -59,9 +61,9 @@ public class Ehcache implements ReadCache { } static { - File cacheFile = FileUtils.createCacheTmpFile(); + CACHE_PATH_FILE = FileUtils.createCacheTmpFile(); FILE_CACHE_MANAGER = - CacheManagerBuilder.newCacheManagerBuilder().with(CacheManagerBuilder.persistence(cacheFile)).build(true); + CacheManagerBuilder.newCacheManagerBuilder().with(CacheManagerBuilder.persistence(CACHE_PATH_FILE)).build(true); ACTIVE_CACHE_MANAGER = CacheManagerBuilder.newCacheManagerBuilder().build(true); FILE_CACHE_CONFIGURATION = CacheConfigurationBuilder .newCacheConfigurationBuilder(Integer.class, ArrayList.class, @@ -72,7 +74,21 @@ public class Ehcache implements ReadCache { @Override public void init(AnalysisContext analysisContext) { cacheAlias = UUID.randomUUID().toString(); - fileCache = FILE_CACHE_MANAGER.createCache(cacheAlias, FILE_CACHE_CONFIGURATION); + try { + fileCache = FILE_CACHE_MANAGER.createCache(cacheAlias, FILE_CACHE_CONFIGURATION); + } catch (IllegalStateException e) { + //fix Issue #2693,重建缓存文件夹 + if (CACHE_PATH_FILE.exists()) { + throw e; + } + synchronized (Ehcache.class) { + if (!CACHE_PATH_FILE.exists()){ + log.debug("cache file dir is not exist retry create"); + FileUtils.createDirectory(CACHE_PATH_FILE); + } + } + fileCache = FILE_CACHE_MANAGER.createCache(cacheAlias, FILE_CACHE_CONFIGURATION); + } activeCache = ACTIVE_CACHE_MANAGER.createCache(cacheAlias, activeCacheConfiguration); } diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/util/FileUtils.java b/easyexcel-core/src/main/java/com/alibaba/excel/util/FileUtils.java index 881c1437..d800be51 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/util/FileUtils.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/util/FileUtils.java @@ -174,7 +174,7 @@ public class FileUtils { * * @param directory */ - private static File createDirectory(File directory) { + public static File createDirectory(File directory) { if (!directory.exists() && !directory.mkdirs()) { throw new ExcelCommonException("Cannot create directory:" + directory.getAbsolutePath()); } diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/large/LargeDataTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/large/LargeDataTest.java index d8acbba5..aeebdde8 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/large/LargeDataTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/large/LargeDataTest.java @@ -2,14 +2,19 @@ package com.alibaba.easyexcel.test.core.large; import java.io.File; import java.io.FileOutputStream; +import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; import com.alibaba.easyexcel.test.util.TestFileUtil; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.ExcelWriter; +import com.alibaba.excel.cache.Ehcache; +import com.alibaba.excel.cache.ReadCache; +import com.alibaba.excel.util.FileUtils; import com.alibaba.excel.write.metadata.WriteSheet; +import org.apache.poi.util.TempFile; import org.apache.poi.xssf.streaming.SXSSFCell; import org.apache.poi.xssf.streaming.SXSSFRow; import org.apache.poi.xssf.streaming.SXSSFSheet; @@ -55,6 +60,7 @@ public class LargeDataTest { LOGGER.info("Large data total time spent:{}", System.currentTimeMillis() - start); } + @Test public void t02Fill() { try (ExcelWriter excelWriter = EasyExcel.write(fileFill07).withTemplate(template07).build()) { @@ -127,7 +133,18 @@ public class LargeDataTest { LOGGER.info("{} vs {}", cost, costPoi); Assert.assertTrue(costPoi * 2 > cost); } - + @Test + public void t05Read() throws Exception { + long start = System.currentTimeMillis(); + EasyExcel.read(TestFileUtil.getPath() + "large" + File.separator + "large07.xlsx", LargeData.class, + new LargeDataListener()).headRowNumber(2).sheet().doRead(); + LOGGER.info("Large data total time spent:{}", System.currentTimeMillis() - start); + FileUtils.delete(new File(System.getProperty(TempFile.JAVA_IO_TMPDIR))); + start = System.currentTimeMillis(); + EasyExcel.read(TestFileUtil.getPath() + "large" + File.separator + "large07.xlsx", LargeData.class, + new LargeDataListener()).headRowNumber(2).sheet().doRead(); + LOGGER.info("Large data total time spent:{}", System.currentTimeMillis() - start); + } private List data() { List list = new ArrayList<>(); int size = i + 100; From bd0f06436360df8edb1a599b3b79a2ed2bdcb0a3 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 8 Feb 2023 15:31:08 +0800 Subject: [PATCH 10/25] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=A8=A1=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/ISSUE_TEMPLATE/bug.md | 2 ++ .github/ISSUE_TEMPLATE/question.md | 1 + 2 files changed, 3 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md index 7ef28dd1..f30eacb5 100644 --- a/.github/ISSUE_TEMPLATE/bug.md +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -16,3 +16,5 @@ assignees: zhuangjiaju 这里写代码 ``` # 提示的异常或者没有达到的效果 +大家尽量把问题一次性描述清楚,然后贴上全部异常,这样方便把问题一次性解决掉。 +至少大家要符合一个原则就是,能让其他人复现出这个问题,如果无法复现,肯定无法解决。 diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md index bd234cf8..daf6eacd 100644 --- a/.github/ISSUE_TEMPLATE/question.md +++ b/.github/ISSUE_TEMPLATE/question.md @@ -15,4 +15,5 @@ assignees: '' ``` # 异常提示 大家尽量把问题一次性描述清楚,然后贴上全部异常,这样方便把问题一次性解决掉。 +至少大家要符合一个原则就是,能让其他人复现出这个问题,如果无法复现,肯定无法解决。 # 问题描述 From b8ec940b2889193ce15b298a8ce43e607a52324a Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 8 Feb 2023 17:01:07 +0800 Subject: [PATCH 11/25] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E5=AF=BC=E5=87=BA=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../easyexcel/test/demo/write/WriteTest.java | 4 + .../test/temp/write/TempWriteTest.java | 79 ++++++++++++++++++- 2 files changed, 82 insertions(+), 1 deletion(-) diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java index 607a91be..a28ac324 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java @@ -242,6 +242,10 @@ public class WriteTest { public void imageWrite() throws Exception { String fileName = TestFileUtil.getPath() + "imageWrite" + System.currentTimeMillis() + ".xlsx"; + // 这里注意下 所有的图片都会放到内存 暂时没有很好的解法,大量图片的情况下建议 2选1: + // 1. 将图片上传到oss 或者其他存储网站: https://www.aliyun.com/product/oss + // 2. 使用: https://github.com/coobird/thumbnailator 或者其他工具压缩图片 + String imagePath = TestFileUtil.getPath() + "converter" + File.separator + "img.jpg"; try (InputStream inputStream = FileUtils.openInputStream(new File(imagePath))) { List list = ListUtils.newArrayList(); diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/write/TempWriteTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/write/TempWriteTest.java index 22126889..b084ed04 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/write/TempWriteTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/write/TempWriteTest.java @@ -1,15 +1,47 @@ package com.alibaba.easyexcel.test.temp.write; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import com.alibaba.easyexcel.test.demo.read.CustomStringStringConverter; +import com.alibaba.easyexcel.test.demo.write.DemoData; +import com.alibaba.easyexcel.test.demo.write.ImageDemoData; import com.alibaba.easyexcel.test.util.TestFileUtil; import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.ExcelWriter; +import com.alibaba.excel.enums.CellDataTypeEnum; +import com.alibaba.excel.metadata.data.ImageData; +import com.alibaba.excel.metadata.data.ImageData.ImageType; +import com.alibaba.excel.metadata.data.WriteCellData; import com.alibaba.excel.util.BeanMapUtils; +import com.alibaba.excel.util.FileUtils; import com.alibaba.excel.util.ListUtils; +import com.alibaba.excel.write.metadata.WriteSheet; import lombok.extern.slf4j.Slf4j; +import org.apache.poi.ss.usermodel.ClientAnchor; +import org.apache.poi.ss.usermodel.CreationHelper; +import org.apache.poi.ss.usermodel.IndexedColors; +import org.apache.poi.ss.usermodel.Picture; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.xssf.streaming.SXSSFCell; +import org.apache.poi.xssf.streaming.SXSSFDrawing; +import org.apache.poi.xssf.streaming.SXSSFRow; +import org.apache.poi.xssf.streaming.SXSSFSheet; +import org.apache.poi.xssf.streaming.SXSSFWorkbook; +import org.apache.poi.xssf.usermodel.XSSFCellStyle; +import org.apache.poi.xssf.usermodel.XSSFColor; +import org.apache.poi.xssf.usermodel.XSSFFont; +import org.apache.poi.xssf.usermodel.XSSFRow; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.junit.Ignore; import org.junit.Test; import org.springframework.cglib.beans.BeanMap; @@ -28,7 +60,6 @@ public class TempWriteTest { .registerConverter(new CustomStringStringConverter()) .doWrite(ListUtils.newArrayList(tempWriteData)); - EasyExcel.write(TestFileUtil.getPath() + "TempWriteTest" + System.currentTimeMillis() + ".xlsx", TempWriteData.class) .sheet() @@ -55,4 +86,50 @@ public class TempWriteTest { log.info("3{}", tempWriteData2.getName()); } + + @Test + public void imageWrite() throws Exception { + //String fileName = TestFileUtil.getPath() + "imageWrite" + System.currentTimeMillis() + ".xlsx"; + // + //// 这里 需要指定写用哪个class去写 + //try (ExcelWriter excelWriter = EasyExcel.write(fileName, DemoData.class).build()) { + // // 这里注意 如果同一个sheet只要创建一次 + // WriteSheet writeSheet = EasyExcel.writerSheet("模板").build(); + // // 去调用写入,这里我调用了五次,实际使用时根据数据库分页的总的页数来 + // for (int i = 0; i < 5; i++) { + // // 分页去数据库查询数据 这里可以去数据库查询每一页的数据 + // List data = data(); + // excelWriter.write(data, writeSheet); + // } + //} + } + + @Test + public void imageWritePoi() throws Exception { + String file = "/Users/zhuangjiaju/test/imagetest" + System.currentTimeMillis() + ".xlsx"; + SXSSFWorkbook workbook = new SXSSFWorkbook(); + SXSSFSheet sheet = workbook.createSheet("测试"); + CreationHelper helper = workbook.getCreationHelper(); + SXSSFDrawing sxssfDrawin = sheet.createDrawingPatriarch(); + + byte[] imagebyte = FileUtils.readFileToByteArray(new File("/Users/zhuangjiaju/Documents/demo.jpg")); + + for (int i = 0; i < 1 * 10000; i++) { + SXSSFRow row = sheet.createRow(i); + SXSSFCell cell = row.createCell(0); + cell.setCellValue(i); + int pictureIdx = workbook.addPicture(imagebyte, Workbook.PICTURE_TYPE_JPEG); + ClientAnchor anchor = helper.createClientAnchor(); + anchor.setCol1(0); + anchor.setRow1(i); + // 插入图片 + Picture pict = sxssfDrawin.createPicture(anchor, pictureIdx); + pict.resize(); + log.info("新增行:{}", i); + } + FileOutputStream fileOutputStream = new FileOutputStream(file); + workbook.write(fileOutputStream); + fileOutputStream.flush(); + workbook.close(); + } } From 14cc4d7712d64843ab5484feab7943318bda781c Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 8 Feb 2023 17:03:37 +0800 Subject: [PATCH 12/25] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E5=AF=BC=E5=87=BA=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/alibaba/easyexcel/test/demo/write/WriteTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java index a28ac324..351e0e0a 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java @@ -243,7 +243,7 @@ public class WriteTest { String fileName = TestFileUtil.getPath() + "imageWrite" + System.currentTimeMillis() + ".xlsx"; // 这里注意下 所有的图片都会放到内存 暂时没有很好的解法,大量图片的情况下建议 2选1: - // 1. 将图片上传到oss 或者其他存储网站: https://www.aliyun.com/product/oss + // 1. 将图片上传到oss 或者其他存储网站: https://www.aliyun.com/product/oss ,然后直接放链接 // 2. 使用: https://github.com/coobird/thumbnailator 或者其他工具压缩图片 String imagePath = TestFileUtil.getPath() + "converter" + File.separator + "img.jpg"; From 7fac3bf318b7e47f82417aee1742ebec0f375a40 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 8 Feb 2023 17:28:31 +0800 Subject: [PATCH 13/25] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=A4=A7=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E8=AF=BB=E5=8F=96=E6=A1=88=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../test/temp/write/TempWriteTest.java | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/write/TempWriteTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/write/TempWriteTest.java index b084ed04..a8603f12 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/write/TempWriteTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/temp/write/TempWriteTest.java @@ -132,4 +132,51 @@ public class TempWriteTest { fileOutputStream.flush(); workbook.close(); } + + @Test + public void tep() throws Exception { + String file = "/Users/zhuangjiaju/test/imagetest" + System.currentTimeMillis() + ".xlsx"; + SXSSFWorkbook workbook = new SXSSFWorkbook(); + SXSSFSheet sheet = workbook.createSheet("测试"); + CreationHelper helper = workbook.getCreationHelper(); + SXSSFDrawing sxssfDrawin = sheet.createDrawingPatriarch(); + + byte[] imagebyte = FileUtils.readFileToByteArray(new File("/Users/zhuangjiaju/Documents/demo.jpg")); + + for (int i = 0; i < 1 * 10000; i++) { + SXSSFRow row = sheet.createRow(i); + SXSSFCell cell = row.createCell(0); + cell.setCellValue(i); + int pictureIdx = workbook.addPicture(imagebyte, Workbook.PICTURE_TYPE_JPEG); + ClientAnchor anchor = helper.createClientAnchor(); + anchor.setCol1(0); + anchor.setRow1(i); + // 插入图片 + Picture pict = sxssfDrawin.createPicture(anchor, pictureIdx); + pict.resize(); + log.info("新增行:{}", i); + } + FileOutputStream fileOutputStream = new FileOutputStream(file); + workbook.write(fileOutputStream); + fileOutputStream.flush(); + workbook.close(); + } + + @Test + public void large() throws Exception { + String file = "/Users/zhuangjiaju/test/imagetest" + System.currentTimeMillis() + ".xlsx"; + SXSSFWorkbook workbook = new SXSSFWorkbook(new XSSFWorkbook( + new File("/Users/zhuangjiaju/IdeaProjects/easyexcel/easyexcel-test/src/test/resources/large/large07.xlsx"))); + SXSSFSheet sheet = workbook.createSheet("测试"); + + SXSSFRow row = sheet.createRow(500000); + SXSSFCell cell = row.createCell(0); + cell.setCellValue("test"); + + FileOutputStream fileOutputStream = new FileOutputStream(file); + workbook.write(fileOutputStream); + fileOutputStream.flush(); + workbook.close(); + + } } From 6ff6fbff13fc5b1a79d600af5261145bcd51de01 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 8 Feb 2023 19:20:53 +0800 Subject: [PATCH 14/25] =?UTF-8?q?*=20=E5=85=BC=E5=AE=B9`LocalDate`=20[Issu?= =?UTF-8?q?e=20#2908](https://github.com/alibaba/easyexcel/issues/2908)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- .../converters/DefaultConverterLoader.java | 10 ++- .../localdate/LocalDateDateConverter.java | 36 +++++++++ .../localdate/LocalDateNumberConverter.java | 57 ++++++++++++++ .../localdate/LocalDateStringConverter.java | 52 +++++++++++++ .../LocalDateTimeDateConverter.java | 4 +- ...java => LocalDateTimeNumberConverter.java} | 2 +- .../com/alibaba/excel/util/DateUtils.java | 74 +++++++++++++++++++ .../core/converter/ConverterDataListener.java | 11 ++- .../core/converter/ConverterDataTest.java | 8 +- .../core/converter/ConverterReadData.java | 3 + .../core/converter/ConverterWriteData.java | 3 + .../alibaba/easyexcel/test/util/TestUtil.java | 36 +++++++++ pom.xml | 2 +- update.md | 4 + 15 files changed, 290 insertions(+), 14 deletions(-) create mode 100644 easyexcel-core/src/main/java/com/alibaba/excel/converters/localdate/LocalDateDateConverter.java create mode 100644 easyexcel-core/src/main/java/com/alibaba/excel/converters/localdate/LocalDateNumberConverter.java create mode 100644 easyexcel-core/src/main/java/com/alibaba/excel/converters/localdate/LocalDateStringConverter.java rename easyexcel-core/src/main/java/com/alibaba/excel/converters/localdatetime/{LocalDateNumberConverter.java => LocalDateTimeNumberConverter.java} (96%) create mode 100644 easyexcel-test/src/test/java/com/alibaba/easyexcel/test/util/TestUtil.java diff --git a/README.md b/README.md index 7987c16c..c6b92caa 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ easyexcel重写了poi对07版Excel的解析,一个3M的excel用POI sax解析 com.alibaba easyexcel - 3.2.0 + 3.2.1 ``` diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/converters/DefaultConverterLoader.java b/easyexcel-core/src/main/java/com/alibaba/excel/converters/DefaultConverterLoader.java index ac2dd8dc..1b04d240 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/converters/DefaultConverterLoader.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/converters/DefaultConverterLoader.java @@ -31,7 +31,10 @@ import com.alibaba.excel.converters.inputstream.InputStreamImageConverter; import com.alibaba.excel.converters.integer.IntegerBooleanConverter; import com.alibaba.excel.converters.integer.IntegerNumberConverter; import com.alibaba.excel.converters.integer.IntegerStringConverter; -import com.alibaba.excel.converters.localdatetime.LocalDateNumberConverter; +import com.alibaba.excel.converters.localdate.LocalDateDateConverter; +import com.alibaba.excel.converters.localdate.LocalDateNumberConverter; +import com.alibaba.excel.converters.localdate.LocalDateStringConverter; +import com.alibaba.excel.converters.localdatetime.LocalDateTimeNumberConverter; import com.alibaba.excel.converters.localdatetime.LocalDateTimeDateConverter; import com.alibaba.excel.converters.localdatetime.LocalDateTimeStringConverter; import com.alibaba.excel.converters.longconverter.LongBooleanConverter; @@ -83,6 +86,9 @@ public class DefaultConverterLoader { putAllConverter(new DateStringConverter()); putAllConverter(new LocalDateNumberConverter()); + putAllConverter(new LocalDateStringConverter()); + + putAllConverter(new LocalDateTimeNumberConverter()); putAllConverter(new LocalDateTimeStringConverter()); putAllConverter(new DoubleBooleanConverter()); @@ -121,6 +127,7 @@ public class DefaultConverterLoader { putWriteConverter(new ByteNumberConverter()); putWriteConverter(new DateDateConverter()); putWriteConverter(new LocalDateTimeDateConverter()); + putWriteConverter(new LocalDateDateConverter()); putWriteConverter(new DoubleNumberConverter()); putWriteConverter(new FloatNumberConverter()); putWriteConverter(new IntegerNumberConverter()); @@ -139,6 +146,7 @@ public class DefaultConverterLoader { putWriteStringConverter(new BooleanStringConverter()); putWriteStringConverter(new ByteStringConverter()); putWriteStringConverter(new DateStringConverter()); + putWriteStringConverter(new LocalDateStringConverter()); putWriteStringConverter(new LocalDateTimeStringConverter()); putWriteStringConverter(new DoubleStringConverter()); putWriteStringConverter(new FloatStringConverter()); diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/converters/localdate/LocalDateDateConverter.java b/easyexcel-core/src/main/java/com/alibaba/excel/converters/localdate/LocalDateDateConverter.java new file mode 100644 index 00000000..3663476a --- /dev/null +++ b/easyexcel-core/src/main/java/com/alibaba/excel/converters/localdate/LocalDateDateConverter.java @@ -0,0 +1,36 @@ +package com.alibaba.excel.converters.localdate; + +import java.time.LocalDate; +import java.time.LocalDateTime; + +import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.metadata.GlobalConfiguration; +import com.alibaba.excel.metadata.data.WriteCellData; +import com.alibaba.excel.metadata.property.ExcelContentProperty; +import com.alibaba.excel.util.DateUtils; +import com.alibaba.excel.util.WorkBookUtil; + +/** + * LocalDate and date converter + * + * @author Jiaju Zhuang + */ +public class LocalDateDateConverter implements Converter { + @Override + public Class supportJavaTypeKey() { + return LocalDate.class; + } + + @Override + public WriteCellData convertToExcelData(LocalDate value, ExcelContentProperty contentProperty, + GlobalConfiguration globalConfiguration) throws Exception { + LocalDateTime localDateTime = value == null ? null : value.atTime(0, 0); + WriteCellData cellData = new WriteCellData<>(localDateTime); + String format = null; + if (contentProperty != null && contentProperty.getDateTimeFormatProperty() != null) { + format = contentProperty.getDateTimeFormatProperty().getFormat(); + } + WorkBookUtil.fillDataFormat(cellData, format, DateUtils.defaultLocalDateFormat); + return cellData; + } +} diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/converters/localdate/LocalDateNumberConverter.java b/easyexcel-core/src/main/java/com/alibaba/excel/converters/localdate/LocalDateNumberConverter.java new file mode 100644 index 00000000..fbec7a4f --- /dev/null +++ b/easyexcel-core/src/main/java/com/alibaba/excel/converters/localdate/LocalDateNumberConverter.java @@ -0,0 +1,57 @@ +package com.alibaba.excel.converters.localdate; + +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.LocalDateTime; + +import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.enums.CellDataTypeEnum; +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; + +/** + * LocalDate and number converter + * + * @author Jiaju Zhuang + */ +public class LocalDateNumberConverter implements Converter { + + @Override + public Class supportJavaTypeKey() { + return LocalDate.class; + } + + @Override + public CellDataTypeEnum supportExcelTypeKey() { + return CellDataTypeEnum.NUMBER; + } + + @Override + public LocalDate convertToJavaData(ReadCellData cellData, ExcelContentProperty contentProperty, + GlobalConfiguration globalConfiguration) { + if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null) { + return DateUtils.getLocalDate(cellData.getNumberValue().doubleValue(), + globalConfiguration.getUse1904windowing()); + } else { + return DateUtils.getLocalDate(cellData.getNumberValue().doubleValue(), + contentProperty.getDateTimeFormatProperty().getUse1904windowing()); + } + } + + @Override + public WriteCellData convertToExcelData(LocalDate value, ExcelContentProperty contentProperty, + GlobalConfiguration globalConfiguration) { + if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null) { + return new WriteCellData<>( + BigDecimal.valueOf(DateUtil.getExcelDate(value, globalConfiguration.getUse1904windowing()))); + } else { + return new WriteCellData<>(BigDecimal.valueOf( + DateUtil.getExcelDate(value, contentProperty.getDateTimeFormatProperty().getUse1904windowing()))); + } + } +} diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/converters/localdate/LocalDateStringConverter.java b/easyexcel-core/src/main/java/com/alibaba/excel/converters/localdate/LocalDateStringConverter.java new file mode 100644 index 00000000..68e3e0b0 --- /dev/null +++ b/easyexcel-core/src/main/java/com/alibaba/excel/converters/localdate/LocalDateStringConverter.java @@ -0,0 +1,52 @@ +package com.alibaba.excel.converters.localdate; + +import java.text.ParseException; +import java.time.LocalDate; + +import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.enums.CellDataTypeEnum; +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; + +/** + * LocalDate and string converter + * + * @author Jiaju Zhuang + */ +public class LocalDateStringConverter implements Converter { + @Override + public Class supportJavaTypeKey() { + return LocalDate.class; + } + + @Override + public CellDataTypeEnum supportExcelTypeKey() { + return CellDataTypeEnum.STRING; + } + + @Override + public LocalDate convertToJavaData(ReadCellData cellData, ExcelContentProperty contentProperty, + GlobalConfiguration globalConfiguration) throws ParseException { + if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null) { + return DateUtils.parseLocalDate(cellData.getStringValue(), null, globalConfiguration.getLocale()); + } else { + return DateUtils.parseLocalDate(cellData.getStringValue(), + contentProperty.getDateTimeFormatProperty().getFormat(), globalConfiguration.getLocale()); + } + } + + @Override + public WriteCellData convertToExcelData(LocalDate value, ExcelContentProperty contentProperty, + GlobalConfiguration globalConfiguration) { + if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null) { + return new WriteCellData<>(DateUtils.format(value, null, globalConfiguration.getLocale())); + } else { + return new WriteCellData<>( + DateUtils.format(value, contentProperty.getDateTimeFormatProperty().getFormat(), + globalConfiguration.getLocale())); + } + } +} diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/converters/localdatetime/LocalDateTimeDateConverter.java b/easyexcel-core/src/main/java/com/alibaba/excel/converters/localdatetime/LocalDateTimeDateConverter.java index 072a7864..39276df9 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/converters/localdatetime/LocalDateTimeDateConverter.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/converters/localdatetime/LocalDateTimeDateConverter.java @@ -10,13 +10,13 @@ import com.alibaba.excel.util.DateUtils; import com.alibaba.excel.util.WorkBookUtil; /** - * Date and date converter + * LocalDateTime and date converter * * @author Jiaju Zhuang */ public class LocalDateTimeDateConverter implements Converter { @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return LocalDateTime.class; } 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/LocalDateTimeNumberConverter.java similarity index 96% rename from easyexcel-core/src/main/java/com/alibaba/excel/converters/localdatetime/LocalDateNumberConverter.java rename to easyexcel-core/src/main/java/com/alibaba/excel/converters/localdatetime/LocalDateTimeNumberConverter.java index 4542fd08..51959fde 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/LocalDateTimeNumberConverter.java @@ -18,7 +18,7 @@ import org.apache.poi.ss.usermodel.DateUtil; * * @author Jiaju Zhuang */ -public class LocalDateNumberConverter implements Converter { +public class LocalDateTimeNumberConverter implements Converter { @Override public Class supportJavaTypeKey() { 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 fb19a105..cab7e4d0 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 @@ -4,7 +4,9 @@ import java.math.BigDecimal; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; +import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.LocalTime; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.Date; @@ -59,6 +61,8 @@ public class DateUtils { public static String defaultDateFormat = DATE_FORMAT_19; + public static String defaultLocalDateFormat = DATE_FORMAT_10; + private DateUtils() {} /** @@ -95,6 +99,25 @@ public class DateUtils { } } + /** + * convert string to date + * + * @param dateString + * @param dateFormat + * @param local + * @return + */ + public static LocalDate parseLocalDate(String dateString, String dateFormat, Locale local) { + if (StringUtils.isEmpty(dateFormat)) { + dateFormat = switchDateFormat(dateString); + } + if (local == null) { + return LocalDate.parse(dateString, DateTimeFormatter.ofPattern(dateFormat)); + } else { + return LocalDate.parse(dateString, DateTimeFormatter.ofPattern(dateFormat, local)); + } + } + /** * convert string to date * @@ -188,6 +211,38 @@ public class DateUtils { } } + /** + * Format date + * + * @param date + * @param dateFormat + * @return + */ + public static String format(LocalDate date, String dateFormat) { + return format(date, dateFormat, null); + } + + /** + * Format date + * + * @param date + * @param dateFormat + * @return + */ + public static String format(LocalDate date, String dateFormat, Locale local) { + if (date == null) { + return null; + } + if (StringUtils.isEmpty(dateFormat)) { + dateFormat = defaultLocalDateFormat; + } + if (local == null) { + return date.format(DateTimeFormatter.ofPattern(dateFormat)); + } else { + return date.format(DateTimeFormatter.ofPattern(dateFormat, local)); + } + } + /** * Format date * @@ -271,6 +326,25 @@ public class DateUtils { return DateUtil.getLocalDateTime(date, use1904windowing, true); } + /** + * Given an Excel date with either 1900 or 1904 date windowing, + * converts it to a java.time.LocalDate. + * + * 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 LocalDate getLocalDate(double date, boolean use1904windowing) { + LocalDateTime localDateTime = getLocalDateTime(date, use1904windowing); + return localDateTime == null ? null : localDateTime.toLocalDate(); + } + /** * Determine if it is a date format. * diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/converter/ConverterDataListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/converter/ConverterDataListener.java index fc353ba2..68a585fc 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/converter/ConverterDataListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/converter/ConverterDataListener.java @@ -3,9 +3,11 @@ package com.alibaba.easyexcel.test.core.converter; import java.math.BigDecimal; import java.math.BigInteger; import java.text.ParseException; +import java.time.LocalDate; import java.util.ArrayList; import java.util.List; +import com.alibaba.easyexcel.test.util.TestUtil; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.exception.ExcelCommonException; @@ -32,12 +34,9 @@ public class ConverterDataListener extends AnalysisEventListener data() throws Exception { List list = new ArrayList(); ConverterWriteData converterWriteData = new ConverterWriteData(); - converterWriteData.setDate(DateUtils.parseDate("2020-01-01 01:01:01")); - converterWriteData.setLocalDateTime(DateUtils.parseLocalDateTime("2020-01-01 01:01:01", null, null)); + converterWriteData.setDate(TestUtil.TEST_DATE); + converterWriteData.setLocalDate(TestUtil.TEST_LOCAL_DATE); + converterWriteData.setLocalDateTime(TestUtil.TEST_LOCAL_DATE_TIME); converterWriteData.setBooleanData(Boolean.TRUE); converterWriteData.setBigDecimal(BigDecimal.ONE); converterWriteData.setBigInteger(BigInteger.ONE); diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/converter/ConverterReadData.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/converter/ConverterReadData.java index f9a6bee6..1ee3aea9 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/converter/ConverterReadData.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/converter/ConverterReadData.java @@ -2,6 +2,7 @@ package com.alibaba.easyexcel.test.core.converter; import java.math.BigDecimal; import java.math.BigInteger; +import java.time.LocalDate; import java.time.LocalDateTime; import java.util.Date; @@ -22,6 +23,8 @@ public class ConverterReadData { @ExcelProperty("日期") private Date date; @ExcelProperty("本地日期") + private LocalDate localDate; + @ExcelProperty("本地日期时间") private LocalDateTime localDateTime; @ExcelProperty("布尔") private Boolean booleanData; diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/converter/ConverterWriteData.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/converter/ConverterWriteData.java index 6782aa1a..88d7b765 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/converter/ConverterWriteData.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/converter/ConverterWriteData.java @@ -2,6 +2,7 @@ package com.alibaba.easyexcel.test.core.converter; import java.math.BigDecimal; import java.math.BigInteger; +import java.time.LocalDate; import java.time.LocalDateTime; import java.util.Date; @@ -22,6 +23,8 @@ public class ConverterWriteData { @ExcelProperty("日期") private Date date; @ExcelProperty("本地日期") + private LocalDate localDate; + @ExcelProperty("本地日期时间") private LocalDateTime localDateTime; @ExcelProperty("布尔") private Boolean booleanData; diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/util/TestUtil.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/util/TestUtil.java new file mode 100644 index 00000000..8246f5b9 --- /dev/null +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/util/TestUtil.java @@ -0,0 +1,36 @@ +package com.alibaba.easyexcel.test.util; + +import java.io.File; +import java.io.InputStream; +import java.text.ParseException; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.Date; + +import com.alibaba.excel.util.DateUtils; + +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; + +/** + * test util + * + * @author Jiaju Zhuang + */ +@Slf4j +public class TestUtil { + + public static final Date TEST_DATE; + public static final LocalDate TEST_LOCAL_DATE = LocalDate.of(2020, 1, 1); + public static final LocalDateTime TEST_LOCAL_DATE_TIME = LocalDateTime.of(2020, 1, 1, 1, 1, 1); + + static { + try { + TEST_DATE = DateUtils.parseDate("2020-01-01 01:01:01"); + } catch (ParseException e) { + log.error("init TestUtil error.", e); + throw new RuntimeException(e); + } + } + +} diff --git a/pom.xml b/pom.xml index 70153a8e..3466d01e 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ - 3.2.0 + 3.2.1 UTF-8 1.8 true diff --git a/update.md b/update.md index 36c98000..54c01471 100644 --- a/update.md +++ b/update.md @@ -1,3 +1,7 @@ +# 3.2.1 + +* 兼容`LocalDate` [Issue #2908](https://github.com/alibaba/easyexcel/issues/2908) + # 3.2.0 * 修复部分xlsx读取日期可能相差1秒的bug [Issue #1956](https://github.com/alibaba/easyexcel/issues/1956) From eb8c7d544617a17d630aae28c11ff8ef697938ba Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 8 Feb 2023 19:33:37 +0800 Subject: [PATCH 15/25] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../excel/write/builder/ExcelWriterBuilder.java | 14 ++++++++++++-- .../excel/write/metadata/WriteWorkbook.java | 4 ++-- .../easyexcel/test/demo/write/WriteTest.java | 1 + 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/write/builder/ExcelWriterBuilder.java b/easyexcel-core/src/main/java/com/alibaba/excel/write/builder/ExcelWriterBuilder.java index 75d702f8..76af6f66 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/write/builder/ExcelWriterBuilder.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/write/builder/ExcelWriterBuilder.java @@ -66,7 +66,6 @@ public class ExcelWriterBuilder extends AbstractExcelWriterParameterBuilder * If 'inputStream' and 'file' all not empty, file first */ @@ -66,7 +67,6 @@ public class WriteWorkbook extends WriteBasicParameter { * Whether the encryption *

* WARRING:Encryption is when the entire file is read into memory, so it is very memory intensive. - * */ private String password; /** diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java index 351e0e0a..a99f7d9d 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java @@ -401,6 +401,7 @@ public class WriteTest { String templateFileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx"; String fileName = TestFileUtil.getPath() + "templateWrite" + System.currentTimeMillis() + ".xlsx"; // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭 + // 这里要注意 withTemplate 的模板文件会全量存储在内存里面,所以尽量不要用于追加文件,如果文件模板文件过大会OOM EasyExcel.write(fileName, DemoData.class).withTemplate(templateFileName).sheet().doWrite(data()); } From 3cc6f468ac20bff53f6ea00c01fd1a699b3a8f8d Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Wed, 8 Feb 2023 20:52:01 +0800 Subject: [PATCH 16/25] =?UTF-8?q?=E4=BF=AE=E6=94=B9map=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../test/java/com/alibaba/easyexcel/test/demo/fill/FillTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/fill/FillTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/fill/FillTest.java index 618a030f..3b3c37fc 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/fill/FillTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/fill/FillTest.java @@ -64,6 +64,7 @@ public class FillTest { public void listFill() { // 模板注意 用{} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 用"\{","\}"代替 // 填充list 的时候还要注意 模板中{.} 多了个点 表示list + // 如果填充list的对象是map,必须包涵所有list的key,哪怕数据为null,必须使用map.put(key,null) String templateFileName = TestFileUtil.getPath() + "demo" + File.separator + "fill" + File.separator + "list.xlsx"; From 6a3f09905c4b82464900c701ddb60d7bdcde1973 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Thu, 9 Feb 2023 18:44:34 +0800 Subject: [PATCH 17/25] =?UTF-8?q?=E9=98=B2=E6=AD=A2=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E4=B8=8D=E8=B0=83=E7=94=A8finish?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/alibaba/excel/ExcelReader.java | 16 ++++++++++++++++ .../main/java/com/alibaba/excel/ExcelWriter.java | 15 +++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/ExcelReader.java b/easyexcel-core/src/main/java/com/alibaba/excel/ExcelReader.java index 9508d941..83b46f40 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/ExcelReader.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/ExcelReader.java @@ -11,11 +11,14 @@ import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.read.metadata.ReadSheet; import com.alibaba.excel.read.metadata.ReadWorkbook; +import lombok.extern.slf4j.Slf4j; + /** * Excel readers are all read in event mode. * * @author jipengfei */ +@Slf4j public class ExcelReader implements Closeable { /** @@ -104,4 +107,17 @@ public class ExcelReader implements Closeable { public void close() { finish(); } + + /** + * Prevents calls to {@link #finish} from freeing the cache + * + */ + @Override + protected void finalize() { + try { + finish(); + } catch (Throwable e) { + log.warn("Destroy object failed", e); + } + } } diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/ExcelWriter.java b/easyexcel-core/src/main/java/com/alibaba/excel/ExcelWriter.java index 95d5446b..3c074384 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/ExcelWriter.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/ExcelWriter.java @@ -12,6 +12,8 @@ import com.alibaba.excel.write.metadata.WriteTable; import com.alibaba.excel.write.metadata.WriteWorkbook; import com.alibaba.excel.write.metadata.fill.FillConfig; +import lombok.extern.slf4j.Slf4j; + /** * Excel Writer This tool is used to write value out to Excel via POI. This object can perform the following two * functions. @@ -23,6 +25,7 @@ import com.alibaba.excel.write.metadata.fill.FillConfig; * * @author jipengfei */ +@Slf4j public class ExcelWriter implements Closeable { private final ExcelBuilder excelBuilder; @@ -154,4 +157,16 @@ public class ExcelWriter implements Closeable { public void close() { finish(); } + + /** + * Prevents calls to {@link #finish} from freeing the cache + */ + @Override + protected void finalize() { + try { + finish(); + } catch (Throwable e) { + log.warn("Destroy object failed", e); + } + } } From 8a202955ed98cfad8e1cdf486f720f607384f0ca Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Thu, 9 Feb 2023 19:07:25 +0800 Subject: [PATCH 18/25] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=96=87=E6=A1=88?= =?UTF-8?q?=E6=8F=8F=E8=BF=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/alibaba/easyexcel/test/demo/write/WriteTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java index a99f7d9d..2b9a802a 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java @@ -402,6 +402,7 @@ public class WriteTest { String fileName = TestFileUtil.getPath() + "templateWrite" + System.currentTimeMillis() + ".xlsx"; // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭 // 这里要注意 withTemplate 的模板文件会全量存储在内存里面,所以尽量不要用于追加文件,如果文件模板文件过大会OOM + // 如果要再文件中追加(无法在一个线程里面处理,可以在一个线程的建议参照多次写入的demo) 建议临时存储到数据库 或者 磁盘缓存 然后再一次性写入 EasyExcel.write(fileName, DemoData.class).withTemplate(templateFileName).sheet().doWrite(data()); } From 8d8cbb784522bef69ba1b1dd165bfd1efd3818a0 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Thu, 9 Feb 2023 19:09:12 +0800 Subject: [PATCH 19/25] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=96=87=E6=A1=88?= =?UTF-8?q?=E6=8F=8F=E8=BF=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/alibaba/easyexcel/test/demo/write/WriteTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java index 2b9a802a..e2418daf 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java @@ -402,7 +402,7 @@ public class WriteTest { String fileName = TestFileUtil.getPath() + "templateWrite" + System.currentTimeMillis() + ".xlsx"; // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭 // 这里要注意 withTemplate 的模板文件会全量存储在内存里面,所以尽量不要用于追加文件,如果文件模板文件过大会OOM - // 如果要再文件中追加(无法在一个线程里面处理,可以在一个线程的建议参照多次写入的demo) 建议临时存储到数据库 或者 磁盘缓存 然后再一次性写入 + // 如果要再文件中追加(无法在一个线程里面处理,可以在一个线程的建议参照多次写入的demo) 建议临时存储到数据库 或者 磁盘缓存(ehcache) 然后再一次性写入 EasyExcel.write(fileName, DemoData.class).withTemplate(templateFileName).sheet().doWrite(data()); } From d58f51db0fac20971f0cb49363056e30809db8a8 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Thu, 9 Feb 2023 19:42:46 +0800 Subject: [PATCH 20/25] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=96=87=E6=A1=88?= =?UTF-8?q?=E6=8F=8F=E8=BF=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/alibaba/easyexcel/test/demo/write/WriteTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java index e2418daf..1e70126e 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java @@ -365,6 +365,7 @@ public class WriteTest { writeCellStyleData.setFillForegroundColor(IndexedColors.GREEN.getIndex()); // 设置单个单元格多种样式 + // 这里需要设置 inMomery=true 不然会导致无法展示单个单元格多种样式,所以慎用 WriteCellData richTest = new WriteCellData<>(); richTest.setType(CellDataTypeEnum.RICH_TEXT_STRING); writeCellDemoData.setRichText(richTest); From 58e5ca173936fdf41069891b26604f94c62a6a16 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Fri, 10 Feb 2023 15:02:57 +0800 Subject: [PATCH 21/25] =?UTF-8?q?*=20=E4=BC=98=E5=8C=96=E5=A4=A7=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E5=86=85=E5=AD=98=E5=AD=98=E5=82=A8=EF=BC=8C=E5=87=8F?= =?UTF-8?q?=E5=B0=91=E5=86=85=E5=AD=98=E5=8D=A0=E7=94=A8=20[Issue=20#2657]?= =?UTF-8?q?(https://github.com/alibaba/easyexcel/issues/2657)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/alibaba/excel/cache/Ehcache.java | 33 +++++++--- .../selector/SimpleReadCacheSelector.java | 66 ++++++++++++++----- update.md | 4 +- 3 files changed, 75 insertions(+), 28 deletions(-) diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/cache/Ehcache.java b/easyexcel-core/src/main/java/com/alibaba/excel/cache/Ehcache.java index b7b542ee..f5481b43 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/cache/Ehcache.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/cache/Ehcache.java @@ -15,6 +15,7 @@ import org.ehcache.config.CacheConfiguration; import org.ehcache.config.builders.CacheConfigurationBuilder; import org.ehcache.config.builders.CacheManagerBuilder; import org.ehcache.config.builders.ResourcePoolsBuilder; +import org.ehcache.config.units.EntryUnit; import org.ehcache.config.units.MemoryUnit; /** @@ -50,12 +51,27 @@ public class Ehcache implements ReadCache { */ private int cacheMiss = 0; - public Ehcache(int maxCacheActivateSize) { - activeCacheConfiguration = CacheConfigurationBuilder - .newCacheConfigurationBuilder(Integer.class, ArrayList.class, - ResourcePoolsBuilder.newResourcePoolsBuilder().heap(maxCacheActivateSize, MemoryUnit.MB)) - .withSizeOfMaxObjectGraph(1000 * 1000L).withSizeOfMaxObjectSize(maxCacheActivateSize, MemoryUnit.MB) - .build(); + @Deprecated + public Ehcache(Integer maxCacheActivateSize) { + this(maxCacheActivateSize, null); + } + + public Ehcache(Integer maxCacheActivateSize, Integer maxCacheActivateBatchCount) { + // In order to be compatible with the code + // If the user set up `maxCacheActivateSize`, then continue using it + if (maxCacheActivateSize != null) { + this.activeCacheConfiguration = CacheConfigurationBuilder + .newCacheConfigurationBuilder(Integer.class, ArrayList.class, + ResourcePoolsBuilder.newResourcePoolsBuilder() + .heap(maxCacheActivateSize, MemoryUnit.MB)) + .build(); + } else { + this.activeCacheConfiguration = CacheConfigurationBuilder + .newCacheConfigurationBuilder(Integer.class, ArrayList.class, + ResourcePoolsBuilder.newResourcePoolsBuilder() + .heap(maxCacheActivateBatchCount, EntryUnit.ENTRIES)) + .build(); + } } static { @@ -64,9 +80,8 @@ public class Ehcache implements ReadCache { CacheManagerBuilder.newCacheManagerBuilder().with(CacheManagerBuilder.persistence(cacheFile)).build(true); ACTIVE_CACHE_MANAGER = CacheManagerBuilder.newCacheManagerBuilder().build(true); FILE_CACHE_CONFIGURATION = CacheConfigurationBuilder - .newCacheConfigurationBuilder(Integer.class, ArrayList.class, - ResourcePoolsBuilder.newResourcePoolsBuilder().disk(10, MemoryUnit.GB)) - .withSizeOfMaxObjectGraph(1000 * 1000L).withSizeOfMaxObjectSize(10, MemoryUnit.GB).build(); + .newCacheConfigurationBuilder(Integer.class, ArrayList.class, ResourcePoolsBuilder.newResourcePoolsBuilder() + .disk(20, MemoryUnit.GB)).build(); } @Override diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/cache/selector/SimpleReadCacheSelector.java b/easyexcel-core/src/main/java/com/alibaba/excel/cache/selector/SimpleReadCacheSelector.java index 658806bd..278c63be 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/cache/selector/SimpleReadCacheSelector.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/cache/selector/SimpleReadCacheSelector.java @@ -2,6 +2,10 @@ package com.alibaba.excel.cache.selector; import java.io.IOException; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; import org.apache.poi.openxml4j.opc.PackagePart; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -15,6 +19,9 @@ import com.alibaba.excel.cache.ReadCache; * * @author Jiaju Zhuang **/ +@Getter +@Setter +@EqualsAndHashCode public class SimpleReadCacheSelector implements ReadCacheSelector { private static final Logger LOGGER = LoggerFactory.getLogger(SimpleReadCacheSelector.class); /** @@ -24,37 +31,46 @@ public class SimpleReadCacheSelector implements ReadCacheSelector { /** * If it's less than 5M, use map cache, or use ehcache.unit MB. */ - private static final int DEFAULT_MAX_USE_MAP_CACHE_SIZE = 5; + private static final long DEFAULT_MAX_USE_MAP_CACHE_SIZE = 5; + /** - * Maximum size of cache activation.unit MB. + * Maximum batch of `SharedStrings` stored in memory. + * The batch size is 100.{@link Ehcache#BATCH_COUNT} */ - private static final int DEFAULT_MAX_EHCACHE_ACTIVATE_SIZE = 20; + private static final int DEFAULT_MAX_EHCACHE_ACTIVATE_BATCH_COUNT = 20; /** * Shared strings exceeding this value will use {@link Ehcache},or use {@link MapCache}.unit MB. */ - private final long maxUseMapCacheSize; + private Long maxUseMapCacheSize; /** * Maximum size of cache activation.unit MB. + * + * @deprecated Please use maxCacheActivateBatchCount to control the size of the occupied memory + */ + @Deprecated + private Integer maxCacheActivateSize; + + /** + * Maximum batch of `SharedStrings` stored in memory. + * The batch size is 100.{@link Ehcache#BATCH_COUNT} */ - private final int maxCacheActivateSize; + private Integer maxCacheActivateBatchCount; public SimpleReadCacheSelector() { - this(DEFAULT_MAX_USE_MAP_CACHE_SIZE, DEFAULT_MAX_EHCACHE_ACTIVATE_SIZE); } - public SimpleReadCacheSelector(long maxUseMapCacheSize, int maxCacheActivateSize) { - if (maxUseMapCacheSize <= 0) { - this.maxUseMapCacheSize = DEFAULT_MAX_USE_MAP_CACHE_SIZE; - } else { - this.maxUseMapCacheSize = maxUseMapCacheSize; - } - if (maxCacheActivateSize <= 0) { - this.maxCacheActivateSize = DEFAULT_MAX_EHCACHE_ACTIVATE_SIZE; - } else { - this.maxCacheActivateSize = maxCacheActivateSize; - } + /** + * Parameter maxCacheActivateSize has already been abandoned + * + * @param maxUseMapCacheSize + * @param maxCacheActivateSize + */ + @Deprecated + public SimpleReadCacheSelector(Long maxUseMapCacheSize, Integer maxCacheActivateSize) { + this.maxUseMapCacheSize = maxUseMapCacheSize; + this.maxCacheActivateSize = maxCacheActivateSize; } @Override @@ -68,6 +84,9 @@ public class SimpleReadCacheSelector implements ReadCacheSelector { return new MapCache(); } } + if (maxUseMapCacheSize == null) { + maxUseMapCacheSize = DEFAULT_MAX_USE_MAP_CACHE_SIZE; + } if (size < maxUseMapCacheSize * B2M) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("Use map cache.size:{}", size); @@ -77,6 +96,17 @@ public class SimpleReadCacheSelector implements ReadCacheSelector { if (LOGGER.isDebugEnabled()) { LOGGER.debug("Use ehcache.size:{}", size); } - return new Ehcache(maxCacheActivateSize); + + // In order to be compatible with the code + // If the user set up `maxCacheActivateSize`, then continue using it + if (maxCacheActivateSize != null) { + return new Ehcache(maxCacheActivateSize, maxCacheActivateBatchCount); + } else { + if (maxCacheActivateBatchCount == null) { + maxCacheActivateBatchCount = DEFAULT_MAX_EHCACHE_ACTIVATE_BATCH_COUNT; + } + return new Ehcache(maxCacheActivateSize, maxCacheActivateBatchCount); + } + } } diff --git a/update.md b/update.md index 54c01471..3383244d 100644 --- a/update.md +++ b/update.md @@ -1,6 +1,7 @@ # 3.2.1 * 兼容`LocalDate` [Issue #2908](https://github.com/alibaba/easyexcel/issues/2908) +* 优化大文件内存存储,减少内存占用 [Issue #2657](https://github.com/alibaba/easyexcel/issues/2657) # 3.2.0 @@ -14,7 +15,8 @@ # 3.1.4 -* 提高xlsx读取兼容性:在存在第一行很多空列的情况下,忽略空列 +* 提高xlsx读取兼容性:在存在第一行很多空 +* 列的情况下,忽略空列 # 3.1.3 From 9dd9fa7638479c9213adc6e6376e413cb849ee69 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Fri, 10 Feb 2023 15:10:10 +0800 Subject: [PATCH 22/25] =?UTF-8?q?*=20=E4=BC=98=E5=8C=96=E5=A4=A7=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E5=86=85=E5=AD=98=E5=AD=98=E5=82=A8=EF=BC=8C=E5=87=8F?= =?UTF-8?q?=E5=B0=91=E5=86=85=E5=AD=98=E5=8D=A0=E7=94=A8=20[Issue=20#2657]?= =?UTF-8?q?(https://github.com/alibaba/easyexcel/issues/2657)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- img/readme/alipay.png | Bin 22337 -> 0 bytes img/readme/large.png | Bin 58751 -> 21022 bytes 3 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 img/readme/alipay.png diff --git a/README.md b/README.md index c6b92caa..83be0b17 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ easyexcel重写了poi对07版Excel的解析,一个3M的excel用POI sax解析 * github地址:[https://github.com/alibaba/easyexcel](https://github.com/alibaba/easyexcel) * gitee地址:[https://gitee.com/easyexcel/easyexcel](https://gitee.com/easyexcel/easyexcel) -# 64M内存20秒读取75M(46W行25列)的Excel(3.0.2+版本) +# 16M内存23秒读取75M(46W行25列)的Excel(3.2.1+版本) 当然还有[极速模式](https://easyexcel.opensource.alibaba.com/qa/read#%E5%BC%80%E5%90%AF%E6%80%A5%E9%80%9F%E6%A8%A1%E5%BC%8F) 能更快,但是内存占用会在100M多一点 diff --git a/img/readme/alipay.png b/img/readme/alipay.png deleted file mode 100644 index 48cbfe08d4f62dff88b4595ba461145f2db7e90e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22337 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 literal 58751 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%0A0cQvb>e=|+PJTx7F~YVhu-v#51+lIp&g>_Z=x;Z zG~94m5i&ON!8B3#T_mHR;Jcd$oW(-Plp@&^C1?ZSJB={M04aya@iyI{Dj?cH8$r&k zdCEAZFzaq{F%qz>XJ;!H2p4&-{gOc^f)ik?94sM1#I%e8fndSWy*kpk`3n3$>hRb{n^=R;&gd9NL^ezOr>Hr zhl(}LF+p3I5zByQm6pk#({|1%pv5A$1vlmY;Pm+a z6xw<~hyn$@^QmV9Y`f5QTF`d-5qyIDTiE@-Z#iqkW#VkTIRtfYbB3$CXt>cCegqmLSx^595l0t4uXt3z({KFU_ zOsP>$uqaZ)|h3tq?N=NX#W!H^{yq!ZP=t9A_l08{{anV%<7X1{bZH zeNvPUUK9!`fuJ^v*Ove=qZoIw)HR-fyJ)Cw!`h>Sy4+o5JQ*|^VsGXgdX8D~!<@$* z=-0ja)2(RREyXSp01*Kb3@1u9{S7om^g82tYC7+R(}sY$TA+u8AXrd9B$JCkC0iDM z!r8p#(HSbtW~aGnr)~8-_P}?#kFVFE5_v+lj%9F1FwR~Frm~mlxYx(%` z>2=ror9MJ}wi^bGv9;-HX^tFP3V5}GiIKrb69R&~J6r0kuWoI2It!w}tZi-}(m;tx z#YG4j;)!d#NbfU_!J58aZ*k$()y^@6WT500H_w^nysJkHdYBJ-`CI+5BtP;eEU&CI z^6vV|!g8Nuh|^-Ji^GG;$%Xk=#PW>c4y{xwiw=26B{ytJeb)99kaMg4^f3elE49)$ zhya?c1-@;*kk$Ela1795|HBN>XbMeL#ND4*B|aGC|g3G1N`jgGkL#@Uq!yGKtRyvwfWZ4B7g zf8|Y&dGxD4{`%Xvc0b_lenp!Ck8Lo&oY!u+NZ=4ui{X|iBCajEMO*Y;*X@vr#i>8I zp0&0Zy6NqK6sT4)U2&qR_3(ODOTjQZ|#%VED~Xsv8#)7y3KEGsd*K`9k0rpvmRpDl;nwqmTVq;dIAA~k!yEO6_87P;-eA)H=Mbl@%;frqm_Vy~fn%)V8muYa6^s!mV&q{Ee5==>?^LB$&FQQnrQ)X|Yt_6h*P% z&Q2p`py}$3n_xRc+r2{DsRy3XLmNbBllGp*0V)}7&$!B5J8*JHRA32&_L(<7=8=zm z(VO3Ob~oD&9&Gn7+DI91rj+&5ZnjPGPRm}X8)EDgwa-|~+G1eWCC)C6WvyQ<3f%Ne z9H5}LYl1E{#&IKyq0NRxcLsK9##~ULj3@RSEY;K5zy@x4L>VWV#lj^9SJCDR)8vs^ zDCapkP%0L=hKZZV_I5a%53C!8>2(KU$>p@~GK*?04+)7dmrYlq$l-}=32`FX-k#O2 z4Rm%k+;jj*c>{%f;D(iIH%!s2?d7MpxO^h^ok09$!|k-r&O6CrZdSr0T^pU|CTFfW z0MTM*Vr)D7Ml318F$e1ItPX06gdRwp-TG^7G^2pDl-~ZvXpCr6V&{ggE{!mFWrehs z4zr=owk}CTqZGF?EOB;Ixp2E536wZ0_nAVvq9T12fmj;8zX6C&Q=;r1qU|1{jVn9# z_4n6nSzZn%RDgY=FRLLKZbmI(v(br# zMLt`BlypidqV=$qkgWnS*1)1*tb@hR(eEfwL#?3$(FOeEHN@U;46VKl|B_ebZ;( z-b=q89u*=01--WSEVivQk`kJM zGSGdV5@AGiEY3|J$=DrIM(8$5z52;>qQS=!QaGwm{vqGYUU5SIQF0t|cx>#t7oA%b zm%ro@kdjuQD=2+OQql(hTw8Az-1G(>qV1lcEjm>0^40eY#sC$g4Pok`Pmx!K4>o

2tq5va?D4{$Se<+K%i++h81F@F@p( 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 Date: Fri, 10 Feb 2023 17:16:10 +0800 Subject: [PATCH 23/25] =?UTF-8?q?*=20=E5=9C=A8=E4=B8=B4=E6=97=B6=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E8=A2=AB=E5=88=A0=E9=99=A4=E7=9A=84=E6=83=85=E5=86=B5?= =?UTF-8?q?=E4=B8=8B=E8=83=BD=E6=AD=A3=E5=B8=B8=E7=9A=84=E8=AF=BB=E5=8F=96?= =?UTF-8?q?=20[Issue=20#2693](https://github.com/alibaba/easyexcel/issues/?= =?UTF-8?q?2693)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/alibaba/excel/cache/Ehcache.java | 13 ++++-- .../core/compatibility/CompatibilityTest.java | 41 +++++++++++++++++++ .../test/core/large/LargeDataTest.java | 13 +----- update.md | 1 + 4 files changed, 52 insertions(+), 16 deletions(-) diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/cache/Ehcache.java b/easyexcel-core/src/main/java/com/alibaba/excel/cache/Ehcache.java index ce506792..6387d2a1 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/cache/Ehcache.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/cache/Ehcache.java @@ -2,6 +2,7 @@ package com.alibaba.excel.cache; import java.io.File; import java.util.ArrayList; +import java.util.Optional; import java.util.UUID; import com.alibaba.excel.context.AnalysisContext; @@ -79,7 +80,8 @@ public class Ehcache implements ReadCache { static { CACHE_PATH_FILE = FileUtils.createCacheTmpFile(); FILE_CACHE_MANAGER = - CacheManagerBuilder.newCacheManagerBuilder().with(CacheManagerBuilder.persistence(CACHE_PATH_FILE)).build(true); + CacheManagerBuilder.newCacheManagerBuilder().with(CacheManagerBuilder.persistence(CACHE_PATH_FILE)).build( + true); ACTIVE_CACHE_MANAGER = CacheManagerBuilder.newCacheManagerBuilder().build(true); FILE_CACHE_CONFIGURATION = CacheConfigurationBuilder .newCacheConfigurationBuilder(Integer.class, ArrayList.class, ResourcePoolsBuilder.newResourcePoolsBuilder() @@ -92,13 +94,16 @@ public class Ehcache implements ReadCache { try { fileCache = FILE_CACHE_MANAGER.createCache(cacheAlias, FILE_CACHE_CONFIGURATION); } catch (IllegalStateException e) { - //fix Issue #2693,重建缓存文件夹 + //fix Issue #2693,Temporary files may be deleted if there is no operation for a long time, so they need + // to be recreated. if (CACHE_PATH_FILE.exists()) { throw e; } synchronized (Ehcache.class) { - if (!CACHE_PATH_FILE.exists()){ - log.debug("cache file dir is not exist retry create"); + if (!CACHE_PATH_FILE.exists()) { + if (log.isDebugEnabled()) { + log.debug("cache file dir is not exist retry create"); + } FileUtils.createDirectory(CACHE_PATH_FILE); } } 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 f4aae4a8..368f91b8 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,16 +1,24 @@ package com.alibaba.easyexcel.test.core.compatibility; +import java.io.File; import java.math.BigDecimal; +import java.util.ArrayList; import java.util.List; import java.util.Map; +import com.alibaba.easyexcel.test.core.large.LargeData; +import com.alibaba.easyexcel.test.core.large.LargeDataListener; +import com.alibaba.easyexcel.test.core.simple.SimpleData; import com.alibaba.easyexcel.test.util.TestFileUtil; import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.cache.Ehcache; import com.alibaba.excel.constant.EasyExcelConstants; import com.alibaba.excel.enums.ReadDefaultReturnEnum; +import com.alibaba.excel.util.FileUtils; import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; +import org.apache.poi.util.TempFile; import org.junit.Assert; import org.junit.FixMethodOrder; import org.junit.Test; @@ -116,4 +124,37 @@ public class CompatibilityTest { Assert.assertEquals("24.20", list.get(0).get(11)); } + @Test + public void t08() { + // https://github.com/alibaba/easyexcel/issues/2693 + // Temporary files may be deleted if there is no operation for a long time, so they need to be recreated. + File file = TestFileUtil.createNewFile("compatibility/t08.xlsx"); + EasyExcel.write(file, SimpleData.class) + .sheet() + .doWrite(data()); + + List> list = EasyExcel.read(file) + .readCache(new Ehcache(null, 20)) + .sheet() + .doReadSync(); + Assert.assertEquals(10L, list.size()); + + FileUtils.delete(new File(System.getProperty(TempFile.JAVA_IO_TMPDIR))); + + list = EasyExcel.read(file) + .readCache(new Ehcache(null, 20)) + .sheet() + .doReadSync(); + Assert.assertEquals(10L, list.size()); + } + + private List data() { + List list = new ArrayList(); + for (int i = 0; i < 10; i++) { + SimpleData simpleData = new SimpleData(); + simpleData.setName("姓名" + i); + list.add(simpleData); + } + return list; + } } diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/large/LargeDataTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/large/LargeDataTest.java index aeebdde8..8862fe18 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/large/LargeDataTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/large/LargeDataTest.java @@ -133,18 +133,7 @@ public class LargeDataTest { LOGGER.info("{} vs {}", cost, costPoi); Assert.assertTrue(costPoi * 2 > cost); } - @Test - public void t05Read() throws Exception { - long start = System.currentTimeMillis(); - EasyExcel.read(TestFileUtil.getPath() + "large" + File.separator + "large07.xlsx", LargeData.class, - new LargeDataListener()).headRowNumber(2).sheet().doRead(); - LOGGER.info("Large data total time spent:{}", System.currentTimeMillis() - start); - FileUtils.delete(new File(System.getProperty(TempFile.JAVA_IO_TMPDIR))); - start = System.currentTimeMillis(); - EasyExcel.read(TestFileUtil.getPath() + "large" + File.separator + "large07.xlsx", LargeData.class, - new LargeDataListener()).headRowNumber(2).sheet().doRead(); - LOGGER.info("Large data total time spent:{}", System.currentTimeMillis() - start); - } + private List data() { List list = new ArrayList<>(); int size = i + 100; diff --git a/update.md b/update.md index 3383244d..f118eeec 100644 --- a/update.md +++ b/update.md @@ -2,6 +2,7 @@ * 兼容`LocalDate` [Issue #2908](https://github.com/alibaba/easyexcel/issues/2908) * 优化大文件内存存储,减少内存占用 [Issue #2657](https://github.com/alibaba/easyexcel/issues/2657) +* 在临时文件被删除的情况下能正常的读取 [Issue #2693](https://github.com/alibaba/easyexcel/issues/2693) # 3.2.0 From 7d19499304c37a7e45a73521be500e8c3f1f8d05 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Fri, 10 Feb 2023 18:49:10 +0800 Subject: [PATCH 24/25] =?UTF-8?q?*=20=E5=88=86=E9=A1=B5=E8=AF=BB=E5=8F=96?= =?UTF-8?q?=E7=9B=91=E5=90=AC=E5=99=A8=E6=94=AF=E6=8C=81=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E5=88=86=E9=A1=B5=E6=9D=A1=E6=95=B0=20[Issue=20#2383]?= =?UTF-8?q?(https://github.com/alibaba/easyexcel/issues/2383)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../excel/read/listener/PageReadListener.java | 15 ++++++++----- .../com/alibaba/excel/util/SheetUtils.java | 9 ++++---- .../test/core/simple/SimpleDataTest.java | 22 +++++++++++++++++-- .../easyexcel/test/demo/read/ReadTest.java | 5 +++-- update.md | 1 + 5 files changed, 38 insertions(+), 14 deletions(-) diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/read/listener/PageReadListener.java b/easyexcel-core/src/main/java/com/alibaba/excel/read/listener/PageReadListener.java index 8c3fe782..b97db357 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/read/listener/PageReadListener.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/read/listener/PageReadListener.java @@ -15,7 +15,7 @@ import org.apache.commons.collections4.CollectionUtils; */ public class PageReadListener implements ReadListener { /** - * Single handle the amount of data + * Defuault single handle the amount of data */ public static int BATCH_COUNT = 100; /** @@ -27,23 +27,26 @@ public class PageReadListener implements ReadListener { */ private final Consumer> consumer; - private final int pageSize; + /** + * Single handle the amount of data + */ + private final int batchCount; public PageReadListener(Consumer> consumer) { this(consumer, BATCH_COUNT); } - public PageReadListener(Consumer> consumer,int pageSize) { + public PageReadListener(Consumer> consumer, int batchCount) { this.consumer = consumer; - this.pageSize = pageSize; + this.batchCount = batchCount; } @Override public void invoke(T data, AnalysisContext context) { cachedDataList.add(data); - if (cachedDataList.size() >= pageSize) { + if (cachedDataList.size() >= batchCount) { consumer.accept(cachedDataList); - cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); + cachedDataList = ListUtils.newArrayListWithExpectedSize(batchCount); } } diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/util/SheetUtils.java b/easyexcel-core/src/main/java/com/alibaba/excel/util/SheetUtils.java index c2c727c7..12886c85 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/util/SheetUtils.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/util/SheetUtils.java @@ -20,8 +20,7 @@ public class SheetUtils { /** * Match the parameters to the actual sheet * - * @param readSheet - * actual sheet + * @param readSheet actual sheet * @param analysisContext * @return */ @@ -47,11 +46,13 @@ public class SheetUtils { if (!StringUtils.isEmpty(parameterSheetName)) { boolean autoTrim = (parameterReadSheet.getAutoTrim() != null && parameterReadSheet.getAutoTrim()) || (parameterReadSheet.getAutoTrim() == null - && analysisContext.readWorkbookHolder().getGlobalConfiguration().getAutoTrim()); + && analysisContext.readWorkbookHolder().getGlobalConfiguration().getAutoTrim()); + String sheetName = readSheet.getSheetName(); if (autoTrim) { parameterSheetName = parameterSheetName.trim(); + sheetName = sheetName.trim(); } - match = parameterSheetName.equals(readSheet.getSheetName()); + match = parameterSheetName.equals(sheetName); } } if (match) { diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/simple/SimpleDataTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/simple/SimpleDataTest.java index 80277545..fcc2ba21 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/simple/SimpleDataTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/simple/SimpleDataTest.java @@ -5,11 +5,16 @@ import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.ArrayList; import java.util.List; +import java.util.Map; +import com.alibaba.easyexcel.test.demo.read.DemoData; import com.alibaba.easyexcel.test.util.TestFileUtil; import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.read.listener.PageReadListener; import com.alibaba.excel.support.ExcelTypeEnum; +import com.alibaba.fastjson.JSON; +import lombok.extern.slf4j.Slf4j; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.FixMethodOrder; @@ -20,6 +25,7 @@ import org.junit.runners.MethodSorters; * @author Jiaju Zhuang */ @FixMethodOrder(MethodSorters.NAME_ASCENDING) +@Slf4j public class SimpleDataTest { private static File file07; @@ -90,8 +96,20 @@ public class SimpleDataTest { @Test public void t21SheetNameRead07() { - EasyExcel.read(TestFileUtil.readFile("simple" + File.separator + "simple07.xlsx"), SimpleData.class, - new SimpleDataSheetNameListener()).sheet("simple").doRead(); + List> list = EasyExcel.read( + TestFileUtil.readFile("simple" + File.separator + "simple07.xlsx")) + .sheet("simple") + .doReadSync(); + Assert.assertEquals(1, list.size()); + } + + @Test + public void t22PageReadListener07() { + EasyExcel.read(file07, SimpleData.class, + new PageReadListener(dataList -> { + Assert.assertEquals(5, dataList.size()); + }, 5)) + .sheet().doRead(); } private void synchronousRead(File file) { diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java index 542fe463..ad72da05 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java @@ -47,12 +47,13 @@ public class ReadTest { // since: 3.0.0-beta1 String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx"; // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭 - // 这里每次会读取100条数据 然后返回过来 直接调用使用数据就行 + // 这里默认每次会读取100条数据 然后返回过来 直接调用使用数据就行 + // 具体需要返回多少行可以在`PageReadListener`的构造函数设置 EasyExcel.read(fileName, DemoData.class, new PageReadListener(dataList -> { for (DemoData demoData : dataList) { log.info("读取到一条数据{}", JSON.toJSONString(demoData)); } - },3)).sheet().doRead(); + })).sheet().doRead(); // 写法2: // 匿名内部类 不用额外写一个DemoDataListener diff --git a/update.md b/update.md index f118eeec..f315c5b3 100644 --- a/update.md +++ b/update.md @@ -3,6 +3,7 @@ * 兼容`LocalDate` [Issue #2908](https://github.com/alibaba/easyexcel/issues/2908) * 优化大文件内存存储,减少内存占用 [Issue #2657](https://github.com/alibaba/easyexcel/issues/2657) * 在临时文件被删除的情况下能正常的读取 [Issue #2693](https://github.com/alibaba/easyexcel/issues/2693) +* 分页读取监听器支持自定义分页条数 [Issue #2383](https://github.com/alibaba/easyexcel/issues/2383) # 3.2.0 From 4514b55bc02204e5a630b2ff16100205f26ca74d Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Fri, 10 Feb 2023 19:08:41 +0800 Subject: [PATCH 25/25] =?UTF-8?q?=E5=8D=87=E7=BA=A7fastjson?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../easyexcel/test/core/compatibility/CompatibilityTest.java | 2 +- .../com/alibaba/easyexcel/test/core/extra/ExtraDataTest.java | 2 +- .../com/alibaba/easyexcel/test/core/simple/SimpleDataTest.java | 1 - pom.xml | 2 +- 4 files changed, 3 insertions(+), 4 deletions(-) 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 368f91b8..df5a2dbb 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 @@ -15,7 +15,7 @@ import com.alibaba.excel.cache.Ehcache; import com.alibaba.excel.constant.EasyExcelConstants; import com.alibaba.excel.enums.ReadDefaultReturnEnum; import com.alibaba.excel.util.FileUtils; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; import lombok.extern.slf4j.Slf4j; import org.apache.poi.util.TempFile; diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/extra/ExtraDataTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/extra/ExtraDataTest.java index 4475d83c..92f35574 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/extra/ExtraDataTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/extra/ExtraDataTest.java @@ -14,7 +14,7 @@ import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.enums.CellExtraTypeEnum; import com.alibaba.excel.metadata.CellExtra; import com.alibaba.excel.read.listener.ReadListener; -import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSON; /** * @author Jiaju Zhuang diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/simple/SimpleDataTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/simple/SimpleDataTest.java index fcc2ba21..236f0571 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/simple/SimpleDataTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/simple/SimpleDataTest.java @@ -12,7 +12,6 @@ import com.alibaba.easyexcel.test.util.TestFileUtil; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.read.listener.PageReadListener; import com.alibaba.excel.support.ExcelTypeEnum; -import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; import org.junit.Assert; diff --git a/pom.xml b/pom.xml index b87e0887..cceb0f94 100644 --- a/pom.xml +++ b/pom.xml @@ -145,7 +145,7 @@ com.alibaba.fastjson2 fastjson2 - 2.0.3 + 2.0.23 org.springframework.boot