Browse Source

优化07版超大文件读取方案

bugfix
Jiaju Zhuang 5 years ago
parent
commit
3a2bf2b43f
  1. 5
      README.md
  2. BIN
      img/readme/large.png
  3. 31
      src/main/java/com/alibaba/excel/context/WriteContextImpl.java
  4. 7
      src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java
  5. 1
      src/main/java/com/alibaba/excel/write/metadata/holder/WriteSheetHolder.java
  6. 1
      update.md

5
README.md

@ -8,6 +8,11 @@ easyexcel
# JAVA解析Excel工具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模式。在上层做了模型转换的封装,让使用者更加简单方便 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) * [快速使用](/quickstart.md)
* [关于软件](/abouteasyexcel.md) * [关于软件](/abouteasyexcel.md)

BIN
img/readme/large.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

31
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.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -83,7 +84,7 @@ public class WriteContextImpl implements WriteContext {
} }
for (WriteHandler writeHandler : handlerList) { for (WriteHandler writeHandler : handlerList) {
if (writeHandler instanceof WorkbookWriteHandler) { if (writeHandler instanceof WorkbookWriteHandler) {
((WorkbookWriteHandler) writeHandler).beforeWorkbookCreate(); ((WorkbookWriteHandler)writeHandler).beforeWorkbookCreate();
} }
} }
} }
@ -95,7 +96,7 @@ public class WriteContextImpl implements WriteContext {
} }
for (WriteHandler writeHandler : handlerList) { for (WriteHandler writeHandler : handlerList) {
if (writeHandler instanceof WorkbookWriteHandler) { 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) { for (WriteHandler writeHandler : handlerList) {
if (writeHandler instanceof SheetWriteHandler) { 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) { for (WriteHandler writeHandler : handlerList) {
if (writeHandler instanceof SheetWriteHandler) { if (writeHandler instanceof SheetWriteHandler) {
((SheetWriteHandler) writeHandler).afterSheetCreate(writeWorkbookHolder, writeSheetHolder); ((SheetWriteHandler)writeHandler).afterSheetCreate(writeWorkbookHolder, writeSheetHolder);
} }
} }
if (null != writeWorkbookHolder.getWriteWorkbook().getWriteHandler()) { if (null != writeWorkbookHolder.getWriteWorkbook().getWriteHandler()) {
@ -181,6 +182,16 @@ public class WriteContextImpl implements WriteContext {
} }
private void initSheet() { 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; Sheet currentSheet;
try { try {
currentSheet = writeWorkbookHolder.getWorkbook().getSheetAt(writeSheetHolder.getSheetNo()); currentSheet = writeWorkbookHolder.getWorkbook().getSheetAt(writeSheetHolder.getSheetNo());
@ -204,7 +215,7 @@ public class WriteContextImpl implements WriteContext {
// Combined head // Combined head
addMergedRegionToCurrentSheet(excelWriteHeadProperty, newRowIndex); addMergedRegionToCurrentSheet(excelWriteHeadProperty, newRowIndex);
for (int relativeRowIndex = 0, i = newRowIndex; i < excelWriteHeadProperty.getHeadRowNumber() + newRowIndex; for (int relativeRowIndex = 0, i = newRowIndex; i < excelWriteHeadProperty.getHeadRowNumber() + newRowIndex;
i++, relativeRowIndex++) { i++, relativeRowIndex++) {
beforeRowCreate(newRowIndex, relativeRowIndex); beforeRowCreate(newRowIndex, relativeRowIndex);
Row row = WorkBookUtil.createRow(writeSheetHolder.getSheet(), i); Row row = WorkBookUtil.createRow(writeSheetHolder.getSheet(), i);
afterRowCreate(row, relativeRowIndex); afterRowCreate(row, relativeRowIndex);
@ -219,7 +230,7 @@ public class WriteContextImpl implements WriteContext {
} }
for (WriteHandler writeHandler : handlerList) { for (WriteHandler writeHandler : handlerList) {
if (writeHandler instanceof RowWriteHandler) { if (writeHandler instanceof RowWriteHandler) {
((RowWriteHandler) writeHandler).beforeRowCreate(writeSheetHolder, writeTableHolder, rowIndex, ((RowWriteHandler)writeHandler).beforeRowCreate(writeSheetHolder, writeTableHolder, rowIndex,
relativeRowIndex, true); relativeRowIndex, true);
} }
} }
@ -232,7 +243,7 @@ public class WriteContextImpl implements WriteContext {
} }
for (WriteHandler writeHandler : handlerList) { for (WriteHandler writeHandler : handlerList) {
if (writeHandler instanceof RowWriteHandler) { if (writeHandler instanceof RowWriteHandler) {
((RowWriteHandler) writeHandler).afterRowCreate(writeSheetHolder, writeTableHolder, row, ((RowWriteHandler)writeHandler).afterRowCreate(writeSheetHolder, writeTableHolder, row,
relativeRowIndex, true); relativeRowIndex, true);
} }
} }
@ -264,7 +275,7 @@ public class WriteContextImpl implements WriteContext {
} }
for (WriteHandler writeHandler : handlerList) { for (WriteHandler writeHandler : handlerList) {
if (writeHandler instanceof CellWriteHandler) { if (writeHandler instanceof CellWriteHandler) {
((CellWriteHandler) writeHandler).beforeCellCreate(writeSheetHolder, writeTableHolder, row, head, ((CellWriteHandler)writeHandler).beforeCellCreate(writeSheetHolder, writeTableHolder, row, head,
relativeRowIndex, true); relativeRowIndex, true);
} }
} }
@ -277,7 +288,7 @@ public class WriteContextImpl implements WriteContext {
} }
for (WriteHandler writeHandler : handlerList) { for (WriteHandler writeHandler : handlerList) {
if (writeHandler instanceof CellWriteHandler) { if (writeHandler instanceof CellWriteHandler) {
((CellWriteHandler) writeHandler).afterCellCreate(writeSheetHolder, writeTableHolder, null, cell, head, ((CellWriteHandler)writeHandler).afterCellCreate(writeSheetHolder, writeTableHolder, null, cell, head,
relativeRowIndex, true); relativeRowIndex, true);
} }
} }
@ -354,7 +365,7 @@ public class WriteContextImpl implements WriteContext {
try { try {
Workbook workbook = writeWorkbookHolder.getWorkbook(); Workbook workbook = writeWorkbookHolder.getWorkbook();
if (workbook instanceof SXSSFWorkbook) { if (workbook instanceof SXSSFWorkbook) {
((SXSSFWorkbook) workbook).dispose(); ((SXSSFWorkbook)workbook).dispose();
} }
} catch (Throwable t) { } catch (Throwable t) {
throwCanNotCloseIo(t); throwCanNotCloseIo(t);

7
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.Row;
import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress; 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.WriteContext;
import com.alibaba.excel.context.WriteContextImpl; import com.alibaba.excel.context.WriteContextImpl;
@ -129,14 +130,14 @@ public class ExcelBuilderImpl implements ExcelBuilder {
private void doFill(Object data) { private void doFill(Object data) {
WriteSheetHolder writeSheetHolder = context.writeSheetHolder(); WriteSheetHolder writeSheetHolder = context.writeSheetHolder();
Sheet sheet = writeSheetHolder.getSheet(); XSSFSheet sheet = writeSheetHolder.getXssfSheet();
Map<Integer, Integer> templateLastRowMap = context.writeWorkbookHolder().getTemplateLastRowMap(); Map<Integer, Integer> templateLastRowMap = context.writeWorkbookHolder().getTemplateLastRowMap();
if (sheet == null) { if (sheet == null) {
throw new ExcelGenerateException( throw new ExcelGenerateException(
"The corresponding table cannot be found,sheetNo:" + writeSheetHolder.getSheetNo()); "The corresponding table cannot be found,sheetNo:" + writeSheetHolder.getSheetNo());
} }
List<AnalysisCell> analysisCellList = new ArrayList<AnalysisCell>(); List<AnalysisCell> analysisCellList = new ArrayList<AnalysisCell>();
for (int i = 0; i < templateLastRowMap.get(writeSheetHolder.getSheetNo()); i++) { for (int i = 0; i <= sheet.getLastRowNum(); i++) {
Row row = sheet.getRow(i); Row row = sheet.getRow(i);
for (int j = 0; j < row.getLastCellNum(); j++) { for (int j = 0; j < row.getLastCellNum(); j++) {
Cell cell = row.getCell(j); Cell cell = row.getCell(j);
@ -151,7 +152,7 @@ public class ExcelBuilderImpl implements ExcelBuilder {
int index = 0; int index = 0;
while (matches) { while (matches) {
Matcher matcher = FILL_PATTERN.matcher(value); 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); variableList.add(variable);
value = matcher.replaceFirst("{" + index++ + "}"); value = matcher.replaceFirst("{" + index++ + "}");
matches = FILL_PATTERN.matcher(value).matches(); matches = FILL_PATTERN.matcher(value).matches();

1
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.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFSheet; 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.HolderEnum;
import com.alibaba.excel.enums.WriteLastRowType; import com.alibaba.excel.enums.WriteLastRowType;

1
update.md

@ -1,5 +1,4 @@
# 2.1.0-beta1 # 2.1.0-beta1
* 降级poi为3.1.7 兼容jdk6
* 新增支持导入、导出支持公式 * 新增支持导入、导出支持公式
* 新增支持读取单元格类型、写入指定单元格类型 * 新增支持读取单元格类型、写入指定单元格类型
* 支持通过模板填充数据 * 支持通过模板填充数据

Loading…
Cancel
Save