From 9be5755b89cfbc664d3de6bb2430a4357c074f55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=AF=E4=BB=AA?= Date: Wed, 6 Dec 2023 14:06:34 +0800 Subject: [PATCH 01/13] =?UTF-8?q?*=20=E5=85=BC=E5=AE=B9=E6=9F=90=E4=BA=9B?= =?UTF-8?q?=E7=89=B9=E6=AE=8A=E7=9A=84xls:=20=E7=BC=BA=E5=B0=91=E6=AF=8F?= =?UTF-8?q?=E4=B8=AAsheet=E7=9A=84=E7=BB=88=E6=AD=A2=E7=AC=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../excel/analysis/v03/XlsSaxAnalyser.java | 4 +++ .../read/metadata/holder/ReadSheetHolder.java | 5 +++ .../holder/xls/XlsReadSheetHolder.java | 34 +++++-------------- .../DefaultAnalysisEventProcessor.java | 11 ++++-- 4 files changed, 26 insertions(+), 28 deletions(-) diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java index e1a303b1..f18fab05 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java @@ -11,6 +11,7 @@ import org.apache.poi.hssf.eventusermodel.HSSFEventFactory; import org.apache.poi.hssf.eventusermodel.HSSFListener; import org.apache.poi.hssf.eventusermodel.HSSFRequest; import org.apache.poi.hssf.eventusermodel.MissingRecordAwareHSSFListener; +import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingRowDummyRecord; import org.apache.poi.hssf.record.BOFRecord; import org.apache.poi.hssf.record.BlankRecord; import org.apache.poi.hssf.record.BoolErrRecord; @@ -137,6 +138,9 @@ public class XlsSaxAnalyser implements HSSFListener, ExcelReadExecutor { } catch (IOException e) { throw new ExcelAnalysisException(e); } + + // There are some special xls that do not have the terminator "[EOF]", so an additional + xlsReadContext.analysisEventProcessor().endSheet(xlsReadContext); } @Override diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/ReadSheetHolder.java b/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/ReadSheetHolder.java index 47957044..db5c4f73 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/ReadSheetHolder.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/ReadSheetHolder.java @@ -67,6 +67,11 @@ public class ReadSheetHolder extends AbstractReadHolder { */ private Integer maxNotEmptyDataHeadSize; + /** + * Reading this sheet has ended. + */ + private Boolean ended; + public ReadSheetHolder(ReadSheet readSheet, ReadWorkbookHolder readWorkbookHolder) { super(readSheet, readWorkbookHolder); this.readSheet = readSheet; diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/xls/XlsReadSheetHolder.java b/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/xls/XlsReadSheetHolder.java index 1d12ab6c..40b1d2d1 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/xls/XlsReadSheetHolder.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/xls/XlsReadSheetHolder.java @@ -8,11 +8,20 @@ import com.alibaba.excel.read.metadata.ReadSheet; import com.alibaba.excel.read.metadata.holder.ReadSheetHolder; import com.alibaba.excel.read.metadata.holder.ReadWorkbookHolder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + /** * sheet holder * * @author Jiaju Zhuang */ +@Getter +@Setter +@EqualsAndHashCode +@NoArgsConstructor public class XlsReadSheetHolder extends ReadSheetHolder { /** * Row type.Temporary storage, last set in ReadRowHolder. @@ -32,29 +41,4 @@ public class XlsReadSheetHolder extends ReadSheetHolder { tempRowType = RowTypeEnum.EMPTY; objectCacheMap = new HashMap(16); } - - public RowTypeEnum getTempRowType() { - return tempRowType; - } - - public void setTempRowType(RowTypeEnum tempRowType) { - this.tempRowType = tempRowType; - } - - - public Integer getTempObjectIndex() { - return tempObjectIndex; - } - - public void setTempObjectIndex(Integer tempObjectIndex) { - this.tempObjectIndex = tempObjectIndex; - } - - public Map getObjectCacheMap() { - return objectCacheMap; - } - - public void setObjectCacheMap(Map objectCacheMap) { - this.objectCacheMap = objectCacheMap; - } } diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/read/processor/DefaultAnalysisEventProcessor.java b/easyexcel-core/src/main/java/com/alibaba/excel/read/processor/DefaultAnalysisEventProcessor.java index 642e71fb..0d783a7b 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/read/processor/DefaultAnalysisEventProcessor.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/read/processor/DefaultAnalysisEventProcessor.java @@ -3,8 +3,6 @@ package com.alibaba.excel.read.processor; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Map.Entry; -import java.util.stream.Collectors; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.enums.CellDataTypeEnum; @@ -16,11 +14,12 @@ import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.data.ReadCellData; import com.alibaba.excel.read.listener.ReadListener; import com.alibaba.excel.read.metadata.holder.ReadRowHolder; +import com.alibaba.excel.read.metadata.holder.ReadSheetHolder; import com.alibaba.excel.read.metadata.property.ExcelReadHeadProperty; +import com.alibaba.excel.util.BooleanUtils; import com.alibaba.excel.util.ConverterUtils; import com.alibaba.excel.util.StringUtils; -import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.MapUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -53,6 +52,12 @@ public class DefaultAnalysisEventProcessor implements AnalysisEventProcessor { @Override public void endSheet(AnalysisContext analysisContext) { + ReadSheetHolder readSheetHolder = analysisContext.readSheetHolder(); + if (BooleanUtils.isTrue(readSheetHolder.getEnded())) { + return; + } + readSheetHolder.setEnded(Boolean.TRUE); + for (ReadListener readListener : analysisContext.currentReadHolder().readListenerList()) { readListener.doAfterAllAnalysed(analysisContext); } From f83683aa739120c0d99afa51b920eee5010f31e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=AF=E4=BB=AA?= Date: Wed, 6 Dec 2023 14:06:46 +0800 Subject: [PATCH 02/13] =?UTF-8?q?*=20=E5=85=BC=E5=AE=B9=E6=9F=90=E4=BA=9B?= =?UTF-8?q?=E7=89=B9=E6=AE=8A=E7=9A=84xls:=20=E7=BC=BA=E5=B0=91=E6=AF=8F?= =?UTF-8?q?=E4=B8=AAsheet=E7=9A=84=E7=BB=88=E6=AD=A2=E7=AC=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9ed5cafb..1cece2ae 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ - 3.3.2 + 3.3.3 UTF-8 1.8 true From 3777654d17e29b77b7d1eda1aa8af432c8e5042f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=AF=E4=BB=AA?= Date: Wed, 6 Dec 2023 14:07:51 +0800 Subject: [PATCH 03/13] =?UTF-8?q?*=20=E5=85=BC=E5=AE=B9=E6=9F=90=E4=BA=9B?= =?UTF-8?q?=E7=89=B9=E6=AE=8A=E7=9A=84xls:=20=E7=BC=BA=E5=B0=91=E6=AF=8F?= =?UTF-8?q?=E4=B8=AAsheet=E7=9A=84=E7=BB=88=E6=AD=A2=E7=AC=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fe7d634a..73195f57 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ easyexcel重写了poi对07版Excel的解析,一个3M的excel用POI sax解析 com.alibaba easyexcel - 3.3.2 + 3.3.3 ``` From a16984862b5ac4447460b2810246f4401464abc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=AF=E4=BB=AA?= Date: Wed, 6 Dec 2023 14:14:00 +0800 Subject: [PATCH 04/13] =?UTF-8?q?*=20=E5=85=BC=E5=AE=B9=E6=9F=90=E4=BA=9B?= =?UTF-8?q?=E7=89=B9=E6=AE=8A=E7=9A=84xls:=20=E7=BC=BA=E5=B0=91=E6=AF=8F?= =?UTF-8?q?=E4=B8=AAsheet=E7=9A=84=E7=BB=88=E6=AD=A2=E7=AC=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- update.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/update.md b/update.md index c448d238..402f69dd 100644 --- a/update.md +++ b/update.md @@ -1,3 +1,7 @@ +# 3.3.3 + +* 兼容某些特殊的xls: 缺少每个sheet的终止符 + # 3.3.2 * 修复`includeColumnIndexes`和`includeColumnFieldNames`在sheet后面失效的问题 From 1ab44ce453564102ff7b41f7b98732a14b962d73 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Thu, 18 Jan 2024 17:30:24 +0800 Subject: [PATCH 05/13] Update README.md remove --- README.md | 8 -------- 1 file changed, 8 deletions(-) diff --git a/README.md b/README.md index 73195f57..421ffb28 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,3 @@ -# 🔥作者最新开源项目[Chat2DB](https://github.com/chat2db/Chat2DB) - -- GitHub地址 [https://github.com/chat2db/Chat2DB](https://github.com/chat2db/Chat2DB) -- 官 网 地 址 [https://chat2db.ai](https://chat2db.ai) - -crete datasource - - EasyExcel ====================== [![Build Status](https://github.com/alibaba/easyexcel/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/alibaba/easyexcel/actions/workflows/ci.yml?query=branch%3Amaster) From 4cd56ad278c7a1142308a37397ff74a775d99396 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=AF=E4=BB=AA?= Date: Mon, 11 Mar 2024 20:25:27 +0800 Subject: [PATCH 06/13] =?UTF-8?q?*=20=E6=94=AF=E6=8C=81=E5=81=9C=E6=AD=A2?= =?UTF-8?q?=E5=8D=95=E4=B8=AA`sheet`=E4=BB=A5=E5=90=8E=E7=BB=A7=E7=BB=AD?= =?UTF-8?q?=E8=AF=BB=E5=8F=96=E5=85=B6=E4=BB=96`sheet`,=E4=BD=BF=E7=94=A8`?= =?UTF-8?q?ExcelAnalysisStopSheetException`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- .../excel/analysis/v03/XlsSaxAnalyser.java | 17 +++++- .../v03/handlers/EofRecordHandler.java | 6 +- .../excel/analysis/v07/XlsxSaxAnalyser.java | 16 +++-- .../exception/ExcelAnalysisStopException.java | 3 + .../ExcelAnalysisStopSheetException.java | 30 ++++++++++ ...nalysisStopSheetExceptionDataListener.java | 52 ++++++++++++++++ .../core/exception/ExceptionDataTest.java | 60 ++++++++++++++++++- pom.xml | 2 +- update.md | 4 ++ 10 files changed, 181 insertions(+), 11 deletions(-) create mode 100644 easyexcel-core/src/main/java/com/alibaba/excel/exception/ExcelAnalysisStopSheetException.java create mode 100644 easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/exception/ExcelAnalysisStopSheetExceptionDataListener.java diff --git a/README.md b/README.md index 421ffb28..d860e19f 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ easyexcel重写了poi对07版Excel的解析,一个3M的excel用POI sax解析 com.alibaba easyexcel - 3.3.3 + 3.3.4 ``` diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java index f18fab05..5fdae31b 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java @@ -5,6 +5,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import lombok.extern.slf4j.Slf4j; import org.apache.poi.hssf.eventusermodel.EventWorkbookBuilder; import org.apache.poi.hssf.eventusermodel.FormatTrackingHSSFListener; import org.apache.poi.hssf.eventusermodel.HSSFEventFactory; @@ -57,6 +58,7 @@ import com.alibaba.excel.analysis.v03.handlers.TextObjectRecordHandler; import com.alibaba.excel.context.xls.XlsReadContext; import com.alibaba.excel.exception.ExcelAnalysisException; import com.alibaba.excel.exception.ExcelAnalysisStopException; +import com.alibaba.excel.exception.ExcelAnalysisStopSheetException; import com.alibaba.excel.read.metadata.ReadSheet; import com.alibaba.excel.read.metadata.holder.xls.XlsReadWorkbookHolder; @@ -70,10 +72,13 @@ import com.alibaba.excel.read.metadata.holder.xls.XlsReadWorkbookHolder; *

* * To turn an excel file into a CSV or similar, then see * the XLS2CSVmra example * *

- * * * @see XLS2CSVmra + * * * @see XLS2CSVmra * * @author jipengfei */ +@Slf4j public class XlsSaxAnalyser implements HSSFListener, ExcelReadExecutor { private static final Logger LOGGER = LoggerFactory.getLogger(XlsSaxAnalyser.class); @@ -158,7 +163,15 @@ public class XlsSaxAnalyser implements HSSFListener, ExcelReadExecutor { if (!handler.support(xlsReadContext, record)) { return; } - handler.processRecord(xlsReadContext, record); + + try { + handler.processRecord(xlsReadContext, record); + } catch (ExcelAnalysisStopSheetException e) { + if (log.isDebugEnabled()) { + log.debug("Custom stop!", e); + } + xlsReadContext.xlsReadWorkbookHolder().setIgnoreRecord(Boolean.TRUE); + } } } diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/handlers/EofRecordHandler.java b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/handlers/EofRecordHandler.java index 448dcb49..5593de12 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/handlers/EofRecordHandler.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/handlers/EofRecordHandler.java @@ -10,13 +10,14 @@ import com.alibaba.excel.enums.RowTypeEnum; import com.alibaba.excel.metadata.Cell; import com.alibaba.excel.read.metadata.holder.ReadRowHolder; import com.alibaba.excel.read.metadata.holder.xls.XlsReadSheetHolder; +import com.alibaba.excel.util.BooleanUtils; /** * Record handler * * @author Dan Zheng */ -public class EofRecordHandler extends AbstractXlsRecordHandler implements IgnorableXlsRecordHandler { +public class EofRecordHandler extends AbstractXlsRecordHandler { @Override public void processRecord(XlsReadContext xlsReadContext, Record record) { @@ -24,7 +25,8 @@ public class EofRecordHandler extends AbstractXlsRecordHandler implements Ignora return; } // Sometimes tables lack the end record of the last column - if (!xlsReadContext.xlsReadSheetHolder().getCellMap().isEmpty()) { + if (BooleanUtils.isNotTrue(xlsReadContext.xlsReadWorkbookHolder().getIgnoreRecord()) + && !xlsReadContext.xlsReadSheetHolder().getCellMap().isEmpty()) { XlsReadSheetHolder xlsReadSheetHolder = xlsReadContext.xlsReadSheetHolder(); // Forge a termination data xlsReadContext.readRowHolder(new ReadRowHolder(xlsReadContext.xlsReadSheetHolder().getRowIndex() + 1, diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java index 5104b1e3..a2bf163d 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java @@ -22,6 +22,8 @@ import com.alibaba.excel.cache.ReadCache; import com.alibaba.excel.context.xlsx.XlsxReadContext; import com.alibaba.excel.enums.CellExtraTypeEnum; import com.alibaba.excel.exception.ExcelAnalysisException; +import com.alibaba.excel.exception.ExcelAnalysisStopException; +import com.alibaba.excel.exception.ExcelAnalysisStopSheetException; import com.alibaba.excel.metadata.CellExtra; import com.alibaba.excel.read.metadata.ReadSheet; import com.alibaba.excel.read.metadata.holder.xlsx.XlsxReadWorkbookHolder; @@ -256,10 +258,16 @@ public class XlsxSaxAnalyser implements ExcelReadExecutor { for (ReadSheet readSheet : sheetList) { readSheet = SheetUtils.match(readSheet, xlsxReadContext); if (readSheet != null) { - xlsxReadContext.currentSheet(readSheet); - parseXmlSource(sheetMap.get(readSheet.getSheetNo()), new XlsxRowHandler(xlsxReadContext)); - // Read comments - readComments(readSheet); + try { + xlsxReadContext.currentSheet(readSheet); + parseXmlSource(sheetMap.get(readSheet.getSheetNo()), new XlsxRowHandler(xlsxReadContext)); + // Read comments + readComments(readSheet); + } catch (ExcelAnalysisStopSheetException e) { + if (log.isDebugEnabled()) { + log.debug("Custom stop!", e); + } + } // The last sheet is read xlsxReadContext.analysisEventProcessor().endSheet(xlsxReadContext); } diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/exception/ExcelAnalysisStopException.java b/easyexcel-core/src/main/java/com/alibaba/excel/exception/ExcelAnalysisStopException.java index fd66d5c1..fd05ff84 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/exception/ExcelAnalysisStopException.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/exception/ExcelAnalysisStopException.java @@ -2,8 +2,11 @@ package com.alibaba.excel.exception; /** * Throw the exception when you need to stop + * This exception will stop the entire excel parsing. If you only want to stop the parsing of a certain sheet, please + * use ExcelAnalysisStopSheetException. * * @author Jiaju Zhuang + * @see ExcelAnalysisStopException */ public class ExcelAnalysisStopException extends ExcelAnalysisException { diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/exception/ExcelAnalysisStopSheetException.java b/easyexcel-core/src/main/java/com/alibaba/excel/exception/ExcelAnalysisStopSheetException.java new file mode 100644 index 00000000..44ca9679 --- /dev/null +++ b/easyexcel-core/src/main/java/com/alibaba/excel/exception/ExcelAnalysisStopSheetException.java @@ -0,0 +1,30 @@ +package com.alibaba.excel.exception; + +/** + * Throw the exception when you need to stop + * This exception will only stop the parsing of the current sheet. If you want to stop the entire excel parsing, please + * use ExcelAnalysisStopException. + * + * The com.alibaba.excel.read.listener.ReadListener#doAfterAllAnalysed(com.alibaba.excel.context.AnalysisContext) method + * is called after the call is stopped. + * + * @author Jiaju Zhuang + * @see ExcelAnalysisStopException + * @since 3.3.4 + */ +public class ExcelAnalysisStopSheetException extends ExcelAnalysisException { + + public ExcelAnalysisStopSheetException() {} + + public ExcelAnalysisStopSheetException(String message) { + super(message); + } + + public ExcelAnalysisStopSheetException(String message, Throwable cause) { + super(message, cause); + } + + public ExcelAnalysisStopSheetException(Throwable cause) { + super(cause); + } +} diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/exception/ExcelAnalysisStopSheetExceptionDataListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/exception/ExcelAnalysisStopSheetExceptionDataListener.java new file mode 100644 index 00000000..8a216d56 --- /dev/null +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/exception/ExcelAnalysisStopSheetExceptionDataListener.java @@ -0,0 +1,52 @@ +package com.alibaba.easyexcel.test.core.exception; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.event.AnalysisEventListener; +import com.alibaba.excel.exception.ExcelAnalysisStopException; +import com.alibaba.excel.exception.ExcelAnalysisStopSheetException; +import com.alibaba.excel.util.ListUtils; +import com.alibaba.excel.util.MapUtils; +import com.alibaba.fastjson2.JSON; + +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.SetUtils; +import org.assertj.core.internal.Maps; +import org.junit.jupiter.api.Assertions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Jiaju Zhuang + */ +@Getter +@Slf4j +public class ExcelAnalysisStopSheetExceptionDataListener extends AnalysisEventListener { + + private Map> dataMap = MapUtils.newHashMap(); + + + @Override + public void invoke(ExceptionData data, AnalysisContext context) { + List sheetDataList = dataMap.computeIfAbsent(context.readSheetHolder().getSheetNo(), + key -> ListUtils.newArrayList()); + sheetDataList.add(data.getName()); + if (sheetDataList.size() >= 5) { + throw new ExcelAnalysisStopSheetException(); + } + } + + @Override + public void doAfterAllAnalysed(AnalysisContext context) { + List sheetDataList = dataMap.get(context.readSheetHolder().getSheetNo()); + Assertions.assertNotNull(sheetDataList); + Assertions.assertEquals(5, sheetDataList.size()); + } +} diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/exception/ExceptionDataTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/exception/ExceptionDataTest.java index b06a105e..0d3fe12e 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/exception/ExceptionDataTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/exception/ExceptionDataTest.java @@ -5,10 +5,15 @@ 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.write.DemoData; import com.alibaba.easyexcel.test.util.TestFileUtil; import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.ExcelWriter; +import com.alibaba.excel.write.metadata.WriteSheet; +import org.assertj.core.util.Lists; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.MethodOrderer; @@ -23,15 +28,20 @@ public class ExceptionDataTest { private static File file07; private static File file03; + private static File fileCsv; + private static File fileExcelAnalysisStopSheetException07; + private static File fileExcelAnalysisStopSheetException03; + private static File fileExcelAnalysisStopSheetExceptionCsv; private static File fileException07; private static File fileException03; - private static File fileCsv; @BeforeAll public static void init() { file07 = TestFileUtil.createNewFile("exception.xlsx"); file03 = TestFileUtil.createNewFile("exception.xls"); fileCsv = TestFileUtil.createNewFile("exception.csv"); + fileExcelAnalysisStopSheetException07 = TestFileUtil.createNewFile("excelAnalysisStopSheetException.xlsx"); + fileExcelAnalysisStopSheetException03 = TestFileUtil.createNewFile("excelAnalysisStopSheetException.xls"); fileException07 = TestFileUtil.createNewFile("exceptionThrow.xlsx"); fileException03 = TestFileUtil.createNewFile("exceptionThrow.xls"); } @@ -61,6 +71,44 @@ public class ExceptionDataTest { readAndWriteException(fileException03); } + @Test + public void t21ReadAndWrite07() throws Exception { + readAndWriteExcelAnalysisStopSheetException(fileExcelAnalysisStopSheetException07); + } + + @Test + public void t22ReadAndWrite03() throws Exception { + readAndWriteExcelAnalysisStopSheetException(fileExcelAnalysisStopSheetException03); + } + + + private void readAndWriteExcelAnalysisStopSheetException(File file) throws Exception { + try (ExcelWriter excelWriter = EasyExcel.write(file, ExceptionData.class).build()) { + for (int i = 0; i < 5; i++) { + String sheetName = "sheet" + i; + WriteSheet writeSheet = EasyExcel.writerSheet(i, sheetName).build(); + List data = data(sheetName); + excelWriter.write(data, writeSheet); + } + } + + ExcelAnalysisStopSheetExceptionDataListener excelAnalysisStopSheetExceptionDataListener + = new ExcelAnalysisStopSheetExceptionDataListener(); + EasyExcel.read(file, ExceptionData.class, excelAnalysisStopSheetExceptionDataListener).doReadAll(); + Map> dataMap = excelAnalysisStopSheetExceptionDataListener.getDataMap(); + Assertions.assertEquals(5, dataMap.size()); + for (int i = 0; i < 5; i++) { + List sheetDataList = dataMap.get(i); + Assertions.assertNotNull(sheetDataList); + Assertions.assertEquals(5, sheetDataList.size()); + String sheetName = "sheet" + i; + + for (String sheetData : sheetDataList) { + Assertions.assertTrue(sheetData.startsWith(sheetName)); + } + } + } + private void readAndWriteException(File file) throws Exception { EasyExcel.write(new FileOutputStream(file), ExceptionData.class).sheet().doWrite(data()); ArithmeticException exception = Assertions.assertThrows(ArithmeticException.class, () -> EasyExcel.read( @@ -83,4 +131,14 @@ public class ExceptionDataTest { } return list; } + + private List data(String prefix) { + List list = Lists.newArrayList(); + for (int i = 0; i < 10; i++) { + ExceptionData simpleData = new ExceptionData(); + simpleData.setName(prefix + "-姓名" + i); + list.add(simpleData); + } + return list; + } } diff --git a/pom.xml b/pom.xml index 1cece2ae..358a2846 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ - 3.3.3 + 3.3.4 UTF-8 1.8 true diff --git a/update.md b/update.md index 402f69dd..a8f95564 100644 --- a/update.md +++ b/update.md @@ -1,3 +1,7 @@ +# 3.3.4 + +* 支持停止单个`sheet`以后继续读取其他`sheet`,使用`ExcelAnalysisStopSheetException` + # 3.3.3 * 兼容某些特殊的xls: 缺少每个sheet的终止符 From abcd4f77f24d99ead266849cb4b36c8e43f015d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=AF=E4=BB=AA?= Date: Mon, 11 Mar 2024 20:26:26 +0800 Subject: [PATCH 07/13] =?UTF-8?q?*=20=E6=94=AF=E6=8C=81=E5=81=9C=E6=AD=A2?= =?UTF-8?q?=E5=8D=95=E4=B8=AA`sheet`=E4=BB=A5=E5=90=8E=E7=BB=A7=E7=BB=AD?= =?UTF-8?q?=E8=AF=BB=E5=8F=96=E5=85=B6=E4=BB=96`sheet`,=E4=BD=BF=E7=94=A8`?= =?UTF-8?q?ExcelAnalysisStopSheetException`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../analysis/csv/CsvExcelReadExecutor.java | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/csv/CsvExcelReadExecutor.java b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/csv/CsvExcelReadExecutor.java index 6afabe34..5a901b5b 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/csv/CsvExcelReadExecutor.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/csv/CsvExcelReadExecutor.java @@ -16,6 +16,8 @@ import com.alibaba.excel.enums.ByteOrderMarkEnum; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.RowTypeEnum; import com.alibaba.excel.exception.ExcelAnalysisException; +import com.alibaba.excel.exception.ExcelAnalysisStopException; +import com.alibaba.excel.exception.ExcelAnalysisStopSheetException; import com.alibaba.excel.metadata.Cell; import com.alibaba.excel.metadata.data.ReadCellData; import com.alibaba.excel.read.metadata.ReadSheet; @@ -69,12 +71,18 @@ public class CsvExcelReadExecutor implements ExcelReadExecutor { if (readSheet == null) { continue; } - csvReadContext.currentSheet(readSheet); - - int rowIndex = 0; - - for (CSVRecord record : csvParser) { - dealRecord(record, rowIndex++); + try { + csvReadContext.currentSheet(readSheet); + + int rowIndex = 0; + + for (CSVRecord record : csvParser) { + dealRecord(record, rowIndex++); + } + } catch (ExcelAnalysisStopSheetException e) { + if (log.isDebugEnabled()) { + log.debug("Custom stop!", e); + } } // The last sheet is read From 5d02c43f82002e55ed9dc0aac5b03ca58ac2a7f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=AF=E4=BB=AA?= Date: Mon, 11 Mar 2024 20:45:50 +0800 Subject: [PATCH 08/13] =?UTF-8?q?*=20=E6=94=AF=E6=8C=81=E5=81=9C=E6=AD=A2?= =?UTF-8?q?=E5=8D=95=E4=B8=AA`sheet`=E4=BB=A5=E5=90=8E=E7=BB=A7=E7=BB=AD?= =?UTF-8?q?=E8=AF=BB=E5=8F=96=E5=85=B6=E4=BB=96`sheet`,=E4=BD=BF=E7=94=A8`?= =?UTF-8?q?ExcelAnalysisStopSheetException`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../excel/analysis/v03/XlsSaxAnalyser.java | 1 + .../v03/handlers/BofRecordHandler.java | 1 + .../v03/handlers/EofRecordHandler.java | 13 +++- .../holder/xls/XlsReadWorkbookHolder.java | 70 ++++--------------- 4 files changed, 27 insertions(+), 58 deletions(-) diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java index 5fdae31b..2866a7de 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java @@ -171,6 +171,7 @@ public class XlsSaxAnalyser implements HSSFListener, ExcelReadExecutor { log.debug("Custom stop!", e); } xlsReadContext.xlsReadWorkbookHolder().setIgnoreRecord(Boolean.TRUE); + xlsReadContext.xlsReadWorkbookHolder().setCurrentSheetStopped(Boolean.TRUE); } } diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/handlers/BofRecordHandler.java b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/handlers/BofRecordHandler.java index 3e6713c4..a05568ee 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/handlers/BofRecordHandler.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/handlers/BofRecordHandler.java @@ -49,6 +49,7 @@ public class BofRecordHandler extends AbstractXlsRecordHandler { } else { xlsReadContext.xlsReadWorkbookHolder().setIgnoreRecord(Boolean.TRUE); } + xlsReadContext.xlsReadWorkbookHolder().setCurrentSheetStopped(Boolean.FALSE); // Go read the next one xlsReadWorkbookHolder.setReadSheetIndex(xlsReadWorkbookHolder.getReadSheetIndex() + 1); } diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/handlers/EofRecordHandler.java b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/handlers/EofRecordHandler.java index 5593de12..6e162028 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/handlers/EofRecordHandler.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/handlers/EofRecordHandler.java @@ -24,9 +24,18 @@ public class EofRecordHandler extends AbstractXlsRecordHandler { if (xlsReadContext.readSheetHolder() == null) { return; } + + //Represents the current sheet does not need to be read or the user manually stopped reading the sheet. + if (BooleanUtils.isTrue(xlsReadContext.xlsReadWorkbookHolder().getIgnoreRecord())) { + // When the user manually stops reading the sheet, the method to end the sheet needs to be called. + if (BooleanUtils.isTrue(xlsReadContext.xlsReadWorkbookHolder().getCurrentSheetStopped())) { + xlsReadContext.analysisEventProcessor().endSheet(xlsReadContext); + } + return; + } + // Sometimes tables lack the end record of the last column - if (BooleanUtils.isNotTrue(xlsReadContext.xlsReadWorkbookHolder().getIgnoreRecord()) - && !xlsReadContext.xlsReadSheetHolder().getCellMap().isEmpty()) { + if (!xlsReadContext.xlsReadSheetHolder().getCellMap().isEmpty()) { XlsReadSheetHolder xlsReadSheetHolder = xlsReadContext.xlsReadSheetHolder(); // Forge a termination data xlsReadContext.readRowHolder(new ReadRowHolder(xlsReadContext.xlsReadSheetHolder().getRowIndex() + 1, diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/xls/XlsReadWorkbookHolder.java b/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/xls/XlsReadWorkbookHolder.java index a8c86a75..da7d87e0 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/xls/XlsReadWorkbookHolder.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/read/metadata/holder/xls/XlsReadWorkbookHolder.java @@ -3,6 +3,10 @@ package com.alibaba.excel.read.metadata.holder.xls; import java.util.ArrayList; import java.util.List; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; import org.apache.poi.hssf.eventusermodel.FormatTrackingHSSFListener; import org.apache.poi.hssf.record.BoundSheetRecord; import org.apache.poi.hssf.usermodel.HSSFWorkbook; @@ -17,6 +21,10 @@ import com.alibaba.excel.support.ExcelTypeEnum; * * @author Jiaju Zhuang */ +@Getter +@Setter +@EqualsAndHashCode +@NoArgsConstructor public class XlsReadWorkbookHolder extends ReadWorkbookHolder { /** * File System @@ -47,6 +55,11 @@ public class XlsReadWorkbookHolder extends ReadWorkbookHolder { */ private Boolean ignoreRecord; + /** + * Has the current sheet already stopped + */ + private Boolean currentSheetStopped; + public XlsReadWorkbookHolder(ReadWorkbook readWorkbook) { super(readWorkbook); this.boundSheetRecordList = new ArrayList(); @@ -56,61 +69,6 @@ public class XlsReadWorkbookHolder extends ReadWorkbookHolder { getGlobalConfiguration().setUse1904windowing(Boolean.FALSE); } ignoreRecord = Boolean.FALSE; - } - - public POIFSFileSystem getPoifsFileSystem() { - return poifsFileSystem; - } - - public void setPoifsFileSystem(POIFSFileSystem poifsFileSystem) { - this.poifsFileSystem = poifsFileSystem; - } - - public FormatTrackingHSSFListener getFormatTrackingHSSFListener() { - return formatTrackingHSSFListener; - } - - public void setFormatTrackingHSSFListener(FormatTrackingHSSFListener formatTrackingHSSFListener) { - this.formatTrackingHSSFListener = formatTrackingHSSFListener; - } - - public HSSFWorkbook getHssfWorkbook() { - return hssfWorkbook; - } - - public void setHssfWorkbook(HSSFWorkbook hssfWorkbook) { - this.hssfWorkbook = hssfWorkbook; - } - - public List getBoundSheetRecordList() { - return boundSheetRecordList; - } - - public void setBoundSheetRecordList(List boundSheetRecordList) { - this.boundSheetRecordList = boundSheetRecordList; - } - - public Boolean getNeedReadSheet() { - return needReadSheet; - } - - public void setNeedReadSheet(Boolean needReadSheet) { - this.needReadSheet = needReadSheet; - } - - public Integer getReadSheetIndex() { - return readSheetIndex; - } - - public void setReadSheetIndex(Integer readSheetIndex) { - this.readSheetIndex = readSheetIndex; - } - - public Boolean getIgnoreRecord() { - return ignoreRecord; - } - - public void setIgnoreRecord(Boolean ignoreRecord) { - this.ignoreRecord = ignoreRecord; + currentSheetStopped = Boolean.TRUE; } } From bd4252f045902e87a816c23d07f5c2e720eed07c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=AF=E4=BB=AA?= Date: Mon, 11 Mar 2024 20:59:17 +0800 Subject: [PATCH 09/13] =?UTF-8?q?*=20=E6=94=AF=E6=8C=81=E5=81=9C=E6=AD=A2?= =?UTF-8?q?=E5=8D=95=E4=B8=AA`sheet`=E4=BB=A5=E5=90=8E=E7=BB=A7=E7=BB=AD?= =?UTF-8?q?=E8=AF=BB=E5=8F=96=E5=85=B6=E4=BB=96`sheet`,=E4=BD=BF=E7=94=A8`?= =?UTF-8?q?ExcelAnalysisStopSheetException`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../excel/analysis/v03/XlsSaxAnalyser.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java index 2866a7de..27e6f010 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java @@ -63,20 +63,19 @@ import com.alibaba.excel.read.metadata.ReadSheet; import com.alibaba.excel.read.metadata.holder.xls.XlsReadWorkbookHolder; /** - * /** * A text extractor for Excel files. * + * A text extractor for Excel files. *

- * * Returns the textual content of the file, suitable for * indexing by something like Lucene, but not really * - * intended for display to the user. * + * Returns the textual content of the file, suitable for indexing by something like Lucene, but not really intended for + * display to the user. *

- * * + * *

- * * To turn an excel file into a CSV or similar, then see * the XLS2CSVmra example * + * To turn an excel file into a CSV or similar, then see the XLS2CSVmra example *

- * * * @see XLS2CSVmra + * * * @author jipengfei + * @see XLS2CSVmra */ @Slf4j public class XlsSaxAnalyser implements HSSFListener, ExcelReadExecutor { From cc24dd2ac5e77f2278937be0ee037eb7a074768f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=AF=E4=BB=AA?= Date: Mon, 18 Mar 2024 20:59:22 +0800 Subject: [PATCH 10/13] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=8B=9B=E8=81=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index d860e19f..d7755b1b 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,17 @@ EasyExcel Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。 easyexcel重写了poi对07版Excel的解析,一个3M的excel用POI sax解析依然需要100M左右内存,改用easyexcel可以降低到几M,并且再大的excel也不会出现内存溢出;03版依赖POI的sax模式,在上层做了模型转换的封装,让使用者更加简单方便 +# 🔥阿里巴巴(淘天集团)岗位内推 +* 内推优势 + * EasyExcel作者协助简历优化 + * 更多岗位前置知识 +* 内推岗位 + * 🔥可在 [淘猫集团岗位搜索](https://talent.taotian.com/off-campus/position-list?lang=zh&search=) 搜索岗位 + * [非淘天集团岗位搜索](https://talent.alibaba.com/) 首页往下拉可以看到各个集团 +* 内推 + * 发送简历到 zhuangjiaju.zjj@taobao.com + * 或者 [联系我们](https://easyexcel.opensource.alibaba.com/community/support) 加入钉钉群联系群主 + # 网站 * 官方网站:[https://easyexcel.opensource.alibaba.com/](https://easyexcel.opensource.alibaba.com/) * github地址:[https://github.com/alibaba/easyexcel](https://github.com/alibaba/easyexcel) From 0789e940c1f84570ff8b4fcda6910bc8a5671ba5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=AF=E4=BB=AA?= Date: Mon, 18 Mar 2024 21:01:03 +0800 Subject: [PATCH 11/13] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=8B=9B=E8=81=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d7755b1b..83793976 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,9 @@ easyexcel重写了poi对07版Excel的解析,一个3M的excel用POI sax解析 # 🔥阿里巴巴(淘天集团)岗位内推 * 内推优势 - * EasyExcel作者协助简历优化 + * 更专业的简历指导 * 更多岗位前置知识 + * 更快的面试进度以及进度查询 * 内推岗位 * 🔥可在 [淘猫集团岗位搜索](https://talent.taotian.com/off-campus/position-list?lang=zh&search=) 搜索岗位 * [非淘天集团岗位搜索](https://talent.alibaba.com/) 首页往下拉可以看到各个集团 From 93e2d0fc6e0d258f991b9cb7b58bb07a0a03a57b Mon Sep 17 00:00:00 2001 From: Chat2DB <1558143046@qq.com> Date: Tue, 9 Apr 2024 23:34:24 +0800 Subject: [PATCH 12/13] Update README.md --- README.md | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 83793976..e9780bff 100644 --- a/README.md +++ b/README.md @@ -10,17 +10,16 @@ EasyExcel Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。 easyexcel重写了poi对07版Excel的解析,一个3M的excel用POI sax解析依然需要100M左右内存,改用easyexcel可以降低到几M,并且再大的excel也不会出现内存溢出;03版依赖POI的sax模式,在上层做了模型转换的封装,让使用者更加简单方便 -# 🔥阿里巴巴(淘天集团)岗位内推 -* 内推优势 - * 更专业的简历指导 - * 更多岗位前置知识 - * 更快的面试进度以及进度查询 -* 内推岗位 - * 🔥可在 [淘猫集团岗位搜索](https://talent.taotian.com/off-campus/position-list?lang=zh&search=) 搜索岗位 - * [非淘天集团岗位搜索](https://talent.alibaba.com/) 首页往下拉可以看到各个集团 -* 内推 - * 发送简历到 zhuangjiaju.zjj@taobao.com - * 或者 [联系我们](https://easyexcel.opensource.alibaba.com/community/support) 加入钉钉群联系群主 +# 推荐 Easyexcel 作者新开源作品 Chat2DB + +Github 地址: [https://github.com/chat2db/Chat2DB](https://github.com/chat2db/Chat2DB) +官网:[https://chat2db-ai.com](https://chat2db-ai.com) +

+ + Chat2DB + +

+ # 网站 * 官方网站:[https://easyexcel.opensource.alibaba.com/](https://easyexcel.opensource.alibaba.com/) From 69baba0786570965b6609782298f684a47645181 Mon Sep 17 00:00:00 2001 From: Chat2DB <1558143046@qq.com> Date: Tue, 9 Apr 2024 23:41:04 +0800 Subject: [PATCH 13/13] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e9780bff..db672ae5 100644 --- a/README.md +++ b/README.md @@ -10,10 +10,10 @@ EasyExcel Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。 easyexcel重写了poi对07版Excel的解析,一个3M的excel用POI sax解析依然需要100M左右内存,改用easyexcel可以降低到几M,并且再大的excel也不会出现内存溢出;03版依赖POI的sax模式,在上层做了模型转换的封装,让使用者更加简单方便 -# 推荐 Easyexcel 作者新开源作品 Chat2DB - -Github 地址: [https://github.com/chat2db/Chat2DB](https://github.com/chat2db/Chat2DB) -官网:[https://chat2db-ai.com](https://chat2db-ai.com) +# 推荐 Chat2DB +AI 驱动的数据库管理、数据分析工具,支持Mysql、pg、oracle、sqlserver、redis等10多种数据库 +* Github 地址: [https://github.com/chat2db/Chat2DB](https://github.com/chat2db/Chat2DB) +* 官网:[https://chat2db-ai.com](https://chat2db-ai.com)

Chat2DB