From 3a2bf2b43fc4514d5a34547caa59c4ce73ac8a75 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Sun, 29 Sep 2019 19:59:15 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=9607=E7=89=88=E8=B6=85=E5=A4=A7?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E8=AF=BB=E5=8F=96=E6=96=B9=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 +++ img/readme/large.png | Bin 0 -> 5424 bytes .../excel/context/WriteContextImpl.java | 31 ++++++++++++------ .../alibaba/excel/write/ExcelBuilderImpl.java | 7 ++-- .../metadata/holder/WriteSheetHolder.java | 1 - update.md | 1 - 6 files changed, 30 insertions(+), 15 deletions(-) create mode 100644 img/readme/large.png diff --git a/README.md b/README.md index 93ee305..583cc4b 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,11 @@ easyexcel # JAVA解析Excel工具easyexcel Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。easyexcel重写了poi对07版Excel的解析,能够原本一个3M的excel用POI sax依然需要100M左右内存降低到几M,并且再大的excel不会出现内存溢出,03版依赖POI的sax模式。在上层做了模型转换的封装,让使用者更加简单方便 + +## 64M内存1分钟内读取75M(46W行25列)的Excel +当然还有急速模式能更快,但是内存占用会在100M多一点 +![img](img/readme/large.png) + ## 相关文档 * [快速使用](/quickstart.md) * [关于软件](/abouteasyexcel.md) diff --git a/img/readme/large.png b/img/readme/large.png new file mode 100644 index 0000000000000000000000000000000000000000..04195a10bfef90fc51c71d2bcb55cd654710461e GIT binary patch literal 5424 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 literal 0 HcmV?d00001 diff --git a/src/main/java/com/alibaba/excel/context/WriteContextImpl.java b/src/main/java/com/alibaba/excel/context/WriteContextImpl.java index 0060211..34b90ba 100644 --- a/src/main/java/com/alibaba/excel/context/WriteContextImpl.java +++ b/src/main/java/com/alibaba/excel/context/WriteContextImpl.java @@ -10,6 +10,7 @@ import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.xssf.streaming.SXSSFWorkbook; +import org.apache.poi.xssf.usermodel.XSSFSheet; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -83,7 +84,7 @@ public class WriteContextImpl implements WriteContext { } for (WriteHandler writeHandler : handlerList) { if (writeHandler instanceof WorkbookWriteHandler) { - ((WorkbookWriteHandler) writeHandler).beforeWorkbookCreate(); + ((WorkbookWriteHandler)writeHandler).beforeWorkbookCreate(); } } } @@ -95,7 +96,7 @@ public class WriteContextImpl implements WriteContext { } for (WriteHandler writeHandler : handlerList) { if (writeHandler instanceof WorkbookWriteHandler) { - ((WorkbookWriteHandler) writeHandler).afterWorkbookCreate(writeWorkbookHolder); + ((WorkbookWriteHandler)writeHandler).afterWorkbookCreate(writeWorkbookHolder); } } } @@ -149,7 +150,7 @@ public class WriteContextImpl implements WriteContext { } for (WriteHandler writeHandler : handlerList) { if (writeHandler instanceof SheetWriteHandler) { - ((SheetWriteHandler) writeHandler).beforeSheetCreate(writeWorkbookHolder, writeSheetHolder); + ((SheetWriteHandler)writeHandler).beforeSheetCreate(writeWorkbookHolder, writeSheetHolder); } } } @@ -161,7 +162,7 @@ public class WriteContextImpl implements WriteContext { } for (WriteHandler writeHandler : handlerList) { if (writeHandler instanceof SheetWriteHandler) { - ((SheetWriteHandler) writeHandler).afterSheetCreate(writeWorkbookHolder, writeSheetHolder); + ((SheetWriteHandler)writeHandler).afterSheetCreate(writeWorkbookHolder, writeSheetHolder); } } if (null != writeWorkbookHolder.getWriteWorkbook().getWriteHandler()) { @@ -181,6 +182,16 @@ public class WriteContextImpl implements WriteContext { } private void initSheet() { + try { + if (writeWorkbookHolder.getXssfWorkbook() != null) { + writeSheetHolder + .setXssfSheet(writeWorkbookHolder.getXssfWorkbook().getSheetAt(writeSheetHolder.getSheetNo())); + } + } catch (Exception e) { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Can not find XSSFSheet:{}.", writeSheetHolder.getSheetNo()); + } + } Sheet currentSheet; try { currentSheet = writeWorkbookHolder.getWorkbook().getSheetAt(writeSheetHolder.getSheetNo()); @@ -204,7 +215,7 @@ public class WriteContextImpl implements WriteContext { // Combined head addMergedRegionToCurrentSheet(excelWriteHeadProperty, newRowIndex); for (int relativeRowIndex = 0, i = newRowIndex; i < excelWriteHeadProperty.getHeadRowNumber() + newRowIndex; - i++, relativeRowIndex++) { + i++, relativeRowIndex++) { beforeRowCreate(newRowIndex, relativeRowIndex); Row row = WorkBookUtil.createRow(writeSheetHolder.getSheet(), i); afterRowCreate(row, relativeRowIndex); @@ -219,7 +230,7 @@ public class WriteContextImpl implements WriteContext { } for (WriteHandler writeHandler : handlerList) { if (writeHandler instanceof RowWriteHandler) { - ((RowWriteHandler) writeHandler).beforeRowCreate(writeSheetHolder, writeTableHolder, rowIndex, + ((RowWriteHandler)writeHandler).beforeRowCreate(writeSheetHolder, writeTableHolder, rowIndex, relativeRowIndex, true); } } @@ -232,7 +243,7 @@ public class WriteContextImpl implements WriteContext { } for (WriteHandler writeHandler : handlerList) { if (writeHandler instanceof RowWriteHandler) { - ((RowWriteHandler) writeHandler).afterRowCreate(writeSheetHolder, writeTableHolder, row, + ((RowWriteHandler)writeHandler).afterRowCreate(writeSheetHolder, writeTableHolder, row, relativeRowIndex, true); } } @@ -264,7 +275,7 @@ public class WriteContextImpl implements WriteContext { } for (WriteHandler writeHandler : handlerList) { if (writeHandler instanceof CellWriteHandler) { - ((CellWriteHandler) writeHandler).beforeCellCreate(writeSheetHolder, writeTableHolder, row, head, + ((CellWriteHandler)writeHandler).beforeCellCreate(writeSheetHolder, writeTableHolder, row, head, relativeRowIndex, true); } } @@ -277,7 +288,7 @@ public class WriteContextImpl implements WriteContext { } for (WriteHandler writeHandler : handlerList) { if (writeHandler instanceof CellWriteHandler) { - ((CellWriteHandler) writeHandler).afterCellCreate(writeSheetHolder, writeTableHolder, null, cell, head, + ((CellWriteHandler)writeHandler).afterCellCreate(writeSheetHolder, writeTableHolder, null, cell, head, relativeRowIndex, true); } } @@ -354,7 +365,7 @@ public class WriteContextImpl implements WriteContext { try { Workbook workbook = writeWorkbookHolder.getWorkbook(); if (workbook instanceof SXSSFWorkbook) { - ((SXSSFWorkbook) workbook).dispose(); + ((SXSSFWorkbook)workbook).dispose(); } } catch (Throwable t) { throwCanNotCloseIo(t); diff --git a/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java b/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java index 2eb301a..3bbda25 100644 --- a/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java +++ b/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java @@ -19,6 +19,7 @@ import org.apache.poi.ss.usermodel.Drawing; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.xssf.usermodel.XSSFSheet; import com.alibaba.excel.context.WriteContext; import com.alibaba.excel.context.WriteContextImpl; @@ -129,14 +130,14 @@ public class ExcelBuilderImpl implements ExcelBuilder { private void doFill(Object data) { WriteSheetHolder writeSheetHolder = context.writeSheetHolder(); - Sheet sheet = writeSheetHolder.getSheet(); + XSSFSheet sheet = writeSheetHolder.getXssfSheet(); Map templateLastRowMap = context.writeWorkbookHolder().getTemplateLastRowMap(); if (sheet == null) { throw new ExcelGenerateException( "The corresponding table cannot be found,sheetNo:" + writeSheetHolder.getSheetNo()); } List analysisCellList = new ArrayList(); - for (int i = 0; i < templateLastRowMap.get(writeSheetHolder.getSheetNo()); i++) { + for (int i = 0; i <= sheet.getLastRowNum(); i++) { Row row = sheet.getRow(i); for (int j = 0; j < row.getLastCellNum(); j++) { Cell cell = row.getCell(j); @@ -151,7 +152,7 @@ public class ExcelBuilderImpl implements ExcelBuilder { int index = 0; while (matches) { Matcher matcher = FILL_PATTERN.matcher(value); - String variable = value.substring(matcher.start(), matcher.end()); + String variable = value.substring(matcher.regionStart() + 2, matcher.regionEnd() - 1); variableList.add(variable); value = matcher.replaceFirst("{" + index++ + "}"); matches = FILL_PATTERN.matcher(value).matches(); diff --git a/src/main/java/com/alibaba/excel/write/metadata/holder/WriteSheetHolder.java b/src/main/java/com/alibaba/excel/write/metadata/holder/WriteSheetHolder.java index 4d051df..208fb41 100644 --- a/src/main/java/com/alibaba/excel/write/metadata/holder/WriteSheetHolder.java +++ b/src/main/java/com/alibaba/excel/write/metadata/holder/WriteSheetHolder.java @@ -5,7 +5,6 @@ import java.util.Map; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.xssf.usermodel.XSSFSheet; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; import com.alibaba.excel.enums.HolderEnum; import com.alibaba.excel.enums.WriteLastRowType; diff --git a/update.md b/update.md index 5d5f254..3beaac9 100644 --- a/update.md +++ b/update.md @@ -1,5 +1,4 @@ # 2.1.0-beta1 -* 降级poi为3.1.7 兼容jdk6 * 新增支持导入、导出支持公式 * 新增支持读取单元格类型、写入指定单元格类型 * 支持通过模板填充数据