diff --git a/README.md b/README.md index 93ee3050..583cc4b1 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 00000000..04195a10 Binary files /dev/null and b/img/readme/large.png differ diff --git a/src/main/java/com/alibaba/excel/context/WriteContextImpl.java b/src/main/java/com/alibaba/excel/context/WriteContextImpl.java index 00602111..34b90bae 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 2eb301a1..3bbda250 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 4d051df3..208fb419 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 5d5f2546..3beaac91 100644 --- a/update.md +++ b/update.md @@ -1,5 +1,4 @@ # 2.1.0-beta1 -* 降级poi为3.1.7 兼容jdk6 * 新增支持导入、导出支持公式 * 新增支持读取单元格类型、写入指定单元格类型 * 支持通过模板填充数据