Browse Source

Merge remote-tracking branch 'remotes/origin/master' into 2.1.x

# Conflicts:
#	pom.xml
#	src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java
#	src/main/java/com/alibaba/excel/analysis/v07/handlers/ProcessResultCellHandler.java
#	src/test/java/com/alibaba/easyexcel/test/core/fill/FillDataTest.java
#	update.md
2.1.x
Jiaju Zhuang 5 years ago
parent
commit
51cb8c8e54
  1. 1
      README.md
  2. 3
      src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java
  3. 31
      src/main/java/com/alibaba/excel/analysis/v07/handlers/RowTagHandler.java
  4. 81
      src/main/java/com/alibaba/excel/context/WriteContextImpl.java
  5. 32
      src/main/java/com/alibaba/excel/util/PositionUtils.java
  6. 9
      src/main/java/com/alibaba/excel/write/metadata/holder/WriteSheetHolder.java
  7. 25
      src/main/java/com/alibaba/excel/write/metadata/holder/WriteWorkbookHolder.java
  8. 25
      src/test/java/com/alibaba/easyexcel/test/core/fill/FillDataTest.java
  9. BIN
      src/test/resources/fill/byName.xls
  10. BIN
      src/test/resources/fill/byName.xlsx
  11. 7
      update.md

1
README.md

@ -7,6 +7,7 @@ easyexcel
[QQ群: 662022184](//shang.qq.com/wpa/qunwpa?idkey=53d9d821b0833e3c14670f007488a61e300f00ff4f1b81fd950590d90dd80f80)
[钉钉群: 21960511](https://qr.dingtalk.com/action/joingroup?code=v1,k1,cchz6k12ci9B08NNqhNRFGXocNVHrZtW0kaOtTKg/Rk=&_dt_no_comment=1&origin=11)
[官方网站: https://alibaba-easyexcel.github.io/](https://alibaba-easyexcel.github.io/)
#### 因为公司不方便用QQ,所以建议加钉钉群
# 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模式。在上层做了模型转换的封装,让使用者更加简单方便

3
src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java

@ -24,7 +24,8 @@ public class CellTagHandler extends AbstractXlsxTagHandler {
@Override
public void startElement(XlsxReadContext xlsxReadContext, String name, Attributes attributes) {
XlsxReadSheetHolder xlsxReadSheetHolder = xlsxReadContext.xlsxReadSheetHolder();
xlsxReadSheetHolder.setColumnIndex(PositionUtils.getCol(attributes.getValue(ExcelXmlConstants.ATTRIBUTE_R)));
xlsxReadSheetHolder.setColumnIndex(PositionUtils.getCol(attributes.getValue(ExcelXmlConstants.ATTRIBUTE_R),
xlsxReadSheetHolder.getColumnIndex()));
// t="s" ,it's means String
// t="str" ,it's means String,but does not need to be read in the 'sharedStrings.xml'

31
src/main/java/com/alibaba/excel/analysis/v07/handlers/RowTagHandler.java

@ -9,6 +9,7 @@ import com.alibaba.excel.context.xlsx.XlsxReadContext;
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.xlsx.XlsxReadSheetHolder;
import com.alibaba.excel.util.PositionUtils;
/**
@ -20,27 +21,31 @@ public class RowTagHandler extends AbstractXlsxTagHandler {
@Override
public void startElement(XlsxReadContext xlsxReadContext, String name, Attributes attributes) {
int rowIndex = PositionUtils.getRowByRowTagt(attributes.getValue(ExcelXmlConstants.ATTRIBUTE_R));
Integer lastIndex = xlsxReadContext.readSheetHolder().getRowIndex();
if (lastIndex != null) {
while (lastIndex + 1 < rowIndex) {
xlsxReadContext.readRowHolder(new ReadRowHolder(lastIndex + 1, RowTypeEnum.EMPTY,
xlsxReadContext.readSheetHolder().getGlobalConfiguration(), new LinkedHashMap<Integer, Cell>()));
XlsxReadSheetHolder xlsxReadSheetHolder = xlsxReadContext.xlsxReadSheetHolder();
int rowIndex = PositionUtils.getRowByRowTagt(attributes.getValue(ExcelXmlConstants.ATTRIBUTE_R),
xlsxReadSheetHolder.getRowIndex());
Integer lastRowIndex = xlsxReadContext.readSheetHolder().getRowIndex();
if (lastRowIndex != null) {
while (lastRowIndex + 1 < rowIndex) {
xlsxReadContext.readRowHolder(new ReadRowHolder(lastRowIndex + 1, RowTypeEnum.EMPTY,
xlsxReadSheetHolder.getGlobalConfiguration(), new LinkedHashMap<Integer, Cell>()));
xlsxReadContext.analysisEventProcessor().endRow(xlsxReadContext);
xlsxReadContext.xlsxReadSheetHolder().setCellMap(new LinkedHashMap<Integer, Cell>());
lastIndex++;
xlsxReadSheetHolder.setColumnIndex(null);
xlsxReadSheetHolder.setCellMap(new LinkedHashMap<Integer, Cell>());
lastRowIndex++;
}
}
xlsxReadContext.readSheetHolder().setRowIndex(rowIndex);
xlsxReadSheetHolder.setRowIndex(rowIndex);
}
@Override
public void endElement(XlsxReadContext xlsxReadContext, String name) {
xlsxReadContext.readRowHolder(new ReadRowHolder(xlsxReadContext.readSheetHolder().getRowIndex(),
RowTypeEnum.DATA, xlsxReadContext.readSheetHolder().getGlobalConfiguration(),
xlsxReadContext.xlsxReadSheetHolder().getCellMap()));
XlsxReadSheetHolder xlsxReadSheetHolder = xlsxReadContext.xlsxReadSheetHolder();
xlsxReadContext.readRowHolder(new ReadRowHolder(xlsxReadSheetHolder.getRowIndex(), RowTypeEnum.DATA,
xlsxReadSheetHolder.getGlobalConfiguration(), xlsxReadSheetHolder.getCellMap()));
xlsxReadContext.analysisEventProcessor().endRow(xlsxReadContext);
xlsxReadContext.xlsxReadSheetHolder().setCellMap(new LinkedHashMap<Integer, Cell>());
xlsxReadSheetHolder.setColumnIndex(null);
xlsxReadSheetHolder.setCellMap(new LinkedHashMap<Integer, Cell>());
}
}

81
src/main/java/com/alibaba/excel/context/WriteContextImpl.java

@ -108,34 +108,39 @@ public class WriteContextImpl implements WriteContext {
if (writeSheet == null) {
throw new IllegalArgumentException("Sheet argument cannot be null");
}
if (writeSheet.getSheetNo() == null || writeSheet.getSheetNo() <= 0) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Sheet number is null");
}
writeSheet.setSheetNo(0);
}
if (writeWorkbookHolder.getHasBeenInitializedSheet().containsKey(writeSheet.getSheetNo())) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Sheet:{} is already existed", writeSheet.getSheetNo());
}
writeSheetHolder = writeWorkbookHolder.getHasBeenInitializedSheet().get(writeSheet.getSheetNo());
writeSheetHolder.setNewInitialization(Boolean.FALSE);
writeTableHolder = null;
currentWriteHolder = writeSheetHolder;
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("CurrentConfiguration is writeSheetHolder");
}
if (selectSheetFromCache(writeSheet)) {
return;
}
initCurrentSheetHolder(writeSheet);
WriteHandlerUtils.beforeSheetCreate(this);
// Initialization current sheet
initSheet(writeType);
}
private boolean selectSheetFromCache(WriteSheet writeSheet) {
writeSheetHolder = null;
if (writeSheet.getSheetNo() != null) {
writeSheetHolder = writeWorkbookHolder.getHasBeenInitializedSheetIndexMap().get(writeSheet.getSheetNo());
}
if (writeSheetHolder == null && !StringUtils.isEmpty(writeSheet.getSheetName())) {
writeSheetHolder = writeWorkbookHolder.getHasBeenInitializedSheetNameMap().get(writeSheet.getSheetName());
}
if (writeSheetHolder == null) {
return false;
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Sheet:{} is already existed", writeSheet.getSheetNo());
}
writeSheetHolder.setNewInitialization(Boolean.FALSE);
writeTableHolder = null;
currentWriteHolder = writeSheetHolder;
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("CurrentConfiguration is writeSheetHolder");
}
return true;
}
private void initCurrentSheetHolder(WriteSheet writeSheet) {
writeSheetHolder = new WriteSheetHolder(writeSheet, writeWorkbookHolder);
writeWorkbookHolder.getHasBeenInitializedSheet().put(writeSheet.getSheetNo(), writeSheetHolder);
writeTableHolder = null;
currentWriteHolder = writeSheetHolder;
if (LOGGER.isDebugEnabled()) {
@ -144,17 +149,24 @@ public class WriteContextImpl implements WriteContext {
}
private void initSheet(WriteTypeEnum writeType) {
WriteHandlerUtils.beforeSheetCreate(this);
Sheet currentSheet;
try {
currentSheet = writeWorkbookHolder.getWorkbook().getSheetAt(writeSheetHolder.getSheetNo());
writeSheetHolder
.setCachedSheet(writeWorkbookHolder.getCachedWorkbook().getSheetAt(writeSheetHolder.getSheetNo()));
} catch (Exception e) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Can not find sheet:{} ,now create it", writeSheetHolder.getSheetNo());
if (writeSheetHolder.getSheetNo() != null) {
currentSheet = writeWorkbookHolder.getWorkbook().getSheetAt(writeSheetHolder.getSheetNo());
writeSheetHolder
.setCachedSheet(writeWorkbookHolder.getCachedWorkbook().getSheetAt(writeSheetHolder.getSheetNo()));
} else {
// sheet name must not null
currentSheet = writeWorkbookHolder.getWorkbook().getSheet(writeSheetHolder.getSheetName());
writeSheetHolder
.setCachedSheet(writeWorkbookHolder.getCachedWorkbook().getSheet(writeSheetHolder.getSheetName()));
}
currentSheet = WorkBookUtil.createSheet(writeWorkbookHolder.getWorkbook(), writeSheetHolder.getSheetName());
writeSheetHolder.setCachedSheet(currentSheet);
} catch (Exception e) {
currentSheet = createSheet();
}
if (currentSheet == null) {
currentSheet = createSheet();
}
writeSheetHolder.setSheet(currentSheet);
WriteHandlerUtils.afterSheetCreate(this);
@ -162,6 +174,21 @@ public class WriteContextImpl implements WriteContext {
// Initialization head
initHead(writeSheetHolder.excelWriteHeadProperty());
}
writeWorkbookHolder.getHasBeenInitializedSheetIndexMap().put(writeSheetHolder.getSheetNo(), writeSheetHolder);
writeWorkbookHolder.getHasBeenInitializedSheetNameMap().put(writeSheetHolder.getSheetName(), writeSheetHolder);
}
private Sheet createSheet() {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Can not find sheet:{} ,now create it", writeSheetHolder.getSheetNo());
}
if (StringUtils.isEmpty(writeSheetHolder.getSheetName())) {
writeSheetHolder.setSheetName(writeSheetHolder.getSheetNo().toString());
}
Sheet currentSheet =
WorkBookUtil.createSheet(writeWorkbookHolder.getWorkbook(), writeSheetHolder.getSheetName());
writeSheetHolder.setCachedSheet(currentSheet);
return currentSheet;
}
public void initHead(ExcelWriteHeadProperty excelWriteHeadProperty) {

32
src/main/java/com/alibaba/excel/util/PositionUtils.java

@ -15,6 +15,20 @@ public class PositionUtils {
return row;
}
public static int getRowByRowTagt(String rowTagt, Integer before) {
int row;
if (rowTagt != null) {
row = Integer.parseInt(rowTagt) - 1;
return row;
} else {
if (before == null) {
before = -1;
}
return before + 1;
}
}
public static int getRow(String currentCellIndex) {
int row = 0;
if (currentCellIndex != null) {
@ -35,4 +49,22 @@ public class PositionUtils {
}
return col - 1;
}
public static int getCol(String currentCellIndex, Integer before) {
int col = 0;
if (currentCellIndex != null) {
char[] currentIndex = currentCellIndex.replaceAll("[0-9]", "").toCharArray();
for (int i = 0; i < currentIndex.length; i++) {
col += (currentIndex[i] - '@') * Math.pow(26, (currentIndex.length - i - 1));
}
return col - 1;
} else {
if (before == null) {
before = -1;
}
return before + 1;
}
}
}

9
src/main/java/com/alibaba/excel/write/metadata/holder/WriteSheetHolder.java

@ -10,6 +10,7 @@ import org.apache.poi.xssf.usermodel.XSSFSheet;
import com.alibaba.excel.enums.HolderEnum;
import com.alibaba.excel.enums.WriteLastRowTypeEnum;
import com.alibaba.excel.util.StringUtils;
import com.alibaba.excel.write.metadata.WriteSheet;
/**
@ -67,12 +68,12 @@ public class WriteSheetHolder extends AbstractWriteHolder {
public WriteSheetHolder(WriteSheet writeSheet, WriteWorkbookHolder writeWorkbookHolder) {
super(writeSheet, writeWorkbookHolder, writeWorkbookHolder.getWriteWorkbook().getConvertAllFiled());
this.writeSheet = writeSheet;
this.sheetNo = writeSheet.getSheetNo();
if (writeSheet.getSheetName() == null) {
this.sheetName = writeSheet.getSheetNo().toString();
if (writeSheet.getSheetNo() == null && StringUtils.isEmpty(writeSheet.getSheetName())) {
this.sheetNo = 0;
} else {
this.sheetName = writeSheet.getSheetName();
this.sheetNo = writeSheet.getSheetNo();
}
this.sheetName = writeSheet.getSheetName();
this.parentWriteWorkbookHolder = writeWorkbookHolder;
this.hasBeenInitializedTable = new HashMap<Integer, WriteTableHolder>();
if (writeWorkbookHolder.getTempTemplateInputStream() != null) {

25
src/main/java/com/alibaba/excel/write/metadata/holder/WriteWorkbookHolder.java

@ -92,7 +92,11 @@ public class WriteWorkbookHolder extends AbstractWriteHolder {
/**
* prevent duplicate creation of sheet objects
*/
private Map<Integer, WriteSheetHolder> hasBeenInitializedSheet;
private Map<Integer, WriteSheetHolder> hasBeenInitializedSheetIndexMap;
/**
* prevent duplicate creation of sheet objects
*/
private Map<String, WriteSheetHolder> hasBeenInitializedSheetNameMap;
/**
* Whether the encryption
*/
@ -148,7 +152,8 @@ public class WriteWorkbookHolder extends AbstractWriteHolder {
} else {
this.mandatoryUseInputStream = writeWorkbook.getMandatoryUseInputStream();
}
this.hasBeenInitializedSheet = new HashMap<Integer, WriteSheetHolder>();
this.hasBeenInitializedSheetIndexMap = new HashMap<Integer, WriteSheetHolder>();
this.hasBeenInitializedSheetNameMap = new HashMap<String, WriteSheetHolder>();
this.password = writeWorkbook.getPassword();
if (writeWorkbook.getInMemory() == null) {
this.inMemory = Boolean.FALSE;
@ -197,12 +202,20 @@ public class WriteWorkbookHolder extends AbstractWriteHolder {
this.cachedWorkbook = cachedWorkbook;
}
public Map<Integer, WriteSheetHolder> getHasBeenInitializedSheet() {
return hasBeenInitializedSheet;
public Map<Integer, WriteSheetHolder> getHasBeenInitializedSheetIndexMap() {
return hasBeenInitializedSheetIndexMap;
}
public void setHasBeenInitializedSheetIndexMap(Map<Integer, WriteSheetHolder> hasBeenInitializedSheetIndexMap) {
this.hasBeenInitializedSheetIndexMap = hasBeenInitializedSheetIndexMap;
}
public Map<String, WriteSheetHolder> getHasBeenInitializedSheetNameMap() {
return hasBeenInitializedSheetNameMap;
}
public void setHasBeenInitializedSheet(Map<Integer, WriteSheetHolder> hasBeenInitializedSheet) {
this.hasBeenInitializedSheet = hasBeenInitializedSheet;
public void setHasBeenInitializedSheetNameMap(Map<String, WriteSheetHolder> hasBeenInitializedSheetNameMap) {
this.hasBeenInitializedSheetNameMap = hasBeenInitializedSheetNameMap;
}
public WriteWorkbook getWriteWorkbook() {

25
src/test/java/com/alibaba/easyexcel/test/core/fill/FillDataTest.java

@ -40,6 +40,10 @@ public class FillDataTest {
private static File horizontalFillTemplate07;
private static File fileHorizontal03;
private static File horizontalFillTemplate03;
private static File byName07;
private static File byName03;
private static File byNameTemplate07;
private static File byNameTemplate03;
private static File fileComposite07;
private static File compositeFillTemplate07;
private static File fileComposite03;
@ -59,6 +63,10 @@ public class FillDataTest {
horizontalFillTemplate07 = TestFileUtil.readFile("fill" + File.separator + "horizontal.xlsx");
fileHorizontal03 = TestFileUtil.createNewFile("fillHorizontal03.xls");
horizontalFillTemplate03 = TestFileUtil.readFile("fill" + File.separator + "horizontal.xls");
byName07 = TestFileUtil.createNewFile("byName07.xlsx");
byNameTemplate07 = TestFileUtil.readFile("fill" + File.separator + "byName.xlsx");
byName03 = TestFileUtil.createNewFile("byName03.xls");
byNameTemplate03 = TestFileUtil.readFile("fill" + File.separator + "byName.xls");
fileComposite07 = TestFileUtil.createNewFile("fileComposite07.xlsx");
compositeFillTemplate07 = TestFileUtil.readFile("fill" + File.separator + "composite.xlsx");
fileComposite03 = TestFileUtil.createNewFile("fileComposite03.xls");
@ -95,6 +103,23 @@ public class FillDataTest {
horizontalFill(fileHorizontal03, horizontalFillTemplate03);
}
@Test
public void t07ByNameFill07() {
byNameFill(byName07, byNameTemplate07);
}
@Test
public void t08ByNameFill03() {
byNameFill(byName03, byNameTemplate03);
}
private void byNameFill(File file, File template) {
FillData fillData = new FillData();
fillData.setName("张三");
fillData.setNumber(5.2);
EasyExcel.write(file, FillData.class).withTemplate(template).sheet("Sheet2").doFill(fillData);
}
@Test
public void t07CompositeFill07() {
compositeFill(fileComposite07, compositeFillTemplate07);

BIN
src/test/resources/fill/byName.xls

Binary file not shown.

BIN
src/test/resources/fill/byName.xlsx

Binary file not shown.

7
update.md

@ -15,6 +15,13 @@
* 修复读取转换器的并发问题
* 填充支持多个List对象
# 2.1.6
* 修复写入只有`sheetName`会抛异常
# 2.1.5
* 修复部分xlsx没有行号读取异常
* 填充时候支持根据`sheetName`定位`sheet`
# 2.1.4
* 新增参数`useDefaultListener` 可以排除默认对象转换

Loading…
Cancel
Save