Browse Source

Merge pull request #2177 from alibaba/developing

Developing
pull/2190/head v3.0.4
Jiaju Zhuang 3 years ago committed by GitHub
parent
commit
729320717d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      README.md
  2. 2
      pom.xml
  3. 2
      src/main/java/com/alibaba/excel/annotation/write/style/ContentLoopMerge.java
  4. 2
      src/main/java/com/alibaba/excel/cache/Ehcache.java
  5. 2
      src/main/java/com/alibaba/excel/metadata/csv/CsvSheet.java
  6. 2
      src/main/java/com/alibaba/excel/read/listener/PageReadListener.java
  7. 6
      src/main/java/com/alibaba/excel/util/WorkBookUtil.java
  8. 3
      src/main/java/com/alibaba/excel/write/executor/AbstractExcelWriteExecutor.java
  9. 28
      src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java
  10. 27
      src/main/java/com/alibaba/excel/write/handler/DefaultWriteHandlerLoader.java
  11. 6
      src/main/java/com/alibaba/excel/write/handler/RowWriteHandler.java
  12. 21
      src/main/java/com/alibaba/excel/write/merge/LoopMergeStrategy.java
  13. 33
      src/main/java/com/alibaba/excel/write/metadata/holder/AbstractWriteHolder.java
  14. 4
      src/main/java/com/alibaba/excel/write/metadata/holder/WriteSheetHolder.java
  15. 3
      src/main/java/com/alibaba/excel/write/metadata/holder/WriteTableHolder.java
  16. 4
      src/main/java/com/alibaba/excel/write/metadata/holder/WriteWorkbookHolder.java
  17. 36
      src/test/java/com/alibaba/easyexcel/test/core/fill/annotation/FillAnnotationData.java
  18. 92
      src/test/java/com/alibaba/easyexcel/test/core/fill/annotation/FillAnnotationDataTest.java
  19. 8
      src/test/java/com/alibaba/easyexcel/test/core/large/LargeDataTest.java
  20. 10
      src/test/java/com/alibaba/easyexcel/test/demo/read/CellDataDemoHeadDataListener.java
  21. 8
      src/test/java/com/alibaba/easyexcel/test/demo/read/ConverterDataListener.java
  22. 4
      src/test/java/com/alibaba/easyexcel/test/demo/read/DemoDataListener.java
  23. 2
      src/test/java/com/alibaba/easyexcel/test/demo/read/DemoExceptionListener.java
  24. 9
      src/test/java/com/alibaba/easyexcel/test/demo/read/DemoHeadDataListener.java
  25. 8
      src/test/java/com/alibaba/easyexcel/test/demo/read/IndexOrNameDataListener.java
  26. 8
      src/test/java/com/alibaba/easyexcel/test/demo/read/NoModelDataListener.java
  27. 2
      src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java
  28. 2
      src/test/java/com/alibaba/easyexcel/test/demo/web/UploadDataListener.java
  29. 2
      src/test/java/com/alibaba/easyexcel/test/temp/LockDataListener.java
  30. 4
      src/test/java/com/alibaba/easyexcel/test/temp/large/LargeData.java
  31. 173
      src/test/java/com/alibaba/easyexcel/test/temp/large/TempLargeDataTest.java
  32. 2
      src/test/java/com/alibaba/easyexcel/test/temp/read/HDListener.java
  33. 2
      src/test/java/com/alibaba/easyexcel/test/temp/read/HeadListener.java
  34. 8
      src/test/java/com/alibaba/easyexcel/test/temp/simple/HgListener.java
  35. 2
      src/test/java/com/alibaba/easyexcel/test/temp/simple/RepeatListener.java
  36. BIN
      src/test/resources/fill/annotation.xls
  37. BIN
      src/test/resources/fill/annotation.xlsx
  38. 4
      update.md

2
README.md

@ -41,7 +41,7 @@ Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.0.3</version>
<version>3.0.4</version>
</dependency>
```

2
pom.xml

@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.0.3</version>
<version>3.0.4</version>
<packaging>jar</packaging>
<name>easyexcel</name>

2
src/main/java/com/alibaba/excel/annotation/write/style/ContentLoopMerge.java

@ -20,7 +20,7 @@ public @interface ContentLoopMerge {
*
* @return
*/
int eachRow() default -1;
int eachRow() default 1;
/**
* Extend column

2
src/main/java/com/alibaba/excel/cache/Ehcache.java vendored

@ -24,7 +24,7 @@ import org.ehcache.config.units.MemoryUnit;
*/
@Slf4j
public class Ehcache implements ReadCache {
public static final int BATCH_COUNT = 1000;
public static final int BATCH_COUNT = 100;
/**
* Key index
*/

2
src/main/java/com/alibaba/excel/metadata/csv/CsvSheet.java

@ -85,7 +85,7 @@ public class CsvSheet implements Sheet, Closeable {
public CsvSheet(CsvWorkbook csvWorkbook, Appendable out) {
this.csvWorkbook = csvWorkbook;
this.out = out;
this.rowCacheCount = 3000;
this.rowCacheCount = 100;
this.csvFormat = CSVFormat.DEFAULT;
this.lastRowIndex = -1;
}

2
src/main/java/com/alibaba/excel/read/listener/PageReadListener.java

@ -17,7 +17,7 @@ public class PageReadListener<T> implements ReadListener<T> {
/**
* Single handle the amount of data
*/
public static int BATCH_COUNT = 3000;
public static int BATCH_COUNT = 100;
/**
* Temporary storage of data
*/

6
src/main/java/com/alibaba/excel/util/WorkBookUtil.java

@ -26,8 +26,6 @@ import org.apache.poi.xssf.usermodel.XSSFWorkbook;
*/
public class WorkBookUtil {
public static final int ROW_ACCESS_WINDOW_SIZE = 500;
private WorkBookUtil() {}
public static void createWorkBook(WriteWorkbookHolder writeWorkbookHolder) throws IOException {
@ -39,7 +37,7 @@ public class WorkBookUtil {
if (writeWorkbookHolder.getInMemory()) {
writeWorkbookHolder.setWorkbook(xssfWorkbook);
} else {
writeWorkbookHolder.setWorkbook(new SXSSFWorkbook(xssfWorkbook, ROW_ACCESS_WINDOW_SIZE));
writeWorkbookHolder.setWorkbook(new SXSSFWorkbook(xssfWorkbook));
}
return;
}
@ -47,7 +45,7 @@ public class WorkBookUtil {
if (writeWorkbookHolder.getInMemory()) {
workbook = new XSSFWorkbook();
} else {
workbook = new SXSSFWorkbook(ROW_ACCESS_WINDOW_SIZE);
workbook = new SXSSFWorkbook();
}
writeWorkbookHolder.setCachedWorkbook(workbook);
writeWorkbookHolder.setWorkbook(workbook);

3
src/main/java/com/alibaba/excel/write/executor/AbstractExcelWriteExecutor.java

@ -334,7 +334,8 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor {
}
if (cellData == null || cellData.getType() == null) {
throw new ExcelWriteDataConvertException(cellWriteHandlerContext,
"Convert data:" + cellWriteHandlerContext.getOriginalValue() + " return null, at row:"
"Convert data:" + cellWriteHandlerContext.getOriginalValue()
+ " return is null or return type is null, at row:"
+ cellWriteHandlerContext.getRowIndex());
}
return cellData;

28
src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java

@ -200,6 +200,9 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
}
Set<String> dataKeySet = new HashSet<>(dataMap.keySet());
RowWriteHandlerContext rowWriteHandlerContext = WriteHandlerUtils.createRowWriteHandlerContext(writeContext,
null, relativeRowIndex, Boolean.FALSE);
for (AnalysisCell analysisCell : analysisCellList) {
CellWriteHandlerContext cellWriteHandlerContext = WriteHandlerUtils.createCellWriteHandlerContext(
writeContext, null, analysisCell.getRowIndex(), null, analysisCell.getColumnIndex(),
@ -215,7 +218,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadClazz(), variable);
cellWriteHandlerContext.setExcelContentProperty(excelContentProperty);
createCell(analysisCell, fillConfig, cellWriteHandlerContext);
createCell(analysisCell, fillConfig, cellWriteHandlerContext, rowWriteHandlerContext);
cellWriteHandlerContext.setOriginalValue(value);
cellWriteHandlerContext.setOriginalFieldClass(FieldUtils.getFieldClass(dataMap, variable, value));
@ -236,7 +239,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
cellWriteHandlerContext.setExcelContentProperty(ExcelContentProperty.EMPTY);
cellWriteHandlerContext.setIgnoreFillStyle(Boolean.TRUE);
createCell(analysisCell, fillConfig, cellWriteHandlerContext);
createCell(analysisCell, fillConfig, cellWriteHandlerContext, rowWriteHandlerContext);
Cell cell = cellWriteHandlerContext.getCell();
for (String variable : analysisCell.getVariableList()) {
@ -288,6 +291,11 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
}
WriteHandlerUtils.afterCellDispose(cellWriteHandlerContext);
}
// In the case of the fill line may be called many times
if (rowWriteHandlerContext.getRow() != null) {
WriteHandlerUtils.afterRowDispose(rowWriteHandlerContext);
}
}
private Integer getRelativeRowIndex() {
@ -302,13 +310,16 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
}
private void createCell(AnalysisCell analysisCell, FillConfig fillConfig,
CellWriteHandlerContext cellWriteHandlerContext) {
CellWriteHandlerContext cellWriteHandlerContext, RowWriteHandlerContext rowWriteHandlerContext) {
Sheet cachedSheet = writeContext.writeSheetHolder().getCachedSheet();
if (WriteTemplateAnalysisCellTypeEnum.COMMON.equals(analysisCell.getCellType())) {
Row row = cachedSheet.getRow(analysisCell.getRowIndex());
cellWriteHandlerContext.setRow(row);
Cell cell = row.getCell(analysisCell.getColumnIndex());
cellWriteHandlerContext.setCell(cell);
rowWriteHandlerContext.setRow(row);
rowWriteHandlerContext.setRowIndex(analysisCell.getRowIndex());
return;
}
Sheet sheet = writeContext.writeSheetHolder().getSheet();
@ -345,7 +356,8 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
throw new ExcelGenerateException("The wrong direction.");
}
Row row = createRowIfNecessary(sheet, cachedSheet, lastRowIndex, fillConfig, analysisCell, isOriginalCell);
Row row = createRowIfNecessary(sheet, cachedSheet, lastRowIndex, fillConfig, analysisCell, isOriginalCell,
rowWriteHandlerContext);
cellWriteHandlerContext.setRow(row);
cellWriteHandlerContext.setRowIndex(lastRowIndex);
@ -375,16 +387,17 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
}
private Row createRowIfNecessary(Sheet sheet, Sheet cachedSheet, Integer lastRowIndex, FillConfig fillConfig,
AnalysisCell analysisCell, boolean isOriginalCell) {
AnalysisCell analysisCell, boolean isOriginalCell, RowWriteHandlerContext rowWriteHandlerContext) {
rowWriteHandlerContext.setRowIndex(lastRowIndex);
Row row = sheet.getRow(lastRowIndex);
if (row != null) {
checkRowHeight(analysisCell, fillConfig, isOriginalCell, row);
rowWriteHandlerContext.setRow(row);
return row;
}
row = cachedSheet.getRow(lastRowIndex);
if (row == null) {
RowWriteHandlerContext rowWriteHandlerContext = WriteHandlerUtils.createRowWriteHandlerContext(writeContext,
lastRowIndex, null, Boolean.FALSE);
rowWriteHandlerContext.setRowIndex(lastRowIndex);
WriteHandlerUtils.beforeRowCreate(rowWriteHandlerContext);
if (fillConfig.getForceNewRow()) {
@ -405,6 +418,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
WriteHandlerUtils.afterRowCreate(rowWriteHandlerContext);
} else {
checkRowHeight(analysisCell, fillConfig, isOriginalCell, row);
rowWriteHandlerContext.setRow(row);
}
return row;
}

27
src/main/java/com/alibaba/excel/write/handler/DefaultWriteHandlerLoader.java

@ -3,6 +3,7 @@ package com.alibaba.excel.write.handler;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.handler.impl.DefaultRowWriteHandler;
import com.alibaba.excel.write.handler.impl.DimensionWorkbookWriteHandler;
import com.alibaba.excel.write.handler.impl.FillStyleCellWriteHandler;
@ -28,12 +29,30 @@ public class DefaultWriteHandlerLoader {
*
* @return
*/
public static List<WriteHandler> loadDefaultHandler(Boolean useDefaultStyle) {
public static List<WriteHandler> loadDefaultHandler(Boolean useDefaultStyle, ExcelTypeEnum excelType) {
List<WriteHandler> handlerList = new ArrayList<>();
if (useDefaultStyle) {
handlerList.add(new DefaultStyle());
switch (excelType) {
case XLSX:
handlerList.add(new DimensionWorkbookWriteHandler());
handlerList.add(new DefaultRowWriteHandler());
handlerList.add(new FillStyleCellWriteHandler());
if (useDefaultStyle) {
handlerList.add(new DefaultStyle());
}
break;
case XLS:
handlerList.add(new DefaultRowWriteHandler());
handlerList.add(new FillStyleCellWriteHandler());
if (useDefaultStyle) {
handlerList.add(new DefaultStyle());
}
break;
case CSV:
handlerList.add(new DefaultRowWriteHandler());
break;
default:
break;
}
handlerList.addAll(DEFAULT_WRITE_HANDLER_LIST);
return handlerList;
}

6
src/main/java/com/alibaba/excel/write/handler/RowWriteHandler.java

@ -58,7 +58,8 @@ public interface RowWriteHandler extends WriteHandler {
Integer relativeRowIndex, Boolean isHead) {}
/**
* Called after all operations on the row have been completed.This method is not called when fill the data.
* Called after all operations on the row have been completed.
* In the case of the fill , may be called many times.
*
* @param context
*/
@ -68,7 +69,8 @@ public interface RowWriteHandler extends WriteHandler {
}
/**
* Called after all operations on the row have been completed.This method is not called when fill the data.
* Called after all operations on the row have been completed.
* In the case of the fill , may be called many times.
*
* @param writeSheetHolder
* @param writeTableHolder Nullable.It is null without using table writes.

21
src/main/java/com/alibaba/excel/write/merge/LoopMergeStrategy.java

@ -1,13 +1,10 @@
package com.alibaba.excel.write.merge;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.util.CellRangeAddress;
import com.alibaba.excel.metadata.property.LoopMergeProperty;
import com.alibaba.excel.write.handler.AbstractRowWriteHandler;
import com.alibaba.excel.write.handler.RowWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import com.alibaba.excel.write.handler.context.RowWriteHandlerContext;
import org.apache.poi.ss.util.CellRangeAddress;
/**
* The regions of the loop merge
@ -55,15 +52,15 @@ public class LoopMergeStrategy implements RowWriteHandler {
}
@Override
public void afterRowDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row,
Integer relativeRowIndex, Boolean isHead) {
if (isHead) {
public void afterRowDispose(RowWriteHandlerContext context) {
if (context.getHead() || context.getRelativeRowIndex() == null) {
return;
}
if (relativeRowIndex % eachRow == 0) {
CellRangeAddress cellRangeAddress = new CellRangeAddress(row.getRowNum(), row.getRowNum() + eachRow - 1,
if (context.getRelativeRowIndex() % eachRow == 0) {
CellRangeAddress cellRangeAddress = new CellRangeAddress(context.getRowIndex(),
context.getRowIndex() + eachRow - 1,
columnIndex, columnIndex + columnExtend - 1);
writeSheetHolder.getSheet().addMergedRegionUnsafe(cellRangeAddress);
context.getWriteSheetHolder().getSheet().addMergedRegionUnsafe(cellRangeAddress);
}
}

33
src/main/java/com/alibaba/excel/write/metadata/holder/AbstractWriteHolder.java

@ -203,6 +203,21 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ
// Initialization property
this.excelWriteHeadProperty = new ExcelWriteHeadProperty(this, getClazz(), getHead());
// Set converterMap
if (parentAbstractWriteHolder == null) {
setConverterMap(DefaultConverterLoader.loadDefaultWriteConverter());
} else {
setConverterMap(new HashMap<>(parentAbstractWriteHolder.getConverterMap()));
}
if (writeBasicParameter.getCustomConverterList() != null
&& !writeBasicParameter.getCustomConverterList().isEmpty()) {
for (Converter<?> converter : writeBasicParameter.getCustomConverterList()) {
getConverterMap().put(ConverterKeyBuild.buildKey(converter.supportJavaTypeKey()), converter);
}
}
}
protected void initHandler(WriteBasicParameter writeBasicParameter, AbstractWriteHolder parentAbstractWriteHolder) {
// Set writeHandlerMap
List<WriteHandler> handlerList = new ArrayList<>();
@ -220,22 +235,12 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ
handlerList.addAll(parentAbstractWriteHolder.getWriteHandlerList());
}
} else {
handlerList.addAll(DefaultWriteHandlerLoader.loadDefaultHandler(useDefaultStyle));
}
sortAndClearUpHandler(handlerList, false);
// Set converterMap
if (parentAbstractWriteHolder == null) {
setConverterMap(DefaultConverterLoader.loadDefaultWriteConverter());
} else {
setConverterMap(new HashMap<>(parentAbstractWriteHolder.getConverterMap()));
}
if (writeBasicParameter.getCustomConverterList() != null
&& !writeBasicParameter.getCustomConverterList().isEmpty()) {
for (Converter<?> converter : writeBasicParameter.getCustomConverterList()) {
getConverterMap().put(ConverterKeyBuild.buildKey(converter.supportJavaTypeKey()), converter);
if (this instanceof WriteWorkbookHolder) {
handlerList.addAll(DefaultWriteHandlerLoader.loadDefaultHandler(useDefaultStyle,
((WriteWorkbookHolder)this).getExcelType()));
}
}
sortAndClearUpHandler(handlerList, false);
}
protected void initAnnotationConfig(List<WriteHandler> handlerList, WriteBasicParameter writeBasicParameter) {

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

@ -80,6 +80,10 @@ public class WriteSheetHolder extends AbstractWriteHolder {
public WriteSheetHolder(WriteSheet writeSheet, WriteWorkbookHolder writeWorkbookHolder) {
super(writeSheet, writeWorkbookHolder);
// init handler
initHandler(writeSheet, writeWorkbookHolder);
this.writeSheet = writeSheet;
if (writeSheet.getSheetNo() == null && StringUtils.isEmpty(writeSheet.getSheetName())) {
this.sheetNo = 0;

3
src/main/java/com/alibaba/excel/write/metadata/holder/WriteTableHolder.java

@ -34,6 +34,9 @@ public class WriteTableHolder extends AbstractWriteHolder {
this.parentWriteSheetHolder = writeSheetHolder;
this.tableNo = writeTable.getTableNo();
this.writeTable = writeTable;
// init handler
initHandler(writeTable, writeSheetHolder);
}
@Override

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

@ -199,6 +199,10 @@ public class WriteWorkbookHolder extends AbstractWriteHolder {
} else {
this.excelType = writeWorkbook.getExcelType();
}
// init handler
initHandler(writeWorkbook, null);
try {
copyTemplate();
} catch (IOException e) {

36
src/test/java/com/alibaba/easyexcel/test/core/fill/annotation/FillAnnotationData.java

@ -0,0 +1,36 @@
package com.alibaba.easyexcel.test.core.fill.annotation;
import java.util.Date;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.DateTimeFormat;
import com.alibaba.excel.annotation.format.NumberFormat;
import com.alibaba.excel.annotation.write.style.ContentLoopMerge;
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* @author Jiaju Zhuang
*/
@Getter
@Setter
@EqualsAndHashCode
@ContentRowHeight(100)
public class FillAnnotationData {
@ExcelProperty("日期")
@DateTimeFormat("yyyy年MM月dd日HH时mm分ss秒")
private Date date;
@ExcelProperty(value = "数字")
@NumberFormat("#.##%")
private Double number;
@ContentLoopMerge(columnExtend = 2)
@ExcelProperty("字符串1")
private String string1;
@ExcelProperty("字符串2")
private String string2;
}

92
src/test/java/com/alibaba/easyexcel/test/core/fill/annotation/FillAnnotationDataTest.java

@ -0,0 +1,92 @@
package com.alibaba.easyexcel.test.core.fill.annotation;
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.alibaba.easyexcel.test.util.TestFileUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.util.DateUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.util.CellRangeAddress;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
/**
* @author Jiaju Zhuang
*/
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class FillAnnotationDataTest {
private static File file07;
private static File file03;
private static File fileTemplate07;
private static File fileTemplate03;
@BeforeClass
public static void init() {
file07 = TestFileUtil.createNewFile("fillAnnotation07.xlsx");
file03 = TestFileUtil.createNewFile("fillAnnotation03.xls");
fileTemplate07 = TestFileUtil.readFile("fill" + File.separator + "annotation.xlsx");
fileTemplate03 = TestFileUtil.readFile("fill" + File.separator + "annotation.xls");
}
@Test
public void t01ReadAndWrite07() throws Exception {
readAndWrite(file07, fileTemplate07);
}
@Test
public void t02ReadAndWrite03() throws Exception {
readAndWrite(file03, fileTemplate03);
}
private void readAndWrite(File file, File fileTemplate) throws Exception {
EasyExcel.write().file(file).head(FillAnnotationData.class).withTemplate(fileTemplate).sheet().doFill(data());
Workbook workbook = WorkbookFactory.create(file);
Sheet sheet = workbook.getSheetAt(0);
Row row1 = sheet.getRow(1);
Assert.assertEquals(2000, row1.getHeight(), 0);
Cell cell10 = row1.getCell(0);
Date date = cell10.getDateCellValue();
Assert.assertEquals(DateUtils.parseDate("2020-01-01 01:01:01").getTime(), date.getTime());
String dataFormatString = cell10.getCellStyle().getDataFormatString();
Assert.assertEquals("yyyy年MM月dd日HH时mm分ss秒", dataFormatString);
Cell cell11 = row1.getCell(1);
Assert.assertEquals(99.99, cell11.getNumericCellValue(), 2);
boolean hasMerge = false;
for (CellRangeAddress mergedRegion : sheet.getMergedRegions()) {
if (mergedRegion.getFirstRow() == 1 && mergedRegion.getLastRow() == 1
&& mergedRegion.getFirstColumn() == 2 && mergedRegion.getLastColumn() == 3) {
hasMerge = true;
}
}
Assert.assertTrue(hasMerge);
}
private List<FillAnnotationData> data() throws Exception {
List<FillAnnotationData> list = new ArrayList<>();
FillAnnotationData data = new FillAnnotationData();
data.setDate(DateUtils.parseDate("2020-01-01 01:01:01"));
data.setNumber(99.99);
data.setString1("string1");
data.setString2("string2");
list.add(data);
list.add(data);
list.add(data);
list.add(data);
list.add(data);
return list;
}
}

8
src/test/java/com/alibaba/easyexcel/test/core/large/LargeDataTest.java

@ -59,7 +59,7 @@ public class LargeDataTest {
public void t02Fill() {
ExcelWriter excelWriter = EasyExcel.write(fileFill07).withTemplate(template07).build();
WriteSheet writeSheet = EasyExcel.writerSheet().build();
for (int j = 0; j < 100; j++) {
for (int j = 0; j < 5000; j++) {
excelWriter.fill(data(), writeSheet);
LOGGER.info("{} fill success.", j);
}
@ -72,7 +72,7 @@ public class LargeDataTest {
long start = System.currentTimeMillis();
ExcelWriter excelWriter = EasyExcel.write(fileCsv).build();
WriteSheet writeSheet = EasyExcel.writerSheet().build();
for (int j = 0; j < 100; j++) {
for (int j = 0; j < 5000; j++) {
excelWriter.write(data(), writeSheet);
LOGGER.info("{} write success.", j);
}
@ -97,7 +97,7 @@ public class LargeDataTest {
long start = System.currentTimeMillis();
excelWriter = EasyExcel.write(fileWrite07, LargeData.class).build();
writeSheet = EasyExcel.writerSheet().build();
for (int j = 0; j < 100; j++) {
for (int j = 0; j < 5000; j++) {
excelWriter.write(data(), writeSheet);
LOGGER.info("{} write success.", j);
}
@ -130,7 +130,7 @@ public class LargeDataTest {
private List<LargeData> data() {
List<LargeData> list = new ArrayList<>();
int size = i + 5000;
int size = i + 100;
for (; i < size; i++) {
LargeData largeData = new LargeData();
list.add(largeData);

10
src/test/java/com/alibaba/easyexcel/test/demo/read/CellDataDemoHeadDataListener.java

@ -3,13 +3,13 @@ package com.alibaba.easyexcel.test.demo.read;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 读取头
*
@ -18,9 +18,9 @@ import com.alibaba.fastjson.JSON;
public class CellDataDemoHeadDataListener extends AnalysisEventListener<CellDataReadDemoData> {
private static final Logger LOGGER = LoggerFactory.getLogger(CellDataDemoHeadDataListener.class);
/**
* 每隔5条存储数据库实际使用中可以3000条然后清理list 方便内存回收
* 每隔5条存储数据库实际使用中可以100条然后清理list 方便内存回收
*/
private static final int BATCH_COUNT = 5;
private static final int BATCH_COUNT = 100;
List<CellDataReadDemoData> list = new ArrayList<CellDataReadDemoData>();
@Override

8
src/test/java/com/alibaba/easyexcel/test/demo/read/ConverterDataListener.java

@ -3,13 +3,13 @@ package com.alibaba.easyexcel.test.demo.read;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 模板的读取类
*
@ -18,7 +18,7 @@ import com.alibaba.fastjson.JSON;
public class ConverterDataListener extends AnalysisEventListener<ConverterData> {
private static final Logger LOGGER = LoggerFactory.getLogger(ConverterDataListener.class);
/**
* 每隔5条存储数据库实际使用中可以3000条然后清理list 方便内存回收
* 每隔5条存储数据库实际使用中可以100条然后清理list 方便内存回收
*/
private static final int BATCH_COUNT = 5;
List<ConverterData> list = new ArrayList<ConverterData>();

4
src/test/java/com/alibaba/easyexcel/test/demo/read/DemoDataListener.java

@ -19,9 +19,9 @@ import org.slf4j.LoggerFactory;
public class DemoDataListener extends AnalysisEventListener<DemoData> {
private static final Logger LOGGER = LoggerFactory.getLogger(DemoDataListener.class);
/**
* 每隔5条存储数据库实际使用中可以3000条然后清理list 方便内存回收
* 每隔5条存储数据库实际使用中可以100条然后清理list 方便内存回收
*/
private static final int BATCH_COUNT = 3000;
private static final int BATCH_COUNT = 100;
/**
* 缓存的数据
*/

2
src/test/java/com/alibaba/easyexcel/test/demo/read/DemoExceptionListener.java

@ -20,7 +20,7 @@ import com.alibaba.fastjson.JSON;
public class DemoExceptionListener extends AnalysisEventListener<ExceptionDemoData> {
private static final Logger LOGGER = LoggerFactory.getLogger(DemoExceptionListener.class);
/**
* 每隔5条存储数据库实际使用中可以3000条然后清理list 方便内存回收
* 每隔5条存储数据库实际使用中可以100条然后清理list 方便内存回收
*/
private static final int BATCH_COUNT = 5;
List<ExceptionDemoData> list = new ArrayList<ExceptionDemoData>();

9
src/test/java/com/alibaba/easyexcel/test/demo/read/DemoHeadDataListener.java

@ -4,15 +4,14 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.junit.Assert;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 读取头
*
@ -21,7 +20,7 @@ import com.alibaba.fastjson.JSON;
public class DemoHeadDataListener extends AnalysisEventListener<DemoData> {
private static final Logger LOGGER = LoggerFactory.getLogger(DemoHeadDataListener.class);
/**
* 每隔5条存储数据库实际使用中可以3000条然后清理list 方便内存回收
* 每隔5条存储数据库实际使用中可以100条然后清理list 方便内存回收
*/
private static final int BATCH_COUNT = 5;
List<DemoData> list = new ArrayList<DemoData>();

8
src/test/java/com/alibaba/easyexcel/test/demo/read/IndexOrNameDataListener.java

@ -3,13 +3,13 @@ package com.alibaba.easyexcel.test.demo.read;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 模板的读取类
*
@ -18,7 +18,7 @@ import com.alibaba.fastjson.JSON;
public class IndexOrNameDataListener extends AnalysisEventListener<IndexOrNameData> {
private static final Logger LOGGER = LoggerFactory.getLogger(IndexOrNameDataListener.class);
/**
* 每隔5条存储数据库实际使用中可以3000条然后清理list 方便内存回收
* 每隔5条存储数据库实际使用中可以100条然后清理list 方便内存回收
*/
private static final int BATCH_COUNT = 5;
List<IndexOrNameData> list = new ArrayList<IndexOrNameData>();

8
src/test/java/com/alibaba/easyexcel/test/demo/read/NoModelDataListener.java

@ -4,13 +4,13 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 直接用map接收数据
*
@ -19,7 +19,7 @@ import com.alibaba.fastjson.JSON;
public class NoModelDataListener extends AnalysisEventListener<Map<Integer, String>> {
private static final Logger LOGGER = LoggerFactory.getLogger(NoModelDataListener.class);
/**
* 每隔5条存储数据库实际使用中可以3000条然后清理list 方便内存回收
* 每隔5条存储数据库实际使用中可以100条然后清理list 方便内存回收
*/
private static final int BATCH_COUNT = 5;
List<Map<Integer, String>> list = new ArrayList<Map<Integer, String>>();

2
src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java

@ -64,7 +64,7 @@ public class ReadTest {
/**
* 单次缓存的数据量
*/
public static final int BATCH_COUNT = 3000;
public static final int BATCH_COUNT = 100;
/**
*临时存储
*/

2
src/test/java/com/alibaba/easyexcel/test/demo/web/UploadDataListener.java

@ -20,7 +20,7 @@ public class UploadDataListener extends AnalysisEventListener<UploadData> {
private static final Logger LOGGER =
LoggerFactory.getLogger(com.alibaba.easyexcel.test.demo.read.DemoDataListener.class);
/**
* 每隔5条存储数据库实际使用中可以3000条然后清理list 方便内存回收
* 每隔5条存储数据库实际使用中可以100条然后清理list 方便内存回收
*/
private static final int BATCH_COUNT = 5;
List<UploadData> list = new ArrayList<UploadData>();

2
src/test/java/com/alibaba/easyexcel/test/temp/LockDataListener.java

@ -19,7 +19,7 @@ import com.alibaba.fastjson.JSON;
public class LockDataListener extends AnalysisEventListener<LockData> {
private static final Logger LOGGER = LoggerFactory.getLogger(DemoDataListener.class);
/**
* 每隔5条存储数据库实际使用中可以3000条然后清理list 方便内存回收
* 每隔5条存储数据库实际使用中可以100条然后清理list 方便内存回收
*/
private static final int BATCH_COUNT = 5;
List<LockData> list = new ArrayList<LockData>();

4
src/test/java/com/alibaba/easyexcel/test/temp/large/LargeData.java

@ -1,8 +1,8 @@
package com.alibaba.easyexcel.test.temp.large;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/**
@ -11,7 +11,7 @@ import lombok.Setter;
@Getter
@Setter
@EqualsAndHashCode
@Builder
@NoArgsConstructor
public class LargeData {
private String str1;

173
src/test/java/com/alibaba/easyexcel/test/temp/large/TempLargeDataTest.java

@ -2,13 +2,25 @@ package com.alibaba.easyexcel.test.temp.large;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;
import com.alibaba.easyexcel.test.core.large.LargeDataTest;
import com.alibaba.easyexcel.test.util.TestFileUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import org.apache.poi.openxml4j.util.ZipSecureFile;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.slf4j.Logger;
@ -21,6 +33,24 @@ import org.slf4j.LoggerFactory;
public class TempLargeDataTest {
private static final Logger LOGGER = LoggerFactory.getLogger(LargeDataTest.class);
private int i = 0;
private static File fileFill07;
private static File template07;
private static File fileCsv;
private static File fileWrite07;
private static File fileWriteTemp07;
private static File fileWritePoi07;
@BeforeClass
public static void init() {
fileFill07 = TestFileUtil.createNewFile("largefill07.xlsx");
fileWrite07 = TestFileUtil.createNewFile("large" + File.separator + "fileWrite07.xlsx");
fileWriteTemp07 = TestFileUtil.createNewFile("large" + File.separator + "fileWriteTemp07.xlsx");
fileWritePoi07 = TestFileUtil.createNewFile("large" + File.separator + "fileWritePoi07.xlsx");
template07 = TestFileUtil.readFile("large" + File.separator + "fill.xlsx");
fileCsv = TestFileUtil.createNewFile("largefileCsv.csv");
}
@Test
public void read() throws Exception {
@ -47,9 +77,148 @@ public class TempLargeDataTest {
long start = System.currentTimeMillis();
EasyExcel.read(
new File("/Users/zhuangjiaju/IdeaProjects/easyexcel/target/test-classes/large1617887262709.xlsx"),
new NoModelLargeDataListener())
new File("/Users/zhuangjiaju/IdeaProjects/easyexcel/target/test-classes/large1617887262709.xlsx"),
new NoModelLargeDataListener())
.sheet().doRead();
LOGGER.info("Large data total time spent:{}", System.currentTimeMillis() - start);
}
@Test
public void t04Write() throws Exception {
ExcelWriter excelWriter = EasyExcel.write(fileWriteTemp07,
com.alibaba.easyexcel.test.core.large.LargeData.class).build();
WriteSheet writeSheet = EasyExcel.writerSheet().build();
for (int j = 0; j < 2; j++) {
excelWriter.write(data(), writeSheet);
}
excelWriter.finish();
long start = System.currentTimeMillis();
excelWriter = EasyExcel.write(fileWrite07, com.alibaba.easyexcel.test.core.large.LargeData.class).build();
writeSheet = EasyExcel.writerSheet().build();
for (int j = 0; j < 5000; j++) {
excelWriter.write(data(), writeSheet);
LOGGER.info("{} write success.", j);
}
excelWriter.finish();
long cost = System.currentTimeMillis() - start;
LOGGER.info("write cost:{}", cost);
start = System.currentTimeMillis();
try (FileOutputStream fileOutputStream = new FileOutputStream(fileWritePoi07)) {
SXSSFWorkbook workbook = new SXSSFWorkbook();
SXSSFSheet sheet = workbook.createSheet("sheet1");
for (int i = 0; i < 100 * 5000; i++) {
SXSSFRow row = sheet.createRow(i);
for (int j = 0; j < 25; j++) {
SXSSFCell cell = row.createCell(j);
cell.setCellValue("str-" + j + "-" + i);
}
if (i % 5000 == 0) {
LOGGER.info("{} write success.", i);
}
}
workbook.write(fileOutputStream);
workbook.dispose();
workbook.close();
}
long costPoi = System.currentTimeMillis() - start;
LOGGER.info("poi write cost:{}", System.currentTimeMillis() - start);
LOGGER.info("{} vs {}", cost, costPoi);
Assert.assertTrue(costPoi * 2 > cost);
}
@Test
public void t04WriteExcel() throws Exception {
IntStream.rangeClosed(0, 100).forEach(index -> {
ExcelWriter excelWriter = EasyExcel.write(fileWriteTemp07,
com.alibaba.easyexcel.test.core.large.LargeData.class).build();
WriteSheet writeSheet = EasyExcel.writerSheet().build();
for (int j = 0; j < 5000; j++) {
excelWriter.write(data(), writeSheet);
}
excelWriter.finish();
LOGGER.info("{} 完成", index);
});
}
@Test
public void t04WriteExcelNo() throws Exception {
IntStream.rangeClosed(0, 10000).forEach(index -> {
ExcelWriter excelWriter = EasyExcel.write(fileWriteTemp07,
com.alibaba.easyexcel.test.core.large.LargeData.class).build();
WriteSheet writeSheet = EasyExcel.writerSheet().build();
for (int j = 0; j < 50; j++) {
excelWriter.write(data(), writeSheet);
}
excelWriter.finish();
LOGGER.info("{} 完成", index);
});
}
@Test
public void t04WriteExcelPoi() throws Exception {
IntStream.rangeClosed(0, 10000).forEach(index -> {
try (FileOutputStream fileOutputStream = new FileOutputStream(fileWritePoi07)) {
SXSSFWorkbook workbook = new SXSSFWorkbook(500);
//workbook.setCompressTempFiles(true);
SXSSFSheet sheet = workbook.createSheet("sheet1");
for (int i = 0; i < 100 * 50; i++) {
SXSSFRow row = sheet.createRow(i);
for (int j = 0; j < 25; j++) {
String str = "str-" + j + "-" + i;
//if (i + 10000 == j) {
SXSSFCell cell = row.createCell(j);
cell.setCellValue(str);
//System.out.println(str);
//}
}
if (i % 5000 == 0) {
LOGGER.info("{} write success.", i);
}
}
workbook.write(fileOutputStream);
workbook.dispose();
workbook.close();
} catch (Exception e) {
e.printStackTrace();
}
LOGGER.info("{} 完成", index);
});
}
private List<LargeData> data() {
List<LargeData> list = new ArrayList<>();
int size = i + 100;
for (; i < size; i++) {
LargeData largeData = new LargeData();
list.add(largeData);
largeData.setStr1("str1-" + i);
largeData.setStr2("str2-" + i);
largeData.setStr3("str3-" + i);
largeData.setStr4("str4-" + i);
largeData.setStr5("str5-" + i);
largeData.setStr6("str6-" + i);
largeData.setStr7("str7-" + i);
largeData.setStr8("str8-" + i);
largeData.setStr9("str9-" + i);
largeData.setStr10("str10-" + i);
largeData.setStr11("str11-" + i);
largeData.setStr12("str12-" + i);
largeData.setStr13("str13-" + i);
largeData.setStr14("str14-" + i);
largeData.setStr15("str15-" + i);
largeData.setStr16("str16-" + i);
largeData.setStr17("str17-" + i);
largeData.setStr18("str18-" + i);
largeData.setStr19("str19-" + i);
largeData.setStr20("str20-" + i);
largeData.setStr21("str21-" + i);
largeData.setStr22("str22-" + i);
largeData.setStr23("str23-" + i);
largeData.setStr24("str24-" + i);
largeData.setStr25("str25-" + i);
}
return list;
}
}

2
src/test/java/com/alibaba/easyexcel/test/temp/read/HDListener.java

@ -17,7 +17,7 @@ import com.alibaba.fastjson.JSON;
public class HDListener extends AnalysisEventListener<HeadReadData> {
private static final Logger LOGGER = LoggerFactory.getLogger(HDListener.class);
/**
* 每隔5条存储数据库实际使用中可以3000条然后清理list 方便内存回收
* 每隔5条存储数据库实际使用中可以100条然后清理list 方便内存回收
*/
private static final int BATCH_COUNT = 5;

2
src/test/java/com/alibaba/easyexcel/test/temp/read/HeadListener.java

@ -17,7 +17,7 @@ import com.alibaba.fastjson.JSON;
public class HeadListener extends AnalysisEventListener<HeadReadData> {
private static final Logger LOGGER = LoggerFactory.getLogger(HeadListener.class);
/**
* 每隔5条存储数据库实际使用中可以3000条然后清理list 方便内存回收
* 每隔5条存储数据库实际使用中可以100条然后清理list 方便内存回收
*/
private static final int BATCH_COUNT = 5;

8
src/test/java/com/alibaba/easyexcel/test/temp/simple/HgListener.java

@ -2,13 +2,13 @@ package com.alibaba.easyexcel.test.temp.simple;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 模板的读取类
*
@ -17,7 +17,7 @@ import com.alibaba.fastjson.JSON;
public class HgListener extends AnalysisEventListener<Map<Integer, String>> {
private static final Logger LOGGER = LoggerFactory.getLogger(HgListener.class);
/**
* 每隔5条存储数据库实际使用中可以3000条然后清理list 方便内存回收
* 每隔5条存储数据库实际使用中可以100条然后清理list 方便内存回收
*/
private static final int BATCH_COUNT = 5;

2
src/test/java/com/alibaba/easyexcel/test/temp/simple/RepeatListener.java

@ -20,7 +20,7 @@ import com.alibaba.fastjson.JSON;
public class RepeatListener extends AnalysisEventListener<LockData> {
private static final Logger LOGGER = LoggerFactory.getLogger(DemoDataListener.class);
/**
* 每隔5条存储数据库实际使用中可以3000条然后清理list 方便内存回收
* 每隔5条存储数据库实际使用中可以100条然后清理list 方便内存回收
*/
private static final int BATCH_COUNT = 5;
List<LockData> list = new ArrayList<LockData>();

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

Binary file not shown.

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

Binary file not shown.

4
update.md

@ -1,3 +1,7 @@
# 3.0.4
* 调整读写默认大小,防止大批量写的时候可能会full gc
* `fill`的情况新增 `afterRowDispose`事件
# 3.0.3
* 修复`HeadStyle`无效的bug

Loading…
Cancel
Save