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比较有名的框架有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)

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.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);

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.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<Integer, Integer> templateLastRowMap = context.writeWorkbookHolder().getTemplateLastRowMap();
if (sheet == null) {
throw new ExcelGenerateException(
"The corresponding table cannot be found,sheetNo:" + writeSheetHolder.getSheetNo());
}
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);
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();

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

1
update.md

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

Loading…
Cancel
Save