Browse Source

Merge pull request #2159 from alibaba/developing

Developing
pull/2160/head
Jiaju Zhuang 3 years ago committed by GitHub
parent
commit
f5807a5bce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      README.md
  2. BIN
      img/readme/large.png
  3. 2
      pom.xml
  4. 6
      src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java
  5. 18
      src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java
  6. 67
      src/main/java/com/alibaba/excel/context/WriteContextImpl.java
  7. 51
      src/main/java/com/alibaba/excel/converters/ConverterKeyBuild.java
  8. 11
      src/main/java/com/alibaba/excel/converters/DefaultConverterLoader.java
  9. 8
      src/main/java/com/alibaba/excel/converters/ReadConverterContext.java
  10. 8
      src/main/java/com/alibaba/excel/converters/WriteConverterContext.java
  11. 12
      src/main/java/com/alibaba/excel/exception/ExcelDataConvertException.java
  12. 36
      src/main/java/com/alibaba/excel/exception/ExcelWriteDataConvertException.java
  13. 8
      src/main/java/com/alibaba/excel/metadata/AbstractCell.java
  14. 13
      src/main/java/com/alibaba/excel/metadata/AbstractHolder.java
  15. 8
      src/main/java/com/alibaba/excel/metadata/BasicParameter.java
  16. 8
      src/main/java/com/alibaba/excel/metadata/CellRange.java
  17. 5
      src/main/java/com/alibaba/excel/metadata/ConfigurationHolder.java
  18. 8
      src/main/java/com/alibaba/excel/metadata/GlobalConfiguration.java
  19. 8
      src/main/java/com/alibaba/excel/metadata/Head.java
  20. 6
      src/main/java/com/alibaba/excel/metadata/csv/CsvCell.java
  21. 8
      src/main/java/com/alibaba/excel/metadata/csv/CsvCellStyle.java
  22. 8
      src/main/java/com/alibaba/excel/metadata/csv/CsvRow.java
  23. 8
      src/main/java/com/alibaba/excel/metadata/csv/CsvSheet.java
  24. 8
      src/main/java/com/alibaba/excel/metadata/csv/CsvWorkbook.java
  25. 8
      src/main/java/com/alibaba/excel/metadata/data/CellData.java
  26. 7
      src/main/java/com/alibaba/excel/metadata/data/ClientAnchorData.java
  27. 8
      src/main/java/com/alibaba/excel/metadata/data/CommentData.java
  28. 8
      src/main/java/com/alibaba/excel/metadata/data/CoordinateData.java
  29. 8
      src/main/java/com/alibaba/excel/metadata/data/DataFormatData.java
  30. 8
      src/main/java/com/alibaba/excel/metadata/data/FormulaData.java
  31. 7
      src/main/java/com/alibaba/excel/metadata/data/HyperlinkData.java
  32. 7
      src/main/java/com/alibaba/excel/metadata/data/ImageData.java
  33. 8
      src/main/java/com/alibaba/excel/metadata/data/ReadCellData.java
  34. 12
      src/main/java/com/alibaba/excel/metadata/data/RichTextStringData.java
  35. 13
      src/main/java/com/alibaba/excel/metadata/data/WriteCellData.java
  36. 5
      src/main/java/com/alibaba/excel/metadata/format/DataFormatter.java
  37. 8
      src/main/java/com/alibaba/excel/metadata/property/DateTimeFormatProperty.java
  38. 8
      src/main/java/com/alibaba/excel/metadata/property/ExcelContentProperty.java
  39. 8
      src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java
  40. 8
      src/main/java/com/alibaba/excel/metadata/property/FontProperty.java
  41. 8
      src/main/java/com/alibaba/excel/metadata/property/StyleProperty.java
  42. 4
      src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java
  43. 8
      src/main/java/com/alibaba/excel/read/metadata/ReadBasicParameter.java
  44. 8
      src/main/java/com/alibaba/excel/read/metadata/ReadWorkbook.java
  45. 8
      src/main/java/com/alibaba/excel/read/metadata/holder/AbstractReadHolder.java
  46. 8
      src/main/java/com/alibaba/excel/read/metadata/holder/ReadSheetHolder.java
  47. 8
      src/main/java/com/alibaba/excel/read/metadata/holder/ReadWorkbookHolder.java
  48. 8
      src/main/java/com/alibaba/excel/read/metadata/holder/csv/CsvReadSheetHolder.java
  49. 8
      src/main/java/com/alibaba/excel/read/metadata/holder/csv/CsvReadWorkbookHolder.java
  50. 39
      src/main/java/com/alibaba/excel/read/metadata/holder/xlsx/XlsxReadSheetHolder.java
  51. 54
      src/main/java/com/alibaba/excel/read/metadata/holder/xlsx/XlsxReadWorkbookHolder.java
  52. 31
      src/main/java/com/alibaba/excel/util/ClassUtils.java
  53. 8
      src/main/java/com/alibaba/excel/util/ConverterUtils.java
  54. 61
      src/main/java/com/alibaba/excel/util/PositionUtils.java
  55. 8
      src/main/java/com/alibaba/excel/util/StyleUtil.java
  56. 285
      src/main/java/com/alibaba/excel/util/WriteHandlerUtils.java
  57. 177
      src/main/java/com/alibaba/excel/write/executor/AbstractExcelWriteExecutor.java
  58. 96
      src/main/java/com/alibaba/excel/write/executor/ExcelWriteAddExecutor.java
  59. 165
      src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java
  60. 67
      src/main/java/com/alibaba/excel/write/handler/chain/CellHandlerExecutionChain.java
  61. 60
      src/main/java/com/alibaba/excel/write/handler/chain/RowHandlerExecutionChain.java
  62. 52
      src/main/java/com/alibaba/excel/write/handler/chain/SheetHandlerExecutionChain.java
  63. 61
      src/main/java/com/alibaba/excel/write/handler/chain/WorkbookHandlerExecutionChain.java
  64. 59
      src/main/java/com/alibaba/excel/write/handler/context/CellWriteHandlerContext.java
  65. 8
      src/main/java/com/alibaba/excel/write/handler/context/RowWriteHandlerContext.java
  66. 8
      src/main/java/com/alibaba/excel/write/handler/context/SheetWriteHandlerContext.java
  67. 8
      src/main/java/com/alibaba/excel/write/handler/context/WorkbookWriteHandlerContext.java
  68. 10
      src/main/java/com/alibaba/excel/write/handler/impl/FillStyleCellWriteHandler.java
  69. 8
      src/main/java/com/alibaba/excel/write/metadata/WriteBasicParameter.java
  70. 8
      src/main/java/com/alibaba/excel/write/metadata/WriteSheet.java
  71. 8
      src/main/java/com/alibaba/excel/write/metadata/WriteTable.java
  72. 8
      src/main/java/com/alibaba/excel/write/metadata/WriteWorkbook.java
  73. 8
      src/main/java/com/alibaba/excel/write/metadata/fill/AnalysisCell.java
  74. 8
      src/main/java/com/alibaba/excel/write/metadata/fill/FillConfig.java
  75. 185
      src/main/java/com/alibaba/excel/write/metadata/holder/AbstractWriteHolder.java
  76. 18
      src/main/java/com/alibaba/excel/write/metadata/holder/WriteHolder.java
  77. 6
      src/main/java/com/alibaba/excel/write/metadata/holder/WriteSheetHolder.java
  78. 8
      src/main/java/com/alibaba/excel/write/metadata/holder/WriteTableHolder.java
  79. 27
      src/main/java/com/alibaba/excel/write/metadata/holder/WriteWorkbookHolder.java
  80. 8
      src/main/java/com/alibaba/excel/write/metadata/style/WriteCellStyle.java
  81. 8
      src/main/java/com/alibaba/excel/write/metadata/style/WriteFont.java
  82. 19
      src/main/java/com/alibaba/excel/write/property/ExcelWriteHeadProperty.java
  83. 8
      src/main/java/com/alibaba/excel/write/style/HorizontalCellStyleStrategy.java
  84. 16
      src/test/java/com/alibaba/easyexcel/test/core/annotation/AnnotationData.java
  85. 19
      src/test/java/com/alibaba/easyexcel/test/core/annotation/AnnotationDataTest.java
  86. 8
      src/test/java/com/alibaba/easyexcel/test/core/annotation/AnnotationIndexAndNameData.java
  87. 8
      src/test/java/com/alibaba/easyexcel/test/core/celldata/CellDataReadData.java
  88. 8
      src/test/java/com/alibaba/easyexcel/test/core/celldata/CellDataWriteData.java
  89. 8
      src/test/java/com/alibaba/easyexcel/test/core/converter/ConverterReadData.java
  90. 8
      src/test/java/com/alibaba/easyexcel/test/core/converter/ConverterWriteData.java
  91. 8
      src/test/java/com/alibaba/easyexcel/test/core/converter/ImageData.java
  92. 8
      src/test/java/com/alibaba/easyexcel/test/core/converter/ReadAllConverterData.java
  93. 8
      src/test/java/com/alibaba/easyexcel/test/core/dataformat/DateFormatData.java
  94. 8
      src/test/java/com/alibaba/easyexcel/test/core/encrypt/EncryptData.java
  95. 8
      src/test/java/com/alibaba/easyexcel/test/core/exception/ExceptionData.java
  96. 8
      src/test/java/com/alibaba/easyexcel/test/core/excludeorinclude/ExcludeOrIncludeData.java
  97. 8
      src/test/java/com/alibaba/easyexcel/test/core/extra/ExtraData.java
  98. 8
      src/test/java/com/alibaba/easyexcel/test/core/fill/FillData.java
  99. 8
      src/test/java/com/alibaba/easyexcel/test/core/fill/style/FillStyleAnnotatedData.java
  100. 8
      src/test/java/com/alibaba/easyexcel/test/core/fill/style/FillStyleData.java
  101. Some files were not shown because too many files have changed in this diff Show More

4
README.md

@ -21,7 +21,7 @@ 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左右内存,改用easyexcel可以降低到几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左右内存,改用easyexcel可以降低到几M,并且再大的excel也不会出现内存溢出;03版依赖POI的sax模式,在上层做了模型转换的封装,让使用者更加简单方便
## 64M内存1分钟内读取75M(46W行25列)的Excel ## 64M内存20秒内读取75M(46W行25列)的Excel(3.0.2+版本)
当然还有极速模式能更快,但是内存占用会在100M多一点 当然还有极速模式能更快,但是内存占用会在100M多一点
![img](img/readme/large.png) ![img](img/readme/large.png)
@ -41,7 +41,7 @@ Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都
<dependency> <dependency>
<groupId>com.alibaba</groupId> <groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId> <artifactId>easyexcel</artifactId>
<version>3.0.1</version> <version>3.0.2</version>
</dependency> </dependency>
``` ```

BIN
img/readme/large.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 57 KiB

2
pom.xml

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

6
src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java

@ -86,9 +86,9 @@ public class XlsxSaxAnalyser implements ExcelReadExecutor {
// set style table // set style table
setStylesTable(xlsxReadWorkbookHolder, xssfReader); setStylesTable(xlsxReadWorkbookHolder, xssfReader);
sheetList = new ArrayList<ReadSheet>(); sheetList = new ArrayList<>();
sheetMap = new HashMap<Integer, InputStream>(); sheetMap = new HashMap<>();
commentsTableMap = new HashMap<Integer, CommentsTable>(); commentsTableMap = new HashMap<>();
XSSFReader.SheetIterator ite = (XSSFReader.SheetIterator)xssfReader.getSheetsData(); XSSFReader.SheetIterator ite = (XSSFReader.SheetIterator)xssfReader.getSheetsData();
int index = 0; int index = 0;
if (!ite.hasNext()) { if (!ite.hasNext()) {

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

@ -2,19 +2,15 @@ package com.alibaba.excel.analysis.v07.handlers;
import java.math.BigDecimal; import java.math.BigDecimal;
import com.alibaba.excel.constant.BuiltinFormats;
import com.alibaba.excel.constant.ExcelXmlConstants; import com.alibaba.excel.constant.ExcelXmlConstants;
import com.alibaba.excel.context.xlsx.XlsxReadContext; import com.alibaba.excel.context.xlsx.XlsxReadContext;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.data.DataFormatData;
import com.alibaba.excel.metadata.data.ReadCellData; import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.read.metadata.holder.xlsx.XlsxReadSheetHolder; import com.alibaba.excel.read.metadata.holder.xlsx.XlsxReadSheetHolder;
import com.alibaba.excel.util.BooleanUtils; import com.alibaba.excel.util.BooleanUtils;
import com.alibaba.excel.util.PositionUtils; import com.alibaba.excel.util.PositionUtils;
import com.alibaba.excel.util.StringUtils; import com.alibaba.excel.util.StringUtils;
import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.xml.sax.Attributes; import org.xml.sax.Attributes;
/** /**
@ -51,17 +47,9 @@ public class CellTagHandler extends AbstractXlsxTagHandler {
} else { } else {
dateFormatIndexInteger = Integer.parseInt(dateFormatIndex); dateFormatIndexInteger = Integer.parseInt(dateFormatIndex);
} }
StylesTable stylesTable = xlsxReadContext.xlsxReadWorkbookHolder().getStylesTable();
if (stylesTable == null) { xlsxReadSheetHolder.getTempCellData().setDataFormatData(
return; xlsxReadContext.xlsxReadWorkbookHolder().dataFormatData(dateFormatIndexInteger));
}
XSSFCellStyle xssfCellStyle = stylesTable.getStyleAt(dateFormatIndexInteger);
short dataFormat = xssfCellStyle.getDataFormat();
DataFormatData dataFormatData = new DataFormatData();
dataFormatData.setIndex(dataFormat);
dataFormatData.setFormat(BuiltinFormats.getBuiltinFormat(dataFormat,
xssfCellStyle.getDataFormatString(), xlsxReadSheetHolder.getGlobalConfiguration().getLocale()));
xlsxReadSheetHolder.getTempCellData().setDataFormatData(dataFormatData);
} }
@Override @Override

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

@ -15,10 +15,15 @@ import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.util.ClassUtils; import com.alibaba.excel.util.ClassUtils;
import com.alibaba.excel.util.DateUtils; import com.alibaba.excel.util.DateUtils;
import com.alibaba.excel.util.FileUtils; import com.alibaba.excel.util.FileUtils;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.util.NumberDataFormatterUtils; import com.alibaba.excel.util.NumberDataFormatterUtils;
import com.alibaba.excel.util.StringUtils; import com.alibaba.excel.util.StringUtils;
import com.alibaba.excel.util.WorkBookUtil; import com.alibaba.excel.util.WorkBookUtil;
import com.alibaba.excel.util.WriteHandlerUtils; import com.alibaba.excel.util.WriteHandlerUtils;
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
import com.alibaba.excel.write.handler.context.RowWriteHandlerContext;
import com.alibaba.excel.write.handler.context.SheetWriteHandlerContext;
import com.alibaba.excel.write.handler.context.WorkbookWriteHandlerContext;
import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.WriteTable; import com.alibaba.excel.write.metadata.WriteTable;
import com.alibaba.excel.write.metadata.WriteWorkbook; import com.alibaba.excel.write.metadata.WriteWorkbook;
@ -83,13 +88,16 @@ public class WriteContextImpl implements WriteContext {
LOGGER.debug("Begin to Initialization 'WriteContextImpl'"); LOGGER.debug("Begin to Initialization 'WriteContextImpl'");
} }
initCurrentWorkbookHolder(writeWorkbook); initCurrentWorkbookHolder(writeWorkbook);
WriteHandlerUtils.beforeWorkbookCreate(this);
WorkbookWriteHandlerContext workbookWriteHandlerContext = WriteHandlerUtils.createWorkbookWriteHandlerContext(
this);
WriteHandlerUtils.beforeWorkbookCreate(workbookWriteHandlerContext);
try { try {
WorkBookUtil.createWorkBook(writeWorkbookHolder); WorkBookUtil.createWorkBook(writeWorkbookHolder);
} catch (Exception e) { } catch (Exception e) {
throw new ExcelGenerateException("Create workbook failure", e); throw new ExcelGenerateException("Create workbook failure", e);
} }
WriteHandlerUtils.afterWorkbookCreate(this); WriteHandlerUtils.afterWorkbookCreate(workbookWriteHandlerContext);
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Initialization 'WriteContextImpl' complete"); LOGGER.debug("Initialization 'WriteContextImpl' complete");
} }
@ -118,8 +126,10 @@ public class WriteContextImpl implements WriteContext {
initCurrentSheetHolder(writeSheet); initCurrentSheetHolder(writeSheet);
// Workbook handler need to supplementary execution // Workbook handler need to supplementary execution
WriteHandlerUtils.beforeWorkbookCreate(this, true); WorkbookWriteHandlerContext workbookWriteHandlerContext = WriteHandlerUtils.createWorkbookWriteHandlerContext(
WriteHandlerUtils.afterWorkbookCreate(this, true); this);
WriteHandlerUtils.beforeWorkbookCreate(workbookWriteHandlerContext, true);
WriteHandlerUtils.afterWorkbookCreate(workbookWriteHandlerContext, true);
// Initialization current sheet // Initialization current sheet
initSheet(writeType); initSheet(writeType);
@ -162,7 +172,8 @@ public class WriteContextImpl implements WriteContext {
} }
private void initSheet(WriteTypeEnum writeType) { private void initSheet(WriteTypeEnum writeType) {
WriteHandlerUtils.beforeSheetCreate(this); SheetWriteHandlerContext sheetWriteHandlerContext = WriteHandlerUtils.createSheetWriteHandlerContext(this);
WriteHandlerUtils.beforeSheetCreate(sheetWriteHandlerContext);
Sheet currentSheet; Sheet currentSheet;
try { try {
if (writeSheetHolder.getSheetNo() != null) { if (writeSheetHolder.getSheetNo() != null) {
@ -192,7 +203,7 @@ public class WriteContextImpl implements WriteContext {
currentSheet = createSheet(); currentSheet = createSheet();
} }
writeSheetHolder.setSheet(currentSheet); writeSheetHolder.setSheet(currentSheet);
WriteHandlerUtils.afterSheetCreate(this); WriteHandlerUtils.afterSheetCreate(sheetWriteHandlerContext);
if (WriteTypeEnum.ADD.equals(writeType)) { if (WriteTypeEnum.ADD.equals(writeType)) {
// Initialization head // Initialization head
initHead(writeSheetHolder.excelWriteHeadProperty()); initHead(writeSheetHolder.excelWriteHeadProperty());
@ -226,11 +237,17 @@ public class WriteContextImpl implements WriteContext {
} }
for (int relativeRowIndex = 0, i = newRowIndex; i < excelWriteHeadProperty.getHeadRowNumber() for (int relativeRowIndex = 0, i = newRowIndex; i < excelWriteHeadProperty.getHeadRowNumber()
+ newRowIndex; i++, relativeRowIndex++) { + newRowIndex; i++, relativeRowIndex++) {
WriteHandlerUtils.beforeRowCreate(this, newRowIndex, relativeRowIndex, Boolean.TRUE);
RowWriteHandlerContext rowWriteHandlerContext = WriteHandlerUtils.createRowWriteHandlerContext(this,
newRowIndex, relativeRowIndex, Boolean.TRUE);
WriteHandlerUtils.beforeRowCreate(rowWriteHandlerContext);
Row row = WorkBookUtil.createRow(writeSheetHolder.getSheet(), i); Row row = WorkBookUtil.createRow(writeSheetHolder.getSheet(), i);
WriteHandlerUtils.afterRowCreate(this, row, relativeRowIndex, Boolean.TRUE); rowWriteHandlerContext.setRow(row);
addOneRowOfHeadDataToExcel(row, excelWriteHeadProperty.getHeadMap(), relativeRowIndex);
WriteHandlerUtils.afterRowDispose(this, row, relativeRowIndex, Boolean.TRUE); WriteHandlerUtils.afterRowCreate(rowWriteHandlerContext);
addOneRowOfHeadDataToExcel(row, i, excelWriteHeadProperty.getHeadMap(), relativeRowIndex);
WriteHandlerUtils.afterRowDispose(rowWriteHandlerContext);
} }
} }
@ -242,25 +259,29 @@ public class WriteContextImpl implements WriteContext {
} }
} }
private void addOneRowOfHeadDataToExcel(Row row, Map<Integer, Head> headMap, int relativeRowIndex) { private void addOneRowOfHeadDataToExcel(Row row, Integer rowIndex, Map<Integer, Head> headMap,
int relativeRowIndex) {
for (Map.Entry<Integer, Head> entry : headMap.entrySet()) { for (Map.Entry<Integer, Head> entry : headMap.entrySet()) {
Head head = entry.getValue(); Head head = entry.getValue();
int columnIndex = entry.getKey(); int columnIndex = entry.getKey();
ExcelContentProperty excelContentProperty = ClassUtils.declaredExcelContentProperty(null, ExcelContentProperty excelContentProperty = ClassUtils.declaredExcelContentProperty(null,
currentWriteHolder.excelWriteHeadProperty().getHeadClazz(), head.getFieldName()); currentWriteHolder.excelWriteHeadProperty().getHeadClazz(), head.getFieldName());
WriteHandlerUtils.beforeCellCreate(this, row, head, columnIndex, relativeRowIndex, Boolean.TRUE, CellWriteHandlerContext cellWriteHandlerContext = WriteHandlerUtils.createCellWriteHandlerContext(this, row,
excelContentProperty); rowIndex, head, columnIndex, relativeRowIndex, Boolean.TRUE, excelContentProperty);
WriteHandlerUtils.beforeCellCreate(cellWriteHandlerContext);
Cell cell = row.createCell(columnIndex); Cell cell = row.createCell(columnIndex);
cellWriteHandlerContext.setCell(cell);
WriteHandlerUtils.afterCellCreate(this, cell, head, relativeRowIndex, Boolean.TRUE, excelContentProperty); WriteHandlerUtils.afterCellCreate(cellWriteHandlerContext);
WriteCellData<String> writeCellData = new WriteCellData<>(head.getHeadNameList().get(relativeRowIndex)); WriteCellData<String> writeCellData = new WriteCellData<>(head.getHeadNameList().get(relativeRowIndex));
cell.setCellValue(writeCellData.getStringValue()); cell.setCellValue(writeCellData.getStringValue());
cellWriteHandlerContext.setCellDataList(ListUtils.newArrayList(writeCellData));
cellWriteHandlerContext.setFirstCellData(writeCellData);
WriteHandlerUtils.afterCellDispose(this, writeCellData, cell, head, relativeRowIndex, Boolean.TRUE, WriteHandlerUtils.afterCellDispose(cellWriteHandlerContext);
excelContentProperty);
} }
} }
@ -288,10 +309,14 @@ public class WriteContextImpl implements WriteContext {
initCurrentTableHolder(writeTable); initCurrentTableHolder(writeTable);
// Workbook and sheet handler need to supplementary execution // Workbook and sheet handler need to supplementary execution
WriteHandlerUtils.beforeWorkbookCreate(this, true); WorkbookWriteHandlerContext workbookWriteHandlerContext = WriteHandlerUtils.createWorkbookWriteHandlerContext(
WriteHandlerUtils.afterWorkbookCreate(this, true); this);
WriteHandlerUtils.beforeSheetCreate(this, true); WriteHandlerUtils.beforeWorkbookCreate(workbookWriteHandlerContext, true);
WriteHandlerUtils.afterSheetCreate(this, true); WriteHandlerUtils.afterWorkbookCreate(workbookWriteHandlerContext, true);
SheetWriteHandlerContext sheetWriteHandlerContext = WriteHandlerUtils.createSheetWriteHandlerContext(this);
WriteHandlerUtils.beforeSheetCreate(sheetWriteHandlerContext, true);
WriteHandlerUtils.afterSheetCreate(sheetWriteHandlerContext, true);
initHead(writeTableHolder.excelWriteHeadProperty()); initHead(writeTableHolder.excelWriteHeadProperty());
} }
@ -331,7 +356,7 @@ public class WriteContextImpl implements WriteContext {
return; return;
} }
finished = true; finished = true;
WriteHandlerUtils.afterWorkbookDispose(this); WriteHandlerUtils.afterWorkbookDispose(writeWorkbookHolder.getWorkbookWriteHandlerContext());
if (writeWorkbookHolder == null) { if (writeWorkbookHolder == null) {
return; return;
} }

51
src/main/java/com/alibaba/excel/converters/ConverterKeyBuild.java

@ -5,6 +5,11 @@ import java.util.Map;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.util.MapUtils; import com.alibaba.excel.util.MapUtils;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* Converter unique key.Consider that you can just use class as the key. * Converter unique key.Consider that you can just use class as the key.
* *
@ -12,33 +17,37 @@ import com.alibaba.excel.util.MapUtils;
*/ */
public class ConverterKeyBuild { public class ConverterKeyBuild {
private static final Map<String, String> BOXING_MAP = MapUtils.newHashMap(); private static final Map<Class<?>, Class<?>> BOXING_MAP = MapUtils.newHashMap();
static { static {
BOXING_MAP.put(int.class.getName(), Integer.class.getName()); BOXING_MAP.put(int.class, Integer.class);
BOXING_MAP.put(byte.class.getName(), Byte.class.getName()); BOXING_MAP.put(byte.class, Byte.class);
BOXING_MAP.put(long.class.getName(), Long.class.getName()); BOXING_MAP.put(long.class, Long.class);
BOXING_MAP.put(double.class.getName(), Double.class.getName()); BOXING_MAP.put(double.class, Double.class);
BOXING_MAP.put(float.class.getName(), Float.class.getName()); BOXING_MAP.put(float.class, Float.class);
BOXING_MAP.put(char.class.getName(), Character.class.getName()); BOXING_MAP.put(char.class, Character.class);
BOXING_MAP.put(short.class.getName(), Short.class.getName()); BOXING_MAP.put(short.class, Short.class);
BOXING_MAP.put(boolean.class.getName(), Boolean.class.getName()); BOXING_MAP.put(boolean.class, Boolean.class);
} }
public static String buildKey(Class<?> clazz) { public static ConverterKey buildKey(Class<?> clazz) {
String className = clazz.getName(); return buildKey(clazz, null);
String boxingClassName = BOXING_MAP.get(clazz.getName());
if (boxingClassName == null) {
return className;
}
return boxingClassName;
} }
public static String buildKey(Class<?> clazz, CellDataTypeEnum cellDataTypeEnum) { public static ConverterKey buildKey(Class<?> clazz, CellDataTypeEnum cellDataTypeEnum) {
String key = buildKey(clazz); Class<?> boxingClass = BOXING_MAP.get(clazz);
if (cellDataTypeEnum == null) { if (boxingClass != null) {
return key; return new ConverterKey(boxingClass, cellDataTypeEnum);
} }
return key + "-" + cellDataTypeEnum; return new ConverterKey(clazz, cellDataTypeEnum);
}
@Getter
@Setter
@EqualsAndHashCode
@AllArgsConstructor
public static class ConverterKey {
private Class<?> clazz;
private CellDataTypeEnum cellDataTypeEnum;
} }
} }

11
src/main/java/com/alibaba/excel/converters/DefaultConverterLoader.java

@ -2,6 +2,7 @@ package com.alibaba.excel.converters;
import java.util.Map; import java.util.Map;
import com.alibaba.excel.converters.ConverterKeyBuild.ConverterKey;
import com.alibaba.excel.converters.bigdecimal.BigDecimalBooleanConverter; import com.alibaba.excel.converters.bigdecimal.BigDecimalBooleanConverter;
import com.alibaba.excel.converters.bigdecimal.BigDecimalNumberConverter; import com.alibaba.excel.converters.bigdecimal.BigDecimalNumberConverter;
import com.alibaba.excel.converters.bigdecimal.BigDecimalStringConverter; import com.alibaba.excel.converters.bigdecimal.BigDecimalStringConverter;
@ -52,8 +53,8 @@ import com.alibaba.excel.util.MapUtils;
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
public class DefaultConverterLoader { public class DefaultConverterLoader {
private static Map<String, Converter<?>> defaultWriteConverter; private static Map<ConverterKey, Converter<?>> defaultWriteConverter;
private static Map<String, Converter<?>> allConverter; private static Map<ConverterKey, Converter<?>> allConverter;
static { static {
initDefaultWriteConverter(); initDefaultWriteConverter();
@ -153,7 +154,7 @@ public class DefaultConverterLoader {
* *
* @return * @return
*/ */
public static Map<String, Converter<?>> loadDefaultWriteConverter() { public static Map<ConverterKey, Converter<?>> loadDefaultWriteConverter() {
return defaultWriteConverter; return defaultWriteConverter;
} }
@ -171,7 +172,7 @@ public class DefaultConverterLoader {
* *
* @return * @return
*/ */
public static Map<String, Converter<?>> loadDefaultReadConverter() { public static Map<ConverterKey, Converter<?>> loadDefaultReadConverter() {
return loadAllConverter(); return loadAllConverter();
} }
@ -180,7 +181,7 @@ public class DefaultConverterLoader {
* *
* @return * @return
*/ */
public static Map<String, Converter<?>> loadAllConverter() { public static Map<ConverterKey, Converter<?>> loadAllConverter() {
return allConverter; return allConverter;
} }

8
src/main/java/com/alibaba/excel/converters/ReadConverterContext.java

@ -5,14 +5,18 @@ import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* read converter context * read converter context
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
@AllArgsConstructor @AllArgsConstructor
public class ReadConverterContext<T> { public class ReadConverterContext<T> {
/** /**

8
src/main/java/com/alibaba/excel/converters/WriteConverterContext.java

@ -4,15 +4,19 @@ import com.alibaba.excel.context.WriteContext;
import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter;
/** /**
* write converter context * write converter context
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class WriteConverterContext<T> { public class WriteConverterContext<T> {

12
src/main/java/com/alibaba/excel/exception/ExcelDataConvertException.java

@ -4,14 +4,18 @@ import com.alibaba.excel.metadata.data.CellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.write.builder.ExcelWriterBuilder; import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* Data convert exception * Data convert exception
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class ExcelDataConvertException extends RuntimeException { public class ExcelDataConvertException extends RuntimeException {
/** /**
* NotNull. * NotNull.
@ -32,7 +36,7 @@ public class ExcelDataConvertException extends RuntimeException {
*/ */
private ExcelContentProperty excelContentProperty; private ExcelContentProperty excelContentProperty;
public ExcelDataConvertException(Integer rowIndex, Integer columnIndex, CellData cellData, public ExcelDataConvertException(Integer rowIndex, Integer columnIndex, CellData<?> cellData,
ExcelContentProperty excelContentProperty, String message) { ExcelContentProperty excelContentProperty, String message) {
super(message); super(message);
this.rowIndex = rowIndex; this.rowIndex = rowIndex;
@ -41,7 +45,7 @@ public class ExcelDataConvertException extends RuntimeException {
this.excelContentProperty = excelContentProperty; this.excelContentProperty = excelContentProperty;
} }
public ExcelDataConvertException(Integer rowIndex, Integer columnIndex, CellData cellData, public ExcelDataConvertException(Integer rowIndex, Integer columnIndex, CellData<?> cellData,
ExcelContentProperty excelContentProperty, String message, Throwable cause) { ExcelContentProperty excelContentProperty, String message, Throwable cause) {
super(message, cause); super(message, cause);
this.rowIndex = rowIndex; this.rowIndex = rowIndex;

36
src/main/java/com/alibaba/excel/exception/ExcelWriteDataConvertException.java

@ -0,0 +1,36 @@
package com.alibaba.excel.exception;
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* Data convert exception
*
* @author Jiaju Zhuang
*/
@Getter
@Setter
@EqualsAndHashCode
public class ExcelWriteDataConvertException extends ExcelDataConvertException {
/**
* handler.
*/
private CellWriteHandlerContext cellWriteHandlerContext;
public ExcelWriteDataConvertException(CellWriteHandlerContext cellWriteHandlerContext, String message) {
super(cellWriteHandlerContext.getRowIndex(), cellWriteHandlerContext.getColumnIndex(),
cellWriteHandlerContext.getFirstCellData(), cellWriteHandlerContext.getExcelContentProperty(), message);
this.cellWriteHandlerContext = cellWriteHandlerContext;
}
public ExcelWriteDataConvertException(CellWriteHandlerContext cellWriteHandlerContext, String message,
Throwable cause) {
super(cellWriteHandlerContext.getRowIndex(), cellWriteHandlerContext.getColumnIndex(),
cellWriteHandlerContext.getFirstCellData(), cellWriteHandlerContext.getExcelContentProperty(), message,
cause);
this.cellWriteHandlerContext = cellWriteHandlerContext;
}
}

8
src/main/java/com/alibaba/excel/metadata/AbstractCell.java

@ -1,13 +1,17 @@
package com.alibaba.excel.metadata; package com.alibaba.excel.metadata;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* cell * cell
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
**/ **/
@Data @Getter
@Setter
@EqualsAndHashCode
public class AbstractCell implements Cell { public class AbstractCell implements Cell {
/** /**
* Row index * Row index

13
src/main/java/com/alibaba/excel/metadata/AbstractHolder.java

@ -4,16 +4,21 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.converters.ConverterKeyBuild.ConverterKey;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter;
/** /**
* Write/read holder * Write/read holder
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
@NoArgsConstructor @NoArgsConstructor
public abstract class AbstractHolder implements ConfigurationHolder { public abstract class AbstractHolder implements ConfigurationHolder {
/** /**
@ -38,7 +43,7 @@ public abstract class AbstractHolder implements ConfigurationHolder {
* <p> * <p>
* Write key: * Write key:
*/ */
private Map<String, Converter<?>> converterMap; private Map<ConverterKey, Converter<?>> converterMap;
public AbstractHolder(BasicParameter basicParameter, AbstractHolder prentAbstractHolder) { public AbstractHolder(BasicParameter basicParameter, AbstractHolder prentAbstractHolder) {
this.newInitialization = Boolean.TRUE; this.newInitialization = Boolean.TRUE;
@ -81,7 +86,7 @@ public abstract class AbstractHolder implements ConfigurationHolder {
} }
@Override @Override
public Map<String, Converter<?>> converterMap() { public Map<ConverterKey, Converter<?>> converterMap() {
return getConverterMap(); return getConverterMap();
} }

8
src/main/java/com/alibaba/excel/metadata/BasicParameter.java

@ -5,14 +5,18 @@ import java.util.Locale;
import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.Converter;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* Basic parameter * Basic parameter
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
**/ **/
@Data @Getter
@Setter
@EqualsAndHashCode
public class BasicParameter { public class BasicParameter {
/** /**
* You can only choose one of the {@link BasicParameter#head} and {@link BasicParameter#clazz} * You can only choose one of the {@link BasicParameter#head} and {@link BasicParameter#clazz}

8
src/main/java/com/alibaba/excel/metadata/CellRange.java

@ -1,11 +1,15 @@
package com.alibaba.excel.metadata; package com.alibaba.excel.metadata;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* @author jipengfei * @author jipengfei
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class CellRange { public class CellRange {
private int firstRow; private int firstRow;

5
src/main/java/com/alibaba/excel/metadata/ConfigurationHolder.java

@ -3,9 +3,9 @@ package com.alibaba.excel.metadata;
import java.util.Map; import java.util.Map;
import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.converters.ConverterKeyBuild.ConverterKey;
/** /**
*
* Get the corresponding holder * Get the corresponding holder
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
@ -13,7 +13,6 @@ import com.alibaba.excel.converters.Converter;
public interface ConfigurationHolder extends Holder { public interface ConfigurationHolder extends Holder {
/** /**
*
* Record whether it's new or from cache * Record whether it's new or from cache
* *
* @return Record whether it's new or from cache * @return Record whether it's new or from cache
@ -32,5 +31,5 @@ public interface ConfigurationHolder extends Holder {
* *
* @return Converter * @return Converter
*/ */
Map<String, Converter<?>> converterMap(); Map<ConverterKey, Converter<?>> converterMap();
} }

8
src/main/java/com/alibaba/excel/metadata/GlobalConfiguration.java

@ -2,14 +2,18 @@ package com.alibaba.excel.metadata;
import java.util.Locale; import java.util.Locale;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* Global configuration * Global configuration
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class GlobalConfiguration { public class GlobalConfiguration {
/** /**
* Automatic trim includes sheet name and content * Automatic trim includes sheet name and content

8
src/main/java/com/alibaba/excel/metadata/Head.java

@ -10,14 +10,18 @@ import com.alibaba.excel.metadata.property.FontProperty;
import com.alibaba.excel.metadata.property.LoopMergeProperty; import com.alibaba.excel.metadata.property.LoopMergeProperty;
import com.alibaba.excel.metadata.property.StyleProperty; import com.alibaba.excel.metadata.property.StyleProperty;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* excel head * excel head
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
**/ **/
@Data @Getter
@Setter
@EqualsAndHashCode
public class Head { public class Head {
/** /**
* Column index of head * Column index of head

6
src/main/java/com/alibaba/excel/metadata/csv/CsvCell.java

@ -10,7 +10,7 @@ import com.alibaba.excel.enums.NumericCellTypeEnum;
import com.alibaba.excel.metadata.data.FormulaData; import com.alibaba.excel.metadata.data.FormulaData;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.apache.poi.ss.SpreadsheetVersion; import org.apache.poi.ss.SpreadsheetVersion;
@ -29,7 +29,9 @@ import org.apache.poi.ss.util.CellRangeAddress;
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class CsvCell extends CellBase { public class CsvCell extends CellBase {
/** /**

8
src/main/java/com/alibaba/excel/metadata/csv/CsvCellStyle.java

@ -2,7 +2,9 @@ package com.alibaba.excel.metadata.csv;
import com.alibaba.excel.metadata.data.DataFormatData; import com.alibaba.excel.metadata.data.DataFormatData;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.apache.poi.ss.usermodel.BorderStyle; import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Color; import org.apache.poi.ss.usermodel.Color;
@ -16,7 +18,9 @@ import org.apache.poi.ss.usermodel.VerticalAlignment;
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class CsvCellStyle implements CellStyle { public class CsvCellStyle implements CellStyle {
/** /**

8
src/main/java/com/alibaba/excel/metadata/csv/CsvRow.java

@ -3,7 +3,9 @@ package com.alibaba.excel.metadata.csv;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists; import org.apache.commons.compress.utils.Lists;
import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Cell;
@ -17,7 +19,9 @@ import org.apache.poi.ss.usermodel.Sheet;
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class CsvRow implements Row { public class CsvRow implements Row {
/** /**

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

@ -16,7 +16,9 @@ import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.util.NumberDataFormatterUtils; import com.alibaba.excel.util.NumberDataFormatterUtils;
import com.alibaba.excel.util.StringUtils; import com.alibaba.excel.util.StringUtils;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter; import org.apache.commons.csv.CSVPrinter;
import org.apache.poi.ss.usermodel.AutoFilter; import org.apache.poi.ss.usermodel.AutoFilter;
@ -45,7 +47,9 @@ import org.apache.poi.ss.util.PaneInformation;
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class CsvSheet implements Sheet, Closeable { public class CsvSheet implements Sheet, Closeable {
/** /**
* workbook * workbook

8
src/main/java/com/alibaba/excel/metadata/csv/CsvWorkbook.java

@ -6,7 +6,9 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.compress.utils.Lists; import org.apache.commons.compress.utils.Lists;
import org.apache.poi.ss.SpreadsheetVersion; import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.ss.formula.udf.UDFFinder; import org.apache.poi.ss.formula.udf.UDFFinder;
@ -26,7 +28,9 @@ import org.apache.poi.ss.usermodel.Workbook;
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class CsvWorkbook implements Workbook { public class CsvWorkbook implements Workbook {
/** /**
* output * output

8
src/main/java/com/alibaba/excel/metadata/data/CellData.java

@ -6,7 +6,9 @@ import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.AbstractCell; import com.alibaba.excel.metadata.AbstractCell;
import com.alibaba.excel.util.StringUtils; import com.alibaba.excel.util.StringUtils;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* Excel internal cell data. * Excel internal cell data.
@ -15,7 +17,9 @@ import lombok.Data;
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class CellData<T> extends AbstractCell { public class CellData<T> extends AbstractCell {
/** /**
* cell type * cell type

7
src/main/java/com/alibaba/excel/metadata/data/ClientAnchorData.java

@ -1,7 +1,8 @@
package com.alibaba.excel.metadata.data; package com.alibaba.excel.metadata.data;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter; import lombok.Getter;
import lombok.Setter;
import org.apache.poi.ss.usermodel.ClientAnchor; import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.util.Internal; import org.apache.poi.util.Internal;
@ -21,7 +22,9 @@ import org.apache.poi.util.Internal;
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class ClientAnchorData extends CoordinateData { public class ClientAnchorData extends CoordinateData {
/** /**
* top * top

8
src/main/java/com/alibaba/excel/metadata/data/CommentData.java

@ -1,13 +1,17 @@
package com.alibaba.excel.metadata.data; package com.alibaba.excel.metadata.data;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* comment * comment
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class CommentData extends ClientAnchorData { public class CommentData extends ClientAnchorData {
/** /**
* Name of the original comment author * Name of the original comment author

8
src/main/java/com/alibaba/excel/metadata/data/CoordinateData.java

@ -1,13 +1,17 @@
package com.alibaba.excel.metadata.data; package com.alibaba.excel.metadata.data;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* coordinate. * coordinate.
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class CoordinateData { public class CoordinateData {
/** /**
* first row index.Priority is higher than {@link #relativeFirstRowIndex}. * first row index.Priority is higher than {@link #relativeFirstRowIndex}.

8
src/main/java/com/alibaba/excel/metadata/data/DataFormatData.java

@ -2,14 +2,18 @@ package com.alibaba.excel.metadata.data;
import com.alibaba.excel.util.StringUtils; import com.alibaba.excel.util.StringUtils;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* data format * data format
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class DataFormatData { public class DataFormatData {
/** /**
* index * index

8
src/main/java/com/alibaba/excel/metadata/data/FormulaData.java

@ -1,13 +1,17 @@
package com.alibaba.excel.metadata.data; package com.alibaba.excel.metadata.data;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* formula * formula
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class FormulaData { public class FormulaData {
/** /**
* formula * formula

7
src/main/java/com/alibaba/excel/metadata/data/HyperlinkData.java

@ -1,14 +1,17 @@
package com.alibaba.excel.metadata.data; package com.alibaba.excel.metadata.data;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter; import lombok.Getter;
import lombok.Setter;
/** /**
* hyperlink * hyperlink
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class HyperlinkData extends CoordinateData { public class HyperlinkData extends CoordinateData {
/** /**
* Depending on the hyperlink type it can be URL, e-mail, path to a file, etc * Depending on the hyperlink type it can be URL, e-mail, path to a file, etc

7
src/main/java/com/alibaba/excel/metadata/data/ImageData.java

@ -1,14 +1,17 @@
package com.alibaba.excel.metadata.data; package com.alibaba.excel.metadata.data;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter; import lombok.Getter;
import lombok.Setter;
/** /**
* image * image
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class ImageData extends ClientAnchorData { public class ImageData extends ClientAnchorData {
/** /**

8
src/main/java/com/alibaba/excel/metadata/data/ReadCellData.java

@ -4,15 +4,19 @@ import java.math.BigDecimal;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter;
/** /**
* read cell data * read cell data
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
@NoArgsConstructor @NoArgsConstructor
public class ReadCellData<T> extends CellData<T> { public class ReadCellData<T> extends CellData<T> {
/** /**

12
src/main/java/com/alibaba/excel/metadata/data/RichTextStringData.java

@ -6,15 +6,19 @@ import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.write.metadata.style.WriteFont; import com.alibaba.excel.write.metadata.style.WriteFont;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter;
/** /**
* rich text string * rich text string
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
@NoArgsConstructor @NoArgsConstructor
public class RichTextStringData { public class RichTextStringData {
private String textString; private String textString;
@ -25,7 +29,9 @@ public class RichTextStringData {
this.textString = textString; this.textString = textString;
} }
@Data @Getter
@Setter
@EqualsAndHashCode
@AllArgsConstructor @AllArgsConstructor
public static class IntervalFont { public static class IntervalFont {
private Integer startIndex; private Integer startIndex;

13
src/main/java/com/alibaba/excel/metadata/data/WriteCellData.java

@ -8,11 +8,12 @@ import java.util.List;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.util.ListUtils; import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.write.metadata.fill.AnalysisCell;
import com.alibaba.excel.write.metadata.style.WriteCellStyle; import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter;
import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.CellStyle;
/** /**
@ -20,7 +21,9 @@ import org.apache.poi.ss.usermodel.CellStyle;
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
@NoArgsConstructor @NoArgsConstructor
public class WriteCellData<T> extends CellData<T> { public class WriteCellData<T> extends CellData<T> {
/** /**
@ -56,10 +59,6 @@ public class WriteCellData<T> extends CellData<T> {
*/ */
private CellStyle originCellStyle; private CellStyle originCellStyle;
/**
* Only in the case of the fill is not null
*/
private AnalysisCell analysisCell;
public WriteCellData(String stringValue) { public WriteCellData(String stringValue) {
this(CellDataTypeEnum.STRING, stringValue); this(CellDataTypeEnum.STRING, stringValue);

5
src/main/java/com/alibaba/excel/metadata/format/DataFormatter.java

@ -111,6 +111,8 @@ public class DataFormatter {
*/ */
private static final Pattern alternateGrouping = Pattern.compile("([#0]([^.#0])[#0]{3})"); private static final Pattern alternateGrouping = Pattern.compile("([#0]([^.#0])[#0]{3})");
private static final Pattern E_NOTATION_PATTERN = Pattern.compile("E(\\d)");
/** /**
* Cells formatted with a date or time format and which contain invalid date or time values show 255 pound signs * Cells formatted with a date or time format and which contain invalid date or time values show 255 pound signs
* ("#"). * ("#").
@ -644,8 +646,7 @@ public class DataFormatter {
*/ */
private String getFormattedNumberString(BigDecimal data, Short dataFormat, String dataFormatString) { private String getFormattedNumberString(BigDecimal data, Short dataFormat, String dataFormatString) {
Format numberFormat = getFormat(data.doubleValue(), dataFormat, dataFormatString); Format numberFormat = getFormat(data.doubleValue(), dataFormat, dataFormatString);
String formatted = numberFormat.format(data); return E_NOTATION_PATTERN.matcher(numberFormat.format(data)).replaceFirst("E+$1");
return formatted.replaceFirst("E(\\d)", "E+$1"); // to match Excel's E-notation
} }
/** /**

8
src/main/java/com/alibaba/excel/metadata/property/DateTimeFormatProperty.java

@ -3,14 +3,18 @@ package com.alibaba.excel.metadata.property;
import com.alibaba.excel.annotation.format.DateTimeFormat; import com.alibaba.excel.annotation.format.DateTimeFormat;
import com.alibaba.excel.util.BooleanUtils; import com.alibaba.excel.util.BooleanUtils;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* Configuration from annotations * Configuration from annotations
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class DateTimeFormatProperty { public class DateTimeFormatProperty {
private String format; private String format;
private Boolean use1904windowing; private Boolean use1904windowing;

8
src/main/java/com/alibaba/excel/metadata/property/ExcelContentProperty.java

@ -4,12 +4,16 @@ import java.lang.reflect.Field;
import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.Converter;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* @author jipengfei * @author jipengfei
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class ExcelContentProperty { public class ExcelContentProperty {
public static final ExcelContentProperty EMPTY = new ExcelContentProperty(); public static final ExcelContentProperty EMPTY = new ExcelContentProperty();

8
src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java

@ -17,7 +17,9 @@ import com.alibaba.excel.util.MapUtils;
import com.alibaba.excel.util.StringUtils; import com.alibaba.excel.util.StringUtils;
import com.alibaba.excel.write.metadata.holder.AbstractWriteHolder; import com.alibaba.excel.write.metadata.holder.AbstractWriteHolder;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -27,7 +29,9 @@ import org.slf4j.LoggerFactory;
* *
* @author jipengfei * @author jipengfei
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class ExcelHeadProperty { public class ExcelHeadProperty {
private static final Logger LOGGER = LoggerFactory.getLogger(ExcelHeadProperty.class); private static final Logger LOGGER = LoggerFactory.getLogger(ExcelHeadProperty.class);

8
src/main/java/com/alibaba/excel/metadata/property/FontProperty.java

@ -4,7 +4,9 @@ import com.alibaba.excel.annotation.write.style.ContentFontStyle;
import com.alibaba.excel.annotation.write.style.HeadFontStyle; import com.alibaba.excel.annotation.write.style.HeadFontStyle;
import com.alibaba.excel.util.StringUtils; import com.alibaba.excel.util.StringUtils;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.apache.poi.common.usermodel.fonts.FontCharset; import org.apache.poi.common.usermodel.fonts.FontCharset;
import org.apache.poi.hssf.usermodel.HSSFPalette; import org.apache.poi.hssf.usermodel.HSSFPalette;
import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.usermodel.Font;
@ -15,7 +17,9 @@ import org.apache.poi.ss.usermodel.IndexedColors;
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class FontProperty { public class FontProperty {
/** /**
* The name for the font (i.e. Arial) * The name for the font (i.e. Arial)

8
src/main/java/com/alibaba/excel/metadata/property/StyleProperty.java

@ -5,7 +5,9 @@ import com.alibaba.excel.annotation.write.style.HeadStyle;
import com.alibaba.excel.metadata.data.DataFormatData; import com.alibaba.excel.metadata.data.DataFormatData;
import com.alibaba.excel.write.metadata.style.WriteFont; import com.alibaba.excel.write.metadata.style.WriteFont;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.apache.poi.ss.usermodel.BorderStyle; import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.BuiltinFormats; import org.apache.poi.ss.usermodel.BuiltinFormats;
import org.apache.poi.ss.usermodel.FillPatternType; import org.apache.poi.ss.usermodel.FillPatternType;
@ -19,7 +21,9 @@ import org.apache.poi.ss.usermodel.VerticalAlignment;
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class StyleProperty { public class StyleProperty {
/** /**
* Set the data format (must be a valid format). Built in formats are defined at {@link BuiltinFormats}. * Set the data format (must be a valid format). Built in formats are defined at {@link BuiltinFormats}.

4
src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java

@ -91,7 +91,6 @@ public class ModelBuildEventListener implements ReadListener<Map<Integer, ReadCe
"Can not instance class: " + excelReadHeadProperty.getHeadClazz().getName(), e); "Can not instance class: " + excelReadHeadProperty.getHeadClazz().getName(), e);
} }
Map<Integer, Head> headMap = excelReadHeadProperty.getHeadMap(); Map<Integer, Head> headMap = excelReadHeadProperty.getHeadMap();
Map<String, Object> map = MapUtils.newHashMapWithExpectedSize(headMap.size());
BeanMap dataMap = BeanMapUtils.create(resultModel); BeanMap dataMap = BeanMapUtils.create(resultModel);
for (Map.Entry<Integer, Head> entry : headMap.entrySet()) { for (Map.Entry<Integer, Head> entry : headMap.entrySet()) {
Integer index = entry.getKey(); Integer index = entry.getKey();
@ -105,10 +104,9 @@ public class ModelBuildEventListener implements ReadListener<Map<Integer, ReadCe
ClassUtils.declaredExcelContentProperty(dataMap, readSheetHolder.excelReadHeadProperty().getHeadClazz(), ClassUtils.declaredExcelContentProperty(dataMap, readSheetHolder.excelReadHeadProperty().getHeadClazz(),
fieldName), readSheetHolder.converterMap(), context, context.readRowHolder().getRowIndex(), index); fieldName), readSheetHolder.converterMap(), context, context.readRowHolder().getRowIndex(), index);
if (value != null) { if (value != null) {
map.put(fieldName, value); dataMap.put(fieldName, value);
} }
} }
dataMap.putAll(map);
return resultModel; return resultModel;
} }

8
src/main/java/com/alibaba/excel/read/metadata/ReadBasicParameter.java

@ -6,14 +6,18 @@ import java.util.List;
import com.alibaba.excel.metadata.BasicParameter; import com.alibaba.excel.metadata.BasicParameter;
import com.alibaba.excel.read.listener.ReadListener; import com.alibaba.excel.read.listener.ReadListener;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* Read basic parameter * Read basic parameter
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
**/ **/
@Data @Getter
@Setter
@EqualsAndHashCode
public class ReadBasicParameter extends BasicParameter { public class ReadBasicParameter extends BasicParameter {
/** /**
* Count the number of added heads when read sheet. * Count the number of added heads when read sheet.

8
src/main/java/com/alibaba/excel/read/metadata/ReadWorkbook.java

@ -14,14 +14,18 @@ import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.read.listener.ModelBuildEventListener; import com.alibaba.excel.read.listener.ModelBuildEventListener;
import com.alibaba.excel.support.ExcelTypeEnum; import com.alibaba.excel.support.ExcelTypeEnum;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* Workbook * Workbook
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
**/ **/
@Data @Getter
@Setter
@EqualsAndHashCode
public class ReadWorkbook extends ReadBasicParameter { public class ReadWorkbook extends ReadBasicParameter {
/** /**
* Excel type * Excel type

8
src/main/java/com/alibaba/excel/read/metadata/holder/AbstractReadHolder.java

@ -15,15 +15,19 @@ import com.alibaba.excel.read.metadata.ReadWorkbook;
import com.alibaba.excel.read.metadata.property.ExcelReadHeadProperty; import com.alibaba.excel.read.metadata.property.ExcelReadHeadProperty;
import com.alibaba.excel.util.ListUtils; import com.alibaba.excel.util.ListUtils;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter;
/** /**
* Read Holder * Read Holder
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
@NoArgsConstructor @NoArgsConstructor
public abstract class AbstractReadHolder extends AbstractHolder implements ReadHolder { public abstract class AbstractReadHolder extends AbstractHolder implements ReadHolder {
/** /**

8
src/main/java/com/alibaba/excel/read/metadata/holder/ReadSheetHolder.java

@ -9,15 +9,19 @@ import com.alibaba.excel.metadata.CellExtra;
import com.alibaba.excel.metadata.data.ReadCellData; import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.read.metadata.ReadSheet; import com.alibaba.excel.read.metadata.ReadSheet;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter;
/** /**
* sheet holder * sheet holder
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
@NoArgsConstructor @NoArgsConstructor
public class ReadSheetHolder extends AbstractReadHolder { public class ReadSheetHolder extends AbstractReadHolder {

8
src/main/java/com/alibaba/excel/read/metadata/holder/ReadWorkbookHolder.java

@ -19,15 +19,19 @@ import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.excel.read.metadata.ReadWorkbook; import com.alibaba.excel.read.metadata.ReadWorkbook;
import com.alibaba.excel.support.ExcelTypeEnum; import com.alibaba.excel.support.ExcelTypeEnum;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter;
/** /**
* Workbook holder * Workbook holder
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
@NoArgsConstructor @NoArgsConstructor
public class ReadWorkbookHolder extends AbstractReadHolder { public class ReadWorkbookHolder extends AbstractReadHolder {

8
src/main/java/com/alibaba/excel/read/metadata/holder/csv/CsvReadSheetHolder.java

@ -4,14 +4,18 @@ import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.excel.read.metadata.holder.ReadSheetHolder; import com.alibaba.excel.read.metadata.holder.ReadSheetHolder;
import com.alibaba.excel.read.metadata.holder.ReadWorkbookHolder; import com.alibaba.excel.read.metadata.holder.ReadWorkbookHolder;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* sheet holder * sheet holder
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class CsvReadSheetHolder extends ReadSheetHolder { public class CsvReadSheetHolder extends ReadSheetHolder {
public CsvReadSheetHolder(ReadSheet readSheet, ReadWorkbookHolder readWorkbookHolder) { public CsvReadSheetHolder(ReadSheet readSheet, ReadWorkbookHolder readWorkbookHolder) {

8
src/main/java/com/alibaba/excel/read/metadata/holder/csv/CsvReadWorkbookHolder.java

@ -4,7 +4,9 @@ import com.alibaba.excel.read.metadata.ReadWorkbook;
import com.alibaba.excel.read.metadata.holder.ReadWorkbookHolder; import com.alibaba.excel.read.metadata.holder.ReadWorkbookHolder;
import com.alibaba.excel.support.ExcelTypeEnum; import com.alibaba.excel.support.ExcelTypeEnum;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVFormat;
/** /**
@ -12,7 +14,9 @@ import org.apache.commons.csv.CSVFormat;
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class CsvReadWorkbookHolder extends ReadWorkbookHolder { public class CsvReadWorkbookHolder extends ReadWorkbookHolder {
private CSVFormat csvFormat; private CSVFormat csvFormat;

39
src/main/java/com/alibaba/excel/read/metadata/holder/xlsx/XlsxReadSheetHolder.java

@ -7,11 +7,18 @@ import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.excel.read.metadata.holder.ReadSheetHolder; import com.alibaba.excel.read.metadata.holder.ReadSheetHolder;
import com.alibaba.excel.read.metadata.holder.ReadWorkbookHolder; import com.alibaba.excel.read.metadata.holder.ReadWorkbookHolder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* sheet holder * sheet holder
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Getter
@Setter
@EqualsAndHashCode
public class XlsxReadSheetHolder extends ReadSheetHolder { public class XlsxReadSheetHolder extends ReadSheetHolder {
/** /**
* Record the label of the current operation to prevent NPE. * Record the label of the current operation to prevent NPE.
@ -34,36 +41,4 @@ public class XlsxReadSheetHolder extends ReadSheetHolder {
super(readSheet, readWorkbookHolder); super(readSheet, readWorkbookHolder);
this.tagDeque = new LinkedList<String>(); this.tagDeque = new LinkedList<String>();
} }
public Deque<String> getTagDeque() {
return tagDeque;
}
public void setTagDeque(Deque<String> tagDeque) {
this.tagDeque = tagDeque;
}
public Integer getColumnIndex() {
return columnIndex;
}
public void setColumnIndex(Integer columnIndex) {
this.columnIndex = columnIndex;
}
public StringBuilder getTempData() {
return tempData;
}
public void setTempData(StringBuilder tempData) {
this.tempData = tempData;
}
public StringBuilder getTempFormula() {
return tempFormula;
}
public void setTempFormula(StringBuilder tempFormula) {
this.tempFormula = tempFormula;
}
} }

54
src/main/java/com/alibaba/excel/read/metadata/holder/xlsx/XlsxReadWorkbookHolder.java

@ -1,19 +1,31 @@
package com.alibaba.excel.read.metadata.holder.xlsx; package com.alibaba.excel.read.metadata.holder.xlsx;
import javax.xml.parsers.SAXParserFactory; import java.util.Map;
import org.apache.poi.openxml4j.opc.OPCPackage; import javax.xml.parsers.SAXParserFactory;
import org.apache.poi.xssf.model.StylesTable;
import com.alibaba.excel.constant.BuiltinFormats;
import com.alibaba.excel.metadata.data.DataFormatData;
import com.alibaba.excel.read.metadata.ReadWorkbook; import com.alibaba.excel.read.metadata.ReadWorkbook;
import com.alibaba.excel.read.metadata.holder.ReadWorkbookHolder; import com.alibaba.excel.read.metadata.holder.ReadWorkbookHolder;
import com.alibaba.excel.support.ExcelTypeEnum; import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.util.MapUtils;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
/** /**
* Workbook holder * Workbook holder
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Getter
@Setter
@EqualsAndHashCode
public class XlsxReadWorkbookHolder extends ReadWorkbookHolder { public class XlsxReadWorkbookHolder extends ReadWorkbookHolder {
/** /**
* Package * Package
@ -34,34 +46,30 @@ public class XlsxReadWorkbookHolder extends ReadWorkbookHolder {
* Current style information * Current style information
*/ */
private StylesTable stylesTable; private StylesTable stylesTable;
/**
* cache data format
*/
private Map<Integer, DataFormatData> dataFormatDataCache;
public XlsxReadWorkbookHolder(ReadWorkbook readWorkbook) { public XlsxReadWorkbookHolder(ReadWorkbook readWorkbook) {
super(readWorkbook); super(readWorkbook);
this.saxParserFactoryName = readWorkbook.getXlsxSAXParserFactoryName(); this.saxParserFactoryName = readWorkbook.getXlsxSAXParserFactoryName();
setExcelType(ExcelTypeEnum.XLSX); setExcelType(ExcelTypeEnum.XLSX);
dataFormatDataCache = MapUtils.newHashMap();
} }
public OPCPackage getOpcPackage() { public DataFormatData dataFormatData(int dateFormatIndexInteger) {
return opcPackage; return dataFormatDataCache.computeIfAbsent(dateFormatIndexInteger, key -> {
DataFormatData dataFormatData = new DataFormatData();
if (stylesTable == null) {
return null;
} }
XSSFCellStyle xssfCellStyle = stylesTable.getStyleAt(dateFormatIndexInteger);
public void setOpcPackage(OPCPackage opcPackage) { dataFormatData.setIndex(xssfCellStyle.getDataFormat());
this.opcPackage = opcPackage; dataFormatData.setFormat(BuiltinFormats.getBuiltinFormat(dataFormatData.getIndex(),
} xssfCellStyle.getDataFormatString(), globalConfiguration().getLocale()));
return dataFormatData;
public String getSaxParserFactoryName() { });
return saxParserFactoryName;
}
public void setSaxParserFactoryName(String saxParserFactoryName) {
this.saxParserFactoryName = saxParserFactoryName;
}
public StylesTable getStylesTable() {
return stylesTable;
} }
public void setStylesTable(StylesTable stylesTable) {
this.stylesTable = stylesTable;
}
} }

31
src/main/java/com/alibaba/excel/util/ClassUtils.java

@ -31,6 +31,10 @@ import com.alibaba.excel.metadata.property.NumberFormatProperty;
import com.alibaba.excel.metadata.property.StyleProperty; import com.alibaba.excel.metadata.property.StyleProperty;
import com.alibaba.excel.write.metadata.holder.WriteHolder; import com.alibaba.excel.write.metadata.holder.WriteHolder;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import net.sf.cglib.beans.BeanMap; import net.sf.cglib.beans.BeanMap;
/** /**
@ -51,7 +55,7 @@ public class ClassUtils {
/** /**
* The cache configuration information for each of the class * The cache configuration information for each of the class
*/ */
public static final Map<String, ExcelContentProperty> CONTENT_CACHE = new ConcurrentHashMap<>(); public static final Map<ContentPropertyKey, ExcelContentProperty> CONTENT_CACHE = new ConcurrentHashMap<>();
/** /**
* Calculate the configuration information for the class * Calculate the configuration information for the class
@ -117,20 +121,8 @@ public class ClassUtils {
} }
} }
private static String buildKey(Class<?> clazz, Class<?> headClass, String fieldName) { private static ContentPropertyKey buildKey(Class<?> clazz, Class<?> headClass, String fieldName) {
String key = ""; return new ContentPropertyKey(clazz, headClass, fieldName);
if (clazz != null) {
key += clazz.getName();
}
key += "-";
if (headClass != null) {
key += headClass.getName();
}
key += "-";
if (fieldName != null) {
key += fieldName;
}
return key;
} }
private static Map<String, ExcelContentProperty> declaredFieldContentMap(Class<?> clazz) { private static Map<String, ExcelContentProperty> declaredFieldContentMap(Class<?> clazz) {
@ -413,4 +405,13 @@ public class ClassUtils {
} }
} }
@Getter
@Setter
@EqualsAndHashCode
@AllArgsConstructor
public static class ContentPropertyKey {
private Class<?> clazz;
private Class<?> headClass;
private String fieldName;
}
} }

8
src/main/java/com/alibaba/excel/util/ConverterUtils.java

@ -8,10 +8,12 @@ import java.util.Map;
import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.converters.ConverterKeyBuild; import com.alibaba.excel.converters.ConverterKeyBuild;
import com.alibaba.excel.converters.ConverterKeyBuild.ConverterKey;
import com.alibaba.excel.converters.NullableObjectConverter; import com.alibaba.excel.converters.NullableObjectConverter;
import com.alibaba.excel.converters.ReadConverterContext; import com.alibaba.excel.converters.ReadConverterContext;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.exception.ExcelDataConvertException; import com.alibaba.excel.exception.ExcelDataConvertException;
import com.alibaba.excel.metadata.data.CellData;
import com.alibaba.excel.metadata.data.ReadCellData; import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.read.metadata.holder.ReadSheetHolder; import com.alibaba.excel.read.metadata.holder.ReadSheetHolder;
@ -80,7 +82,7 @@ public class ConverterUtils {
* @return * @return
*/ */
public static Object convertToJavaObject(ReadCellData<?> cellData, Field field, public static Object convertToJavaObject(ReadCellData<?> cellData, Field field,
ExcelContentProperty contentProperty, Map<String, Converter<?>> converterMap, AnalysisContext context, ExcelContentProperty contentProperty, Map<ConverterKey, Converter<?>> converterMap, AnalysisContext context,
Integer rowIndex, Integer columnIndex) { Integer rowIndex, Integer columnIndex) {
Class<?> clazz; Class<?> clazz;
if (field == null) { if (field == null) {
@ -88,7 +90,7 @@ public class ConverterUtils {
} else { } else {
clazz = field.getType(); clazz = field.getType();
} }
if (clazz == ReadCellData.class) { if (clazz == CellData.class || clazz == ReadCellData.class) {
Class<?> classGeneric = getClassGeneric(field.getGenericType()); Class<?> classGeneric = getClassGeneric(field.getGenericType());
ReadCellData<Object> cellDataReturn = cellData.clone(); ReadCellData<Object> cellDataReturn = cellData.clone();
cellDataReturn.setData(doConvertToJavaObject(cellData, classGeneric, contentProperty, converterMap, cellDataReturn.setData(doConvertToJavaObject(cellData, classGeneric, contentProperty, converterMap,
@ -126,7 +128,7 @@ public class ConverterUtils {
* @return * @return
*/ */
private static Object doConvertToJavaObject(ReadCellData<?> cellData, Class<?> clazz, private static Object doConvertToJavaObject(ReadCellData<?> cellData, Class<?> clazz,
ExcelContentProperty contentProperty, Map<String, Converter<?>> converterMap, AnalysisContext context, ExcelContentProperty contentProperty, Map<ConverterKey, Converter<?>> converterMap, AnalysisContext context,
Integer rowIndex, Integer columnIndex) { Integer rowIndex, Integer columnIndex) {
Converter<?> converter = null; Converter<?> converter = null;
if (contentProperty != null) { if (contentProperty != null) {

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

@ -1,11 +1,7 @@
package com.alibaba.excel.util; package com.alibaba.excel.util;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.apache.poi.ss.util.CellReference;
/** /**
* @author jipengfei * @author jipengfei
*/ */
@ -18,14 +14,6 @@ public class PositionUtils {
private PositionUtils() {} private PositionUtils() {}
public static int getRowByRowTagt(String rowTagt) {
int row = 0;
if (rowTagt != null) {
row = Integer.parseInt(rowTagt) - 1;
}
return row;
}
public static int getRowByRowTagt(String rowTagt, Integer before) { public static int getRowByRowTagt(String rowTagt, Integer before) {
int row; int row;
if (rowTagt != null) { if (rowTagt != null) {
@ -37,47 +25,40 @@ public class PositionUtils {
} }
return before + 1; return before + 1;
} }
} }
public static int getRow(String currentCellIndex) { public static int getRow(String currentCellIndex) {
if (currentCellIndex != null) { if (currentCellIndex == null) {
int plingPos = currentCellIndex.lastIndexOf(SHEET_NAME_DELIMITER);
String cell = currentCellIndex.substring(plingPos + 1).toUpperCase(Locale.ROOT);
Matcher matcher = CELL_REF_PATTERN.matcher(cell);
if (!matcher.matches()) {
throw new IllegalArgumentException("Invalid CellReference: " + currentCellIndex);
}
String row = matcher.group(2);
return Integer.parseInt(row) - 1;
}
return -1; return -1;
} }
int firstNumber = currentCellIndex.length() - 1;
public static int getCol(String currentCellIndex, Integer before) { for (; firstNumber >= 0; firstNumber--) {
if (currentCellIndex != null) { char c = currentCellIndex.charAt(firstNumber);
int plingPos = currentCellIndex.lastIndexOf(SHEET_NAME_DELIMITER); if (c < '0' || c > '9') {
String cell = currentCellIndex.substring(plingPos + 1).toUpperCase(Locale.ROOT); break;
Matcher matcher = CELL_REF_PATTERN.matcher(cell);
if (!matcher.matches()) {
throw new IllegalArgumentException("Invalid CellReference: " + currentCellIndex);
} }
String col = matcher.group(1);
if (col.length() > 0 && col.charAt(0) == REDUNDANT_CHARACTERS) {
col = col.substring(1);
} }
if (col.length() == 0) { return Integer.parseUnsignedInt(currentCellIndex.substring(firstNumber + 1)) - 1;
return -1;
} else {
return CellReference.convertColStringToIndex(col);
} }
} else {
public static int getCol(String currentCellIndex, Integer before) {
if (currentCellIndex == null) {
if (before == null) { if (before == null) {
before = -1; before = -1;
} }
return before + 1; return before + 1;
} }
int firstNumber = currentCellIndex.charAt(0) == REDUNDANT_CHARACTERS ? 1 : 0;
int col = 0;
for (; firstNumber < currentCellIndex.length(); firstNumber++) {
char c = currentCellIndex.charAt(firstNumber);
boolean isNotLetter = c == REDUNDANT_CHARACTERS || (c >= '0' && c <= '9');
if (isNotLetter) {
break;
}
col = col * 26 + Character.toUpperCase(c) - 'A' + 1;
}
return col - 1;
} }
} }

8
src/main/java/com/alibaba/excel/util/StyleUtil.java

@ -1,5 +1,7 @@
package com.alibaba.excel.util; package com.alibaba.excel.util;
import java.util.Optional;
import com.alibaba.excel.constant.BuiltinFormats; import com.alibaba.excel.constant.BuiltinFormats;
import com.alibaba.excel.metadata.data.DataFormatData; import com.alibaba.excel.metadata.data.DataFormatData;
import com.alibaba.excel.metadata.data.HyperlinkData; import com.alibaba.excel.metadata.data.HyperlinkData;
@ -189,7 +191,11 @@ public class StyleUtil {
xssfFont.setStrikeout(xssfOriginFont.getStrikeout()); xssfFont.setStrikeout(xssfOriginFont.getStrikeout());
// Colors cannot be overwritten // Colors cannot be overwritten
if (writeFont == null || writeFont.getColor() == null) { if (writeFont == null || writeFont.getColor() == null) {
xssfFont.setColor(new XSSFColor(xssfOriginFont.getXSSFColor().getRGB(), null)); xssfFont.setColor(Optional.of(xssfOriginFont)
.map(XSSFFont::getXSSFColor)
.map(XSSFColor::getRGB)
.map(rgb -> new XSSFColor(rgb, null))
.orElse(null));
} }
xssfFont.setTypeOffset(xssfOriginFont.getTypeOffset()); xssfFont.setTypeOffset(xssfOriginFont.getTypeOffset());
xssfFont.setUnderline(xssfOriginFont.getUnderline()); xssfFont.setUnderline(xssfOriginFont.getUnderline());

285
src/main/java/com/alibaba/excel/util/WriteHandlerUtils.java

@ -1,24 +1,19 @@
package com.alibaba.excel.util; package com.alibaba.excel.util;
import java.util.List;
import java.util.Map;
import com.alibaba.excel.context.WriteContext; import com.alibaba.excel.context.WriteContext;
import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.write.handler.CellWriteHandler; import com.alibaba.excel.write.handler.chain.CellHandlerExecutionChain;
import com.alibaba.excel.write.handler.RowWriteHandler; import com.alibaba.excel.write.handler.chain.RowHandlerExecutionChain;
import com.alibaba.excel.write.handler.SheetWriteHandler; import com.alibaba.excel.write.handler.chain.SheetHandlerExecutionChain;
import com.alibaba.excel.write.handler.WorkbookWriteHandler; import com.alibaba.excel.write.handler.chain.WorkbookHandlerExecutionChain;
import com.alibaba.excel.write.handler.WriteHandler;
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext; import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
import com.alibaba.excel.write.handler.context.RowWriteHandlerContext; import com.alibaba.excel.write.handler.context.RowWriteHandlerContext;
import com.alibaba.excel.write.handler.context.SheetWriteHandlerContext; import com.alibaba.excel.write.handler.context.SheetWriteHandlerContext;
import com.alibaba.excel.write.handler.context.WorkbookWriteHandlerContext; import com.alibaba.excel.write.handler.context.WorkbookWriteHandlerContext;
import com.alibaba.excel.write.metadata.holder.AbstractWriteHolder;
import org.apache.commons.collections4.CollectionUtils; import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Row;
/** /**
@ -26,228 +21,162 @@ import org.apache.poi.ss.usermodel.Row;
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Slf4j
public class WriteHandlerUtils { public class WriteHandlerUtils {
private WriteHandlerUtils() {} private WriteHandlerUtils() {}
public static void beforeWorkbookCreate(WriteContext writeContext) { public static WorkbookWriteHandlerContext createWorkbookWriteHandlerContext(WriteContext writeContext) {
beforeWorkbookCreate(writeContext, false); WorkbookWriteHandlerContext context = new WorkbookWriteHandlerContext(writeContext,
writeContext.writeWorkbookHolder());
writeContext.writeWorkbookHolder().setWorkbookWriteHandlerContext(context);
return context;
} }
public static void beforeWorkbookCreate(WriteContext writeContext, boolean runOwn) { public static void beforeWorkbookCreate(WorkbookWriteHandlerContext context) {
List<WriteHandler> handlerList = getHandlerList(writeContext, WorkbookWriteHandler.class, runOwn); beforeWorkbookCreate(context, false);
if (handlerList == null || handlerList.isEmpty()) {
return;
}
WorkbookWriteHandlerContext context = new WorkbookWriteHandlerContext(writeContext, null);
for (WriteHandler writeHandler : handlerList) {
if (writeHandler instanceof WorkbookWriteHandler) {
((WorkbookWriteHandler)writeHandler).beforeWorkbookCreate(context);
} }
public static void beforeWorkbookCreate(WorkbookWriteHandlerContext context, boolean runOwn) {
WorkbookHandlerExecutionChain workbookHandlerExecutionChain = getWorkbookHandlerExecutionChain(context, runOwn);
if (workbookHandlerExecutionChain != null) {
workbookHandlerExecutionChain.beforeWorkbookCreate(context);
} }
} }
public static void afterWorkbookCreate(WriteContext writeContext) { public static void afterWorkbookCreate(WorkbookWriteHandlerContext context) {
afterWorkbookCreate(writeContext, false); afterWorkbookCreate(context, false);
} }
public static void afterWorkbookCreate(WriteContext writeContext, boolean runOwn) { public static void afterWorkbookCreate(WorkbookWriteHandlerContext context, boolean runOwn) {
List<WriteHandler> handlerList = getHandlerList(writeContext, WorkbookWriteHandler.class, runOwn); WorkbookHandlerExecutionChain workbookHandlerExecutionChain = getWorkbookHandlerExecutionChain(context, runOwn);
if (handlerList == null || handlerList.isEmpty()) { if (workbookHandlerExecutionChain != null) {
return; workbookHandlerExecutionChain.afterWorkbookCreate(context);
}
WorkbookWriteHandlerContext context = new WorkbookWriteHandlerContext(writeContext,
writeContext.writeWorkbookHolder());
for (WriteHandler writeHandler : handlerList) {
if (writeHandler instanceof WorkbookWriteHandler) {
((WorkbookWriteHandler)writeHandler).afterWorkbookCreate(context);
}
} }
} }
public static void afterWorkbookDispose(WriteContext writeContext) { private static WorkbookHandlerExecutionChain getWorkbookHandlerExecutionChain(WorkbookWriteHandlerContext context,
List<WriteHandler> handlerList = boolean runOwn) {
writeContext.currentWriteHolder().writeHandlerMap().get(WorkbookWriteHandler.class); AbstractWriteHolder abstractWriteHolder = (AbstractWriteHolder)context.getWriteContext().currentWriteHolder();
if (handlerList == null || handlerList.isEmpty()) { if (runOwn) {
return; return abstractWriteHolder.getOwnWorkbookHandlerExecutionChain();
} else {
return abstractWriteHolder.getWorkbookHandlerExecutionChain();
} }
WorkbookWriteHandlerContext context = new WorkbookWriteHandlerContext(writeContext,
writeContext.writeWorkbookHolder());
for (WriteHandler writeHandler : handlerList) {
if (writeHandler instanceof WorkbookWriteHandler) {
((WorkbookWriteHandler)writeHandler).afterWorkbookDispose(context);
} }
public static void afterWorkbookDispose(WorkbookWriteHandlerContext context) {
WorkbookHandlerExecutionChain workbookHandlerExecutionChain = getWorkbookHandlerExecutionChain(context, false);
if (workbookHandlerExecutionChain != null) {
workbookHandlerExecutionChain.afterWorkbookDispose(context);
} }
} }
public static void beforeSheetCreate(WriteContext writeContext) { public static SheetWriteHandlerContext createSheetWriteHandlerContext(WriteContext writeContext) {
beforeSheetCreate(writeContext, false); return new SheetWriteHandlerContext(writeContext, writeContext.writeWorkbookHolder(),
writeContext.writeSheetHolder());
} }
public static void beforeSheetCreate(WriteContext writeContext, boolean runOwn) { public static void beforeSheetCreate(SheetWriteHandlerContext context) {
List<WriteHandler> handlerList = getHandlerList(writeContext, SheetWriteHandler.class, runOwn); beforeSheetCreate(context, false);
if (handlerList == null || handlerList.isEmpty()) {
return;
}
SheetWriteHandlerContext context = new SheetWriteHandlerContext(writeContext,
writeContext.writeWorkbookHolder(), writeContext.writeSheetHolder());
for (WriteHandler writeHandler : handlerList) {
if (writeHandler instanceof SheetWriteHandler) {
((SheetWriteHandler)writeHandler).beforeSheetCreate(context);
} }
public static void beforeSheetCreate(SheetWriteHandlerContext context, boolean runOwn) {
SheetHandlerExecutionChain sheetHandlerExecutionChain = getSheetHandlerExecutionChain(context, runOwn);
if (sheetHandlerExecutionChain != null) {
sheetHandlerExecutionChain.beforeSheetCreate(context);
} }
} }
public static void afterSheetCreate(WriteContext writeContext) { public static void afterSheetCreate(SheetWriteHandlerContext context) {
afterSheetCreate(writeContext, false); afterSheetCreate(context, false);
} }
public static void afterSheetCreate(WriteContext writeContext, boolean runOwn) { public static void afterSheetCreate(SheetWriteHandlerContext context, boolean runOwn) {
List<WriteHandler> handlerList = getHandlerList(writeContext, SheetWriteHandler.class, runOwn); SheetHandlerExecutionChain sheetHandlerExecutionChain = getSheetHandlerExecutionChain(context, runOwn);
if (handlerList == null || handlerList.isEmpty()) { if (sheetHandlerExecutionChain != null) {
return; sheetHandlerExecutionChain.afterSheetCreate(context);
}
SheetWriteHandlerContext context = new SheetWriteHandlerContext(writeContext,
writeContext.writeWorkbookHolder(), writeContext.writeSheetHolder());
for (WriteHandler writeHandler : handlerList) {
if (writeHandler instanceof SheetWriteHandler) {
((SheetWriteHandler)writeHandler).afterSheetCreate(context);
}
} }
} }
public static void beforeCellCreate(WriteContext writeContext, Row row, Head head, Integer columnIndex, private static SheetHandlerExecutionChain getSheetHandlerExecutionChain(SheetWriteHandlerContext context,
Integer relativeRowIndex, Boolean isHead, ExcelContentProperty excelContentProperty) { boolean runOwn) {
List<WriteHandler> handlerList = AbstractWriteHolder abstractWriteHolder = (AbstractWriteHolder)context.getWriteContext().currentWriteHolder();
writeContext.currentWriteHolder().writeHandlerMap().get(CellWriteHandler.class); if (runOwn) {
if (handlerList == null || handlerList.isEmpty()) { return abstractWriteHolder.getOwnSheetHandlerExecutionChain();
return; } else {
} return abstractWriteHolder.getSheetHandlerExecutionChain();
CellWriteHandlerContext context = new CellWriteHandlerContext(writeContext, writeContext.writeWorkbookHolder(),
writeContext.writeSheetHolder(), writeContext.writeTableHolder(), row, null, columnIndex, relativeRowIndex,
head, null, null, isHead, excelContentProperty);
for (WriteHandler writeHandler : handlerList) {
if (writeHandler instanceof CellWriteHandler) {
((CellWriteHandler)writeHandler).beforeCellCreate(context);
}
} }
} }
public static void afterCellCreate(WriteContext writeContext, Cell cell, Head head, Integer relativeRowIndex, public static CellWriteHandlerContext createCellWriteHandlerContext(WriteContext writeContext, Row row,
Boolean isHead, ExcelContentProperty excelContentProperty) { Integer rowIndex, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead,
List<WriteHandler> handlerList = ExcelContentProperty excelContentProperty) {
writeContext.currentWriteHolder().writeHandlerMap().get(CellWriteHandler.class); return new CellWriteHandlerContext(writeContext, writeContext.writeWorkbookHolder(),
if (handlerList == null || handlerList.isEmpty()) { writeContext.writeSheetHolder(), writeContext.writeTableHolder(), row, rowIndex, null, columnIndex,
return; relativeRowIndex, head, null, null, isHead, excelContentProperty);
}
CellWriteHandlerContext context = new CellWriteHandlerContext(writeContext, writeContext.writeWorkbookHolder(),
writeContext.writeSheetHolder(), writeContext.writeTableHolder(), cell.getRow(), cell,
cell.getColumnIndex(), relativeRowIndex, head, null, null, isHead, excelContentProperty);
for (WriteHandler writeHandler : handlerList) {
if (writeHandler instanceof CellWriteHandler) {
((CellWriteHandler)writeHandler).afterCellCreate(context);
}
}
} }
public static void afterCellDataConverted(WriteContext writeContext, WriteCellData<?> cellData, Cell cell, public static void beforeCellCreate(CellWriteHandlerContext context) {
Head head, Integer relativeRowIndex, Boolean isHead, ExcelContentProperty excelContentProperty) { CellHandlerExecutionChain cellHandlerExecutionChain = ((AbstractWriteHolder)context.getWriteContext()
List<WriteHandler> handlerList = .currentWriteHolder()).getCellHandlerExecutionChain();
writeContext.currentWriteHolder().writeHandlerMap().get(CellWriteHandler.class); if (cellHandlerExecutionChain != null) {
if (handlerList == null || handlerList.isEmpty()) { cellHandlerExecutionChain.beforeCellCreate(context);
return;
}
List<WriteCellData<?>> cellDataList = cellData == null ? null : ListUtils.newArrayList(cellData);
CellWriteHandlerContext context = new CellWriteHandlerContext(writeContext, writeContext.writeWorkbookHolder(),
writeContext.writeSheetHolder(), writeContext.writeTableHolder(), cell.getRow(), cell,
cell.getColumnIndex(), relativeRowIndex, head, cellDataList, cellData, isHead, excelContentProperty);
for (WriteHandler writeHandler : handlerList) {
if (writeHandler instanceof CellWriteHandler) {
((CellWriteHandler)writeHandler).afterCellDataConverted(context);
}
} }
} }
public static void afterCellDispose(WriteContext writeContext, WriteCellData<?> cellData, Cell cell, Head head, public static void afterCellCreate(CellWriteHandlerContext context) {
Integer relativeRowIndex, Boolean isHead, ExcelContentProperty excelContentProperty) { CellHandlerExecutionChain cellHandlerExecutionChain = ((AbstractWriteHolder)context.getWriteContext()
List<WriteCellData<?>> cellDataList = cellData == null ? null : ListUtils.newArrayList(cellData); .currentWriteHolder()).getCellHandlerExecutionChain();
afterCellDispose(writeContext, cellDataList, cell, head, relativeRowIndex, isHead, excelContentProperty); if (cellHandlerExecutionChain != null) {
cellHandlerExecutionChain.afterCellCreate(context);
} }
public static void afterCellDispose(WriteContext writeContext, List<WriteCellData<?>> cellDataList, Cell cell,
Head head, Integer relativeRowIndex, Boolean isHead, ExcelContentProperty excelContentProperty) {
List<WriteHandler> handlerList =
writeContext.currentWriteHolder().writeHandlerMap().get(CellWriteHandler.class);
if (handlerList == null || handlerList.isEmpty()) {
return;
} }
WriteCellData<?> cellData = null;
if (CollectionUtils.isNotEmpty(cellDataList)) { public static void afterCellDataConverted(CellWriteHandlerContext context) {
cellData = cellDataList.get(0); CellHandlerExecutionChain cellHandlerExecutionChain = ((AbstractWriteHolder)context.getWriteContext()
.currentWriteHolder()).getCellHandlerExecutionChain();
if (cellHandlerExecutionChain != null) {
cellHandlerExecutionChain.afterCellDataConverted(context);
} }
CellWriteHandlerContext context = new CellWriteHandlerContext(writeContext, writeContext.writeWorkbookHolder(),
writeContext.writeSheetHolder(), writeContext.writeTableHolder(), cell.getRow(), cell,
cell.getColumnIndex(), relativeRowIndex, head, cellDataList, cellData, isHead, excelContentProperty);
for (WriteHandler writeHandler : handlerList) {
if (writeHandler instanceof CellWriteHandler) {
((CellWriteHandler)writeHandler).afterCellDispose(context);
} }
public static void afterCellDispose(CellWriteHandlerContext context) {
CellHandlerExecutionChain cellHandlerExecutionChain = ((AbstractWriteHolder)context.getWriteContext()
.currentWriteHolder()).getCellHandlerExecutionChain();
if (cellHandlerExecutionChain != null) {
cellHandlerExecutionChain.afterCellDispose(context);
} }
} }
public static void beforeRowCreate(WriteContext writeContext, Integer rowIndex, Integer relativeRowIndex, public static RowWriteHandlerContext createRowWriteHandlerContext(WriteContext writeContext, Integer rowIndex,
Boolean isHead) { Integer relativeRowIndex, Boolean isHead) {
List<WriteHandler> handlerList = writeContext.currentWriteHolder().writeHandlerMap().get(RowWriteHandler.class); return new RowWriteHandlerContext(writeContext, writeContext.writeWorkbookHolder(),
if (handlerList == null || handlerList.isEmpty()) {
return;
}
RowWriteHandlerContext context = new RowWriteHandlerContext(writeContext, writeContext.writeWorkbookHolder(),
writeContext.writeSheetHolder(), writeContext.writeTableHolder(), rowIndex, null, relativeRowIndex, isHead); writeContext.writeSheetHolder(), writeContext.writeTableHolder(), rowIndex, null, relativeRowIndex, isHead);
for (WriteHandler writeHandler : handlerList) {
if (writeHandler instanceof RowWriteHandler) {
((RowWriteHandler)writeHandler).beforeRowCreate(context);
}
}
} }
public static void afterRowCreate(WriteContext writeContext, Row row, Integer relativeRowIndex, Boolean isHead) { public static void beforeRowCreate(RowWriteHandlerContext context) {
List<WriteHandler> handlerList = writeContext.currentWriteHolder().writeHandlerMap().get(RowWriteHandler.class); RowHandlerExecutionChain rowHandlerExecutionChain = ((AbstractWriteHolder)context.getWriteContext()
if (handlerList == null || handlerList.isEmpty()) { .currentWriteHolder()).getRowHandlerExecutionChain();
return; if (rowHandlerExecutionChain != null) {
} rowHandlerExecutionChain.beforeRowCreate(context);
RowWriteHandlerContext context = new RowWriteHandlerContext(writeContext, writeContext.writeWorkbookHolder(),
writeContext.writeSheetHolder(), writeContext.writeTableHolder(), row.getRowNum(), row, relativeRowIndex,
isHead);
for (WriteHandler writeHandler : handlerList) {
if (writeHandler instanceof RowWriteHandler) {
((RowWriteHandler)writeHandler).afterRowCreate(context);
}
} }
} }
public static void afterRowDispose(WriteContext writeContext, Row row, Integer relativeRowIndex, Boolean isHead) { public static void afterRowCreate(RowWriteHandlerContext context) {
List<WriteHandler> handlerList = writeContext.currentWriteHolder().writeHandlerMap().get(RowWriteHandler.class); RowHandlerExecutionChain rowHandlerExecutionChain = ((AbstractWriteHolder)context.getWriteContext()
if (handlerList == null || handlerList.isEmpty()) { .currentWriteHolder()).getRowHandlerExecutionChain();
return; if (rowHandlerExecutionChain != null) {
} rowHandlerExecutionChain.afterRowCreate(context);
RowWriteHandlerContext context = new RowWriteHandlerContext(writeContext, writeContext.writeWorkbookHolder(),
writeContext.writeSheetHolder(), writeContext.writeTableHolder(), row.getRowNum(), row, relativeRowIndex,
isHead);
for (WriteHandler writeHandler : handlerList) {
if (writeHandler instanceof RowWriteHandler) {
((RowWriteHandler)writeHandler).afterRowDispose(context);
}
} }
} }
private static List<WriteHandler> getHandlerList(WriteContext writeContext, Class<? extends WriteHandler> clazz, public static void afterRowDispose(RowWriteHandlerContext context) {
boolean runOwn) { RowHandlerExecutionChain rowHandlerExecutionChain = ((AbstractWriteHolder)context.getWriteContext()
Map<Class<? extends WriteHandler>, List<WriteHandler>> writeHandlerMap; .currentWriteHolder()).getRowHandlerExecutionChain();
if (runOwn) { if (rowHandlerExecutionChain != null) {
writeHandlerMap = writeContext.currentWriteHolder().ownWriteHandlerMap(); rowHandlerExecutionChain.afterRowDispose(context);
} else {
writeHandlerMap = writeContext.currentWriteHolder().writeHandlerMap();
} }
return writeHandlerMap.get(clazz);
} }
} }

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

@ -8,8 +8,7 @@ import com.alibaba.excel.converters.ConverterKeyBuild;
import com.alibaba.excel.converters.NullableObjectConverter; import com.alibaba.excel.converters.NullableObjectConverter;
import com.alibaba.excel.converters.WriteConverterContext; import com.alibaba.excel.converters.WriteConverterContext;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.exception.ExcelDataConvertException; import com.alibaba.excel.exception.ExcelWriteDataConvertException;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.CommentData; import com.alibaba.excel.metadata.data.CommentData;
import com.alibaba.excel.metadata.data.FormulaData; import com.alibaba.excel.metadata.data.FormulaData;
import com.alibaba.excel.metadata.data.HyperlinkData; import com.alibaba.excel.metadata.data.HyperlinkData;
@ -19,10 +18,11 @@ import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.support.ExcelTypeEnum; import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.util.DateUtils; import com.alibaba.excel.util.DateUtils;
import com.alibaba.excel.util.FileTypeUtils; import com.alibaba.excel.util.FileTypeUtils;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.util.StyleUtil; import com.alibaba.excel.util.StyleUtil;
import com.alibaba.excel.util.WorkBookUtil; import com.alibaba.excel.util.WorkBookUtil;
import com.alibaba.excel.util.WriteHandlerUtils; import com.alibaba.excel.util.WriteHandlerUtils;
import com.alibaba.excel.write.metadata.holder.WriteHolder; import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.hssf.usermodel.HSSFClientAnchor; import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
@ -33,6 +33,7 @@ import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.Drawing; import org.apache.poi.ss.usermodel.Drawing;
import org.apache.poi.ss.usermodel.Hyperlink; import org.apache.poi.ss.usermodel.Hyperlink;
import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor; import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
/** /**
@ -47,124 +48,140 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor {
this.writeContext = writeContext; this.writeContext = writeContext;
} }
protected WriteCellData<?> converterAndSet(WriteHolder currentWriteHolder, Class<?> clazz, /**
CellDataTypeEnum targetType, Cell cell, Object value, ExcelContentProperty excelContentProperty, Head head, * Transform the data and then to set into the cell
Integer relativeRowIndex, int rowIndex, int columnIndex) { *
boolean needTrim = value != null && (value instanceof String && currentWriteHolder.globalConfiguration() * @param cellWriteHandlerContext context
.getAutoTrim()); * @return
if (needTrim) { */
value = ((String)value).trim(); protected void converterAndSet(CellWriteHandlerContext cellWriteHandlerContext) {
}
WriteCellData<?> cellData = convert(currentWriteHolder, clazz, targetType, cell, value, excelContentProperty); WriteCellData<?> cellData = convert(cellWriteHandlerContext);
WriteHandlerUtils.afterCellDataConverted(writeContext, cellData, cell, head, relativeRowIndex, Boolean.FALSE, cellWriteHandlerContext.setCellDataList(ListUtils.newArrayList(cellData));
excelContentProperty); cellWriteHandlerContext.setFirstCellData(cellData);
WriteHandlerUtils.afterCellDataConverted(cellWriteHandlerContext);
// Fill in picture information // Fill in picture information
fillImage(cell, cellData.getImageDataList()); fillImage(cellWriteHandlerContext, cellData.getImageDataList());
// Fill in comment information // Fill in comment information
fillComment(cell, cellData.getCommentData()); fillComment(cellWriteHandlerContext, cellData.getCommentData());
// Fill in hyper link information // Fill in hyper link information
fillHyperLink(cell, cellData.getHyperlinkData()); fillHyperLink(cellWriteHandlerContext, cellData.getHyperlinkData());
// Fill in formula information // Fill in formula information
fillFormula(cell, cellData.getFormulaData()); fillFormula(cellWriteHandlerContext, cellData.getFormulaData());
// Fill index // Fill index
cellData.setRowIndex(rowIndex); cellData.setRowIndex(cellWriteHandlerContext.getRowIndex());
cellData.setColumnIndex(columnIndex); cellData.setColumnIndex(cellWriteHandlerContext.getColumnIndex());
if (cellData.getType() == null) { if (cellData.getType() == null) {
cellData.setType(CellDataTypeEnum.EMPTY); cellData.setType(CellDataTypeEnum.EMPTY);
} }
Cell cell = cellWriteHandlerContext.getCell();
switch (cellData.getType()) { switch (cellData.getType()) {
case STRING: case STRING:
cell.setCellValue(cellData.getStringValue()); cell.setCellValue(cellData.getStringValue());
return cellData; return;
case BOOLEAN: case BOOLEAN:
cell.setCellValue(cellData.getBooleanValue()); cell.setCellValue(cellData.getBooleanValue());
return cellData; return;
case NUMBER: case NUMBER:
cell.setCellValue(cellData.getNumberValue().doubleValue()); cell.setCellValue(cellData.getNumberValue().doubleValue());
return cellData; return;
case DATE: case DATE:
cell.setCellValue(cellData.getDateValue()); cell.setCellValue(cellData.getDateValue());
return cellData; return;
case RICH_TEXT_STRING: case RICH_TEXT_STRING:
cell.setCellValue(StyleUtil cell.setCellValue(StyleUtil
.buildRichTextString(writeContext.writeWorkbookHolder(), cellData.getRichTextStringDataValue())); .buildRichTextString(writeContext.writeWorkbookHolder(), cellData.getRichTextStringDataValue()));
return cellData; return;
case EMPTY: case EMPTY:
return cellData; return;
default: default:
throw new ExcelDataConvertException(cell.getRow().getRowNum(), cell.getColumnIndex(), cellData, throw new ExcelWriteDataConvertException(cellWriteHandlerContext,
excelContentProperty, "Not supported data:" + value + " return type:" + cell.getCellType() "Not supported data:" + cellWriteHandlerContext.getOriginalValue() + " return type:"
+ "at row:" + cell.getRow().getRowNum()); + cellData.getType()
+ "at row:" + cellWriteHandlerContext.getRowIndex());
} }
} }
private void fillFormula(Cell cell, FormulaData formulaData) { private void fillFormula(CellWriteHandlerContext cellWriteHandlerContext, FormulaData formulaData) {
if (formulaData == null) { if (formulaData == null) {
return; return;
} }
Cell cell = cellWriteHandlerContext.getCell();
if (formulaData.getFormulaValue() != null) { if (formulaData.getFormulaValue() != null) {
cell.setCellFormula(formulaData.getFormulaValue()); cell.setCellFormula(formulaData.getFormulaValue());
} }
} }
private void fillHyperLink(Cell cell, HyperlinkData hyperlinkData) { private void fillHyperLink(CellWriteHandlerContext cellWriteHandlerContext, HyperlinkData hyperlinkData) {
if (hyperlinkData == null) { if (hyperlinkData == null) {
return; return;
} }
CreationHelper helper = cell.getSheet().getWorkbook().getCreationHelper(); Integer rowIndex = cellWriteHandlerContext.getRowIndex();
Integer columnIndex = cellWriteHandlerContext.getColumnIndex();
Workbook workbook = cellWriteHandlerContext.getWriteWorkbookHolder().getWorkbook();
Cell cell = cellWriteHandlerContext.getCell();
CreationHelper helper = workbook.getCreationHelper();
Hyperlink hyperlink = helper.createHyperlink(StyleUtil.getHyperlinkType(hyperlinkData.getHyperlinkType())); Hyperlink hyperlink = helper.createHyperlink(StyleUtil.getHyperlinkType(hyperlinkData.getHyperlinkType()));
hyperlink.setAddress(hyperlinkData.getAddress()); hyperlink.setAddress(hyperlinkData.getAddress());
hyperlink.setFirstRow(StyleUtil.getCellCoordinate(cell.getRow().getRowNum(), hyperlinkData.getFirstRowIndex(), hyperlink.setFirstRow(StyleUtil.getCellCoordinate(rowIndex, hyperlinkData.getFirstRowIndex(),
hyperlinkData.getRelativeFirstRowIndex())); hyperlinkData.getRelativeFirstRowIndex()));
hyperlink.setFirstColumn(StyleUtil.getCellCoordinate(cell.getColumnIndex(), hyperlinkData.getFirstColumnIndex(), hyperlink.setFirstColumn(StyleUtil.getCellCoordinate(columnIndex, hyperlinkData.getFirstColumnIndex(),
hyperlinkData.getRelativeFirstColumnIndex())); hyperlinkData.getRelativeFirstColumnIndex()));
hyperlink.setLastRow(StyleUtil.getCellCoordinate(cell.getRow().getRowNum(), hyperlinkData.getLastRowIndex(), hyperlink.setLastRow(StyleUtil.getCellCoordinate(rowIndex, hyperlinkData.getLastRowIndex(),
hyperlinkData.getRelativeLastRowIndex())); hyperlinkData.getRelativeLastRowIndex()));
hyperlink.setLastColumn(StyleUtil.getCellCoordinate(cell.getColumnIndex(), hyperlinkData.getLastColumnIndex(), hyperlink.setLastColumn(StyleUtil.getCellCoordinate(columnIndex, hyperlinkData.getLastColumnIndex(),
hyperlinkData.getRelativeLastColumnIndex())); hyperlinkData.getRelativeLastColumnIndex()));
cell.setHyperlink(hyperlink); cell.setHyperlink(hyperlink);
} }
private void fillComment(Cell cell, CommentData commentData) { private void fillComment(CellWriteHandlerContext cellWriteHandlerContext, CommentData commentData) {
if (commentData == null) { if (commentData == null) {
return; return;
} }
ClientAnchor anchor; ClientAnchor anchor;
Integer rowIndex = cellWriteHandlerContext.getRowIndex();
Integer columnIndex = cellWriteHandlerContext.getColumnIndex();
Sheet sheet = cellWriteHandlerContext.getWriteSheetHolder().getSheet();
Cell cell = cellWriteHandlerContext.getCell();
if (writeContext.writeWorkbookHolder().getExcelType() == ExcelTypeEnum.XLSX) { if (writeContext.writeWorkbookHolder().getExcelType() == ExcelTypeEnum.XLSX) {
anchor = new XSSFClientAnchor(StyleUtil.getCoordinate(commentData.getLeft()), anchor = new XSSFClientAnchor(StyleUtil.getCoordinate(commentData.getLeft()),
StyleUtil.getCoordinate(commentData.getTop()), StyleUtil.getCoordinate(commentData.getTop()),
StyleUtil.getCoordinate(commentData.getRight()), StyleUtil.getCoordinate(commentData.getRight()),
StyleUtil.getCoordinate(commentData.getBottom()), StyleUtil.getCoordinate(commentData.getBottom()),
StyleUtil.getCellCoordinate(cell.getColumnIndex(), commentData.getFirstColumnIndex(), StyleUtil.getCellCoordinate(columnIndex, commentData.getFirstColumnIndex(),
commentData.getRelativeFirstColumnIndex()), commentData.getRelativeFirstColumnIndex()),
StyleUtil.getCellCoordinate(cell.getRow().getRowNum(), commentData.getFirstRowIndex(), StyleUtil.getCellCoordinate(rowIndex, commentData.getFirstRowIndex(),
commentData.getRelativeFirstRowIndex()), commentData.getRelativeFirstRowIndex()),
StyleUtil.getCellCoordinate(cell.getColumnIndex(), commentData.getLastColumnIndex(), StyleUtil.getCellCoordinate(columnIndex, commentData.getLastColumnIndex(),
commentData.getRelativeLastColumnIndex()) + 1, commentData.getRelativeLastColumnIndex()) + 1,
StyleUtil.getCellCoordinate(cell.getRow().getRowNum(), commentData.getLastRowIndex(), StyleUtil.getCellCoordinate(rowIndex, commentData.getLastRowIndex(),
commentData.getRelativeLastRowIndex()) + 1); commentData.getRelativeLastRowIndex()) + 1);
} else { } else {
anchor = new HSSFClientAnchor(StyleUtil.getCoordinate(commentData.getLeft()), anchor = new HSSFClientAnchor(StyleUtil.getCoordinate(commentData.getLeft()),
StyleUtil.getCoordinate(commentData.getTop()), StyleUtil.getCoordinate(commentData.getTop()),
StyleUtil.getCoordinate(commentData.getRight()), StyleUtil.getCoordinate(commentData.getRight()),
StyleUtil.getCoordinate(commentData.getBottom()), StyleUtil.getCoordinate(commentData.getBottom()),
(short)StyleUtil.getCellCoordinate(cell.getColumnIndex(), commentData.getFirstColumnIndex(), (short)StyleUtil.getCellCoordinate(columnIndex, commentData.getFirstColumnIndex(),
commentData.getRelativeFirstColumnIndex()), commentData.getRelativeFirstColumnIndex()),
StyleUtil.getCellCoordinate(cell.getRow().getRowNum(), commentData.getFirstRowIndex(), StyleUtil.getCellCoordinate(rowIndex, commentData.getFirstRowIndex(),
commentData.getRelativeFirstRowIndex()), commentData.getRelativeFirstRowIndex()),
(short)(StyleUtil.getCellCoordinate(cell.getColumnIndex(), commentData.getLastColumnIndex(), (short)(StyleUtil.getCellCoordinate(columnIndex, commentData.getLastColumnIndex(),
commentData.getRelativeLastColumnIndex()) + 1), commentData.getRelativeLastColumnIndex()) + 1),
StyleUtil.getCellCoordinate(cell.getRow().getRowNum(), commentData.getLastRowIndex(), StyleUtil.getCellCoordinate(rowIndex, commentData.getLastRowIndex(),
commentData.getRelativeLastRowIndex()) + 1); commentData.getRelativeLastRowIndex()) + 1);
} }
Comment comment = cell.getSheet().createDrawingPatriarch().createCellComment(anchor);
Comment comment = sheet.createDrawingPatriarch().createCellComment(anchor);
if (commentData.getRichTextStringData() != null) { if (commentData.getRichTextStringData() != null) {
comment.setString( comment.setString(
StyleUtil.buildRichTextString(writeContext.writeWorkbookHolder(), commentData.getRichTextStringData())); StyleUtil.buildRichTextString(writeContext.writeWorkbookHolder(), commentData.getRichTextStringData()));
@ -175,18 +192,22 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor {
cell.setCellComment(comment); cell.setCellComment(comment);
} }
protected void fillImage(Cell cell, List<ImageData> imageDataList) { protected void fillImage(CellWriteHandlerContext cellWriteHandlerContext, List<ImageData> imageDataList) {
if (CollectionUtils.isEmpty(imageDataList)) { if (CollectionUtils.isEmpty(imageDataList)) {
return; return;
} }
Sheet sheet = cell.getSheet(); Integer rowIndex = cellWriteHandlerContext.getRowIndex();
Integer columnIndex = cellWriteHandlerContext.getColumnIndex();
Sheet sheet = cellWriteHandlerContext.getWriteSheetHolder().getSheet();
Workbook workbook = cellWriteHandlerContext.getWriteWorkbookHolder().getWorkbook();
Drawing<?> drawing = sheet.getDrawingPatriarch(); Drawing<?> drawing = sheet.getDrawingPatriarch();
if (drawing == null) { if (drawing == null) {
drawing = sheet.createDrawingPatriarch(); drawing = sheet.createDrawingPatriarch();
} }
CreationHelper helper = sheet.getWorkbook().getCreationHelper(); CreationHelper helper = sheet.getWorkbook().getCreationHelper();
for (ImageData imageData : imageDataList) { for (ImageData imageData : imageDataList) {
int index = sheet.getWorkbook().addPicture(imageData.getImage(), int index = workbook.addPicture(imageData.getImage(),
FileTypeUtils.getImageTypeFormat(imageData.getImage())); FileTypeUtils.getImageTypeFormat(imageData.getImage()));
ClientAnchor anchor = helper.createClientAnchor(); ClientAnchor anchor = helper.createClientAnchor();
if (imageData.getTop() != null) { if (imageData.getTop() != null) {
@ -201,13 +222,13 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor {
if (imageData.getLeft() != null) { if (imageData.getLeft() != null) {
anchor.setDx1(StyleUtil.getCoordinate(imageData.getLeft())); anchor.setDx1(StyleUtil.getCoordinate(imageData.getLeft()));
} }
anchor.setRow1(StyleUtil.getCellCoordinate(cell.getRow().getRowNum(), imageData.getFirstRowIndex(), anchor.setRow1(StyleUtil.getCellCoordinate(rowIndex, imageData.getFirstRowIndex(),
imageData.getRelativeFirstRowIndex())); imageData.getRelativeFirstRowIndex()));
anchor.setCol1(StyleUtil.getCellCoordinate(cell.getColumnIndex(), imageData.getFirstColumnIndex(), anchor.setCol1(StyleUtil.getCellCoordinate(columnIndex, imageData.getFirstColumnIndex(),
imageData.getRelativeFirstColumnIndex())); imageData.getRelativeFirstColumnIndex()));
anchor.setRow2(StyleUtil.getCellCoordinate(cell.getRow().getRowNum(), imageData.getLastRowIndex(), anchor.setRow2(StyleUtil.getCellCoordinate(rowIndex, imageData.getLastRowIndex(),
imageData.getRelativeLastRowIndex()) + 1); imageData.getRelativeLastRowIndex()) + 1);
anchor.setCol2(StyleUtil.getCellCoordinate(cell.getColumnIndex(), imageData.getLastColumnIndex(), anchor.setCol2(StyleUtil.getCellCoordinate(columnIndex, imageData.getLastColumnIndex(),
imageData.getRelativeLastColumnIndex()) + 1); imageData.getRelativeLastColumnIndex()) + 1);
if (imageData.getAnchorType() != null) { if (imageData.getAnchorType() != null) {
anchor.setAnchorType(imageData.getAnchorType().getValue()); anchor.setAnchorType(imageData.getAnchorType().getValue());
@ -216,17 +237,16 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor {
} }
} }
protected WriteCellData<?> convert(WriteHolder currentWriteHolder, Class<?> clazz, CellDataTypeEnum targetType, protected WriteCellData<?> convert(CellWriteHandlerContext cellWriteHandlerContext) {
Cell cell, Object value, ExcelContentProperty excelContentProperty) {
// This means that the user has defined the data. // This means that the user has defined the data.
if (clazz == WriteCellData.class) { if (cellWriteHandlerContext.getOriginalFieldClass() == WriteCellData.class) {
if (value == null) { if (cellWriteHandlerContext.getOriginalValue() == null) {
return new WriteCellData<>(CellDataTypeEnum.EMPTY); return new WriteCellData<>(CellDataTypeEnum.EMPTY);
} }
WriteCellData<?> cellDataValue = (WriteCellData<?>)value; WriteCellData<?> cellDataValue = (WriteCellData<?>)cellWriteHandlerContext.getOriginalValue();
if (cellDataValue.getType() != null) { if (cellDataValue.getType() != null) {
// Configuration information may not be read here // Configuration information may not be read here
fillProperty(cellDataValue, excelContentProperty); fillProperty(cellDataValue, cellWriteHandlerContext.getExcelContentProperty());
return cellDataValue; return cellDataValue;
} else { } else {
@ -235,8 +255,7 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor {
return cellDataValue; return cellDataValue;
} }
} }
WriteCellData<?> cellDataReturn = doConvert(currentWriteHolder, cellDataValue.getData().getClass(), WriteCellData<?> cellDataReturn = doConvert(cellWriteHandlerContext);
targetType, cell, cellDataValue.getData(), excelContentProperty);
if (cellDataValue.getImageDataList() != null) { if (cellDataValue.getImageDataList() != null) {
cellDataReturn.setImageDataList(cellDataValue.getImageDataList()); cellDataReturn.setImageDataList(cellDataValue.getImageDataList());
@ -256,7 +275,7 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor {
} }
return cellDataReturn; return cellDataReturn;
} }
return doConvert(currentWriteHolder, clazz, targetType, cell, value, excelContentProperty); return doConvert(cellWriteHandlerContext);
} }
private void fillProperty(WriteCellData<?> cellDataValue, ExcelContentProperty excelContentProperty) { private void fillProperty(WriteCellData<?> cellDataValue, ExcelContentProperty excelContentProperty) {
@ -280,8 +299,9 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor {
} }
} }
private WriteCellData<?> doConvert(WriteHolder currentWriteHolder, Class<?> clazz, CellDataTypeEnum targetType, private WriteCellData<?> doConvert(CellWriteHandlerContext cellWriteHandlerContext) {
Cell cell, Object value, ExcelContentProperty excelContentProperty) { ExcelContentProperty excelContentProperty = cellWriteHandlerContext.getExcelContentProperty();
Converter<?> converter = null; Converter<?> converter = null;
if (excelContentProperty != null) { if (excelContentProperty != null) {
converter = excelContentProperty.getConverter(); converter = excelContentProperty.getConverter();
@ -289,31 +309,34 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor {
if (converter == null) { if (converter == null) {
// csv is converted to string by default // csv is converted to string by default
if (writeContext.writeWorkbookHolder().getExcelType() == ExcelTypeEnum.CSV) { if (writeContext.writeWorkbookHolder().getExcelType() == ExcelTypeEnum.CSV) {
targetType = CellDataTypeEnum.STRING; cellWriteHandlerContext.setTargetCellDataType(CellDataTypeEnum.STRING);
} }
converter = currentWriteHolder.converterMap().get(ConverterKeyBuild.buildKey(clazz, targetType)); converter = writeContext.currentWriteHolder().converterMap().get(
ConverterKeyBuild.buildKey(cellWriteHandlerContext.getOriginalFieldClass(),
cellWriteHandlerContext.getTargetCellDataType()));
} }
if (value == null && !(converter instanceof NullableObjectConverter)) { if (cellWriteHandlerContext.getOriginalValue() == null && !(converter instanceof NullableObjectConverter)) {
return new WriteCellData<>(CellDataTypeEnum.EMPTY); return new WriteCellData<>(CellDataTypeEnum.EMPTY);
} }
if (converter == null) { if (converter == null) {
throw new ExcelDataConvertException(cell.getRow().getRowNum(), cell.getColumnIndex(), throw new ExcelWriteDataConvertException(cellWriteHandlerContext,
new WriteCellData<>(CellDataTypeEnum.EMPTY), excelContentProperty, "Can not find 'Converter' support class " + cellWriteHandlerContext.getOriginalFieldClass()
"Can not find 'Converter' support class " + clazz.getSimpleName() + "."); .getSimpleName() + ".");
} }
WriteCellData<?> cellData; WriteCellData<?> cellData;
try { try {
cellData = ((Converter<Object>)converter).convertToExcelData( cellData = ((Converter<Object>)converter).convertToExcelData(
new WriteConverterContext<>(value, excelContentProperty, writeContext)); new WriteConverterContext<>(cellWriteHandlerContext.getOriginalValue(), excelContentProperty,
writeContext));
} catch (Exception e) { } catch (Exception e) {
throw new ExcelDataConvertException(cell.getRow().getRowNum(), cell.getColumnIndex(), throw new ExcelWriteDataConvertException(cellWriteHandlerContext,
new WriteCellData<>(CellDataTypeEnum.EMPTY), excelContentProperty, "Convert data:" + cellWriteHandlerContext.getOriginalValue() + " error, at row:"
"Convert data:" + value + " error, at row:" + cell.getRow().getRowNum(), e); + cellWriteHandlerContext.getRowIndex(), e);
} }
if (cellData == null || cellData.getType() == null) { if (cellData == null || cellData.getType() == null) {
throw new ExcelDataConvertException(cell.getRow().getRowNum(), cell.getColumnIndex(), throw new ExcelWriteDataConvertException(cellWriteHandlerContext,
new WriteCellData<>(CellDataTypeEnum.EMPTY), excelContentProperty, "Convert data:" + cellWriteHandlerContext.getOriginalValue() + " return null, at row:"
"Convert data:" + value + " return null, at row:" + cell.getRow().getRowNum()); + cellWriteHandlerContext.getRowIndex());
} }
return cellData; return cellData;
} }

96
src/main/java/com/alibaba/excel/write/executor/ExcelWriteAddExecutor.java

@ -11,13 +11,14 @@ import java.util.TreeMap;
import com.alibaba.excel.context.WriteContext; import com.alibaba.excel.context.WriteContext;
import com.alibaba.excel.enums.HeadKindEnum; import com.alibaba.excel.enums.HeadKindEnum;
import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.util.BeanMapUtils; import com.alibaba.excel.util.BeanMapUtils;
import com.alibaba.excel.util.ClassUtils; import com.alibaba.excel.util.ClassUtils;
import com.alibaba.excel.util.FieldUtils; import com.alibaba.excel.util.FieldUtils;
import com.alibaba.excel.util.WorkBookUtil; import com.alibaba.excel.util.WorkBookUtil;
import com.alibaba.excel.util.WriteHandlerUtils; import com.alibaba.excel.util.WriteHandlerUtils;
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
import com.alibaba.excel.write.handler.context.RowWriteHandlerContext;
import com.alibaba.excel.write.metadata.CollectionRowData; import com.alibaba.excel.write.metadata.CollectionRowData;
import com.alibaba.excel.write.metadata.MapRowData; import com.alibaba.excel.write.metadata.MapRowData;
import com.alibaba.excel.write.metadata.RowData; import com.alibaba.excel.write.metadata.RowData;
@ -64,9 +65,14 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor {
if (oneRowData == null) { if (oneRowData == null) {
return; return;
} }
WriteHandlerUtils.beforeRowCreate(writeContext, rowIndex, relativeRowIndex, Boolean.FALSE); RowWriteHandlerContext rowWriteHandlerContext = WriteHandlerUtils.createRowWriteHandlerContext(writeContext,
rowIndex, relativeRowIndex, Boolean.FALSE);
WriteHandlerUtils.beforeRowCreate(rowWriteHandlerContext);
Row row = WorkBookUtil.createRow(writeContext.writeSheetHolder().getSheet(), rowIndex); Row row = WorkBookUtil.createRow(writeContext.writeSheetHolder().getSheet(), rowIndex);
WriteHandlerUtils.afterRowCreate(writeContext, row, relativeRowIndex, Boolean.FALSE); rowWriteHandlerContext.setRow(row);
WriteHandlerUtils.afterRowCreate(rowWriteHandlerContext);
if (oneRowData instanceof Collection<?>) { if (oneRowData instanceof Collection<?>) {
addBasicTypeToExcel(new CollectionRowData((Collection<?>)oneRowData), row, rowIndex, relativeRowIndex); addBasicTypeToExcel(new CollectionRowData((Collection<?>)oneRowData), row, rowIndex, relativeRowIndex);
@ -75,7 +81,8 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor {
} else { } else {
addJavaObjectToExcel(oneRowData, row, rowIndex, relativeRowIndex, sortedAllFiledMap); addJavaObjectToExcel(oneRowData, row, rowIndex, relativeRowIndex, sortedAllFiledMap);
} }
WriteHandlerUtils.afterRowDispose(writeContext, row, relativeRowIndex, Boolean.FALSE);
WriteHandlerUtils.afterRowDispose(rowWriteHandlerContext);
} }
private void addBasicTypeToExcel(RowData oneRowData, Row row, int rowIndex, int relativeRowIndex) { private void addBasicTypeToExcel(RowData oneRowData, Row row, int rowIndex, int relativeRowIndex) {
@ -114,23 +121,30 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor {
writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadClazz(), writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadClazz(),
head == null ? null : head.getFieldName()); head == null ? null : head.getFieldName());
WriteHandlerUtils.beforeCellCreate(writeContext, row, head, columnIndex, relativeRowIndex, Boolean.FALSE, CellWriteHandlerContext cellWriteHandlerContext = WriteHandlerUtils.createCellWriteHandlerContext(writeContext,
excelContentProperty); row, rowIndex, head, columnIndex, relativeRowIndex, Boolean.FALSE, excelContentProperty);
WriteHandlerUtils.beforeCellCreate(cellWriteHandlerContext);
Cell cell = WorkBookUtil.createCell(row, columnIndex); Cell cell = WorkBookUtil.createCell(row, columnIndex);
WriteHandlerUtils.afterCellCreate(writeContext, cell, head, relativeRowIndex, Boolean.FALSE, cellWriteHandlerContext.setCell(cell);
excelContentProperty);
Object value = oneRowData.get(dataIndex); WriteHandlerUtils.afterCellCreate(cellWriteHandlerContext);
WriteCellData<?> cellData = converterAndSet(writeContext.currentWriteHolder(),
FieldUtils.getFieldClass(value), null, cell, value, null, head, relativeRowIndex, rowIndex, columnIndex); cellWriteHandlerContext.setOriginalValue(oneRowData.get(dataIndex));
WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, head, relativeRowIndex, Boolean.FALSE, cellWriteHandlerContext.setOriginalFieldClass(
excelContentProperty); FieldUtils.getFieldClass(cellWriteHandlerContext.getOriginalValue()));
converterAndSet(cellWriteHandlerContext);
WriteHandlerUtils.afterCellDispose(cellWriteHandlerContext);
} }
private void addJavaObjectToExcel(Object oneRowData, Row row, int rowIndex, int relativeRowIndex, private void addJavaObjectToExcel(Object oneRowData, Row row, int rowIndex, int relativeRowIndex,
Map<Integer, Field> sortedAllFiledMap) { Map<Integer, Field> sortedAllFiledMap) {
WriteHolder currentWriteHolder = writeContext.currentWriteHolder(); WriteHolder currentWriteHolder = writeContext.currentWriteHolder();
BeanMap beanMap = BeanMapUtils.create(oneRowData); BeanMap beanMap = BeanMapUtils.create(oneRowData);
Set<String> beanMapHandledSet = new HashSet<String>(); // Bean the contains of the Map Key method with poor performance,So to create a keySet here
Set<String> beanKeySet = new HashSet<>(beanMap.keySet());
Set<String> beanMapHandledSet = new HashSet<>();
int maxCellIndex = -1; int maxCellIndex = -1;
// If it's a class it needs to be cast by type // If it's a class it needs to be cast by type
if (HeadKindEnum.CLASS.equals(writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadKind())) { if (HeadKindEnum.CLASS.equals(writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadKind())) {
@ -139,21 +153,28 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor {
int columnIndex = entry.getKey(); int columnIndex = entry.getKey();
Head head = entry.getValue(); Head head = entry.getValue();
String name = head.getFieldName(); String name = head.getFieldName();
if (!beanMap.containsKey(name)) { if (!beanKeySet.contains(name)) {
continue; continue;
} }
ExcelContentProperty excelContentProperty = ClassUtils.declaredExcelContentProperty(beanMap, ExcelContentProperty excelContentProperty = ClassUtils.declaredExcelContentProperty(beanMap,
currentWriteHolder.excelWriteHeadProperty().getHeadClazz(), name); currentWriteHolder.excelWriteHeadProperty().getHeadClazz(), name);
WriteHandlerUtils.beforeCellCreate(writeContext, row, head, columnIndex, relativeRowIndex, CellWriteHandlerContext cellWriteHandlerContext = WriteHandlerUtils.createCellWriteHandlerContext(
Boolean.FALSE, excelContentProperty); writeContext, row, rowIndex, head, columnIndex, relativeRowIndex, Boolean.FALSE,
Cell cell = WorkBookUtil.createCell(row, columnIndex);
WriteHandlerUtils.afterCellCreate(writeContext, cell, head, relativeRowIndex, Boolean.FALSE,
excelContentProperty);
Object value = beanMap.get(name);
WriteCellData<?> cellData = converterAndSet(currentWriteHolder, head.getField().getType(),
null, cell, value, excelContentProperty, head, relativeRowIndex, rowIndex, columnIndex);
WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, head, relativeRowIndex, Boolean.FALSE,
excelContentProperty); excelContentProperty);
WriteHandlerUtils.beforeCellCreate(cellWriteHandlerContext);
Cell cell = WorkBookUtil.createCell(row, columnIndex);
cellWriteHandlerContext.setCell(cell);
WriteHandlerUtils.afterCellCreate(cellWriteHandlerContext);
cellWriteHandlerContext.setOriginalValue(beanMap.get(name));
cellWriteHandlerContext.setOriginalFieldClass(head.getField().getType());
converterAndSet(cellWriteHandlerContext);
WriteHandlerUtils.afterCellDispose(cellWriteHandlerContext);
beanMapHandledSet.add(name); beanMapHandledSet.add(name);
maxCellIndex = Math.max(maxCellIndex, columnIndex); maxCellIndex = Math.max(maxCellIndex, columnIndex);
} }
@ -169,7 +190,7 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor {
for (Map.Entry<Integer, Field> entry : sortedAllFiledMap.entrySet()) { for (Map.Entry<Integer, Field> entry : sortedAllFiledMap.entrySet()) {
Field field = entry.getValue(); Field field = entry.getValue();
String filedName = FieldUtils.resolveCglibFieldName(field); String filedName = FieldUtils.resolveCglibFieldName(field);
boolean uselessData = !beanMap.containsKey(filedName) || beanMapHandledSet.contains(filedName) boolean uselessData = !beanKeySet.contains(filedName) || beanMapHandledSet.contains(filedName)
|| ignoreMap.containsKey(filedName); || ignoreMap.containsKey(filedName);
if (uselessData) { if (uselessData) {
continue; continue;
@ -177,18 +198,23 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor {
Object value = beanMap.get(filedName); Object value = beanMap.get(filedName);
ExcelContentProperty excelContentProperty = ClassUtils.declaredExcelContentProperty(beanMap, ExcelContentProperty excelContentProperty = ClassUtils.declaredExcelContentProperty(beanMap,
currentWriteHolder.excelWriteHeadProperty().getHeadClazz(), filedName); currentWriteHolder.excelWriteHeadProperty().getHeadClazz(), filedName);
WriteHandlerUtils.beforeCellCreate(writeContext, row, null, maxCellIndex, relativeRowIndex, Boolean.FALSE, CellWriteHandlerContext cellWriteHandlerContext = WriteHandlerUtils.createCellWriteHandlerContext(
excelContentProperty); writeContext, row, rowIndex, null, maxCellIndex, relativeRowIndex, Boolean.FALSE, excelContentProperty);
WriteHandlerUtils.beforeCellCreate(cellWriteHandlerContext);
// fix https://github.com/alibaba/easyexcel/issues/1870 // fix https://github.com/alibaba/easyexcel/issues/1870
// If there is data, it is written to the next cell // If there is data, it is written to the next cell
Cell cell = WorkBookUtil.createCell(row, maxCellIndex++); Cell cell = WorkBookUtil.createCell(row, maxCellIndex);
WriteHandlerUtils.afterCellCreate(writeContext, cell, null, relativeRowIndex, Boolean.FALSE, cellWriteHandlerContext.setCell(cell);
excelContentProperty);
WriteCellData<?> cellData = converterAndSet(currentWriteHolder, WriteHandlerUtils.afterCellCreate(cellWriteHandlerContext);
FieldUtils.getFieldClass(beanMap, filedName, value), null, cell, value, null, null, relativeRowIndex,
rowIndex, maxCellIndex); cellWriteHandlerContext.setOriginalValue(value);
WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, null, relativeRowIndex, Boolean.FALSE, cellWriteHandlerContext.setOriginalFieldClass(FieldUtils.getFieldClass(beanMap, filedName, value));
excelContentProperty); converterAndSet(cellWriteHandlerContext);
WriteHandlerUtils.afterCellDispose(cellWriteHandlerContext);
maxCellIndex++;
} }
} }

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

@ -7,6 +7,7 @@ import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
@ -24,11 +25,17 @@ import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.util.MapUtils; import com.alibaba.excel.util.MapUtils;
import com.alibaba.excel.util.StringUtils; import com.alibaba.excel.util.StringUtils;
import com.alibaba.excel.util.WriteHandlerUtils; import com.alibaba.excel.util.WriteHandlerUtils;
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
import com.alibaba.excel.write.handler.context.RowWriteHandlerContext;
import com.alibaba.excel.write.metadata.fill.AnalysisCell; import com.alibaba.excel.write.metadata.fill.AnalysisCell;
import com.alibaba.excel.write.metadata.fill.FillConfig; import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.excel.write.metadata.fill.FillWrapper; import com.alibaba.excel.write.metadata.fill.FillWrapper;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.hssf.usermodel.PoiUtils; import org.apache.poi.hssf.usermodel.PoiUtils;
import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Cell;
@ -53,29 +60,30 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
/** /**
* Fields to replace in the template * Fields to replace in the template
*/ */
private final Map<String, List<AnalysisCell>> templateAnalysisCache = MapUtils.newHashMap(); private final Map<UniqueDataFlagKey, List<AnalysisCell>> templateAnalysisCache = MapUtils.newHashMap();
/** /**
* Collection fields to replace in the template * Collection fields to replace in the template
*/ */
private final Map<String, List<AnalysisCell>> templateCollectionAnalysisCache = MapUtils.newHashMap(); private final Map<UniqueDataFlagKey, List<AnalysisCell>> templateCollectionAnalysisCache = MapUtils.newHashMap();
/** /**
* Style cache for collection fields * Style cache for collection fields
*/ */
private final Map<String, Map<AnalysisCell, CellStyle>> collectionFieldStyleCache = MapUtils.newHashMap(); private final Map<UniqueDataFlagKey, Map<AnalysisCell, CellStyle>> collectionFieldStyleCache
= MapUtils.newHashMap();
/** /**
* Row height cache for collection * Row height cache for collection
*/ */
private final Map<String, Short> collectionRowHeightCache = MapUtils.newHashMap(); private final Map<UniqueDataFlagKey, Short> collectionRowHeightCache = MapUtils.newHashMap();
/** /**
* Last index cache for collection fields * Last index cache for collection fields
*/ */
private final Map<String, Map<AnalysisCell, Integer>> collectionLastIndexCache = MapUtils.newHashMap(); private final Map<UniqueDataFlagKey, Map<AnalysisCell, Integer>> collectionLastIndexCache = MapUtils.newHashMap();
private final Map<String, Integer> relativeRowIndexMap = MapUtils.newHashMap(); private final Map<UniqueDataFlagKey, Integer> relativeRowIndexMap = MapUtils.newHashMap();
/** /**
* The unique data encoding for this fill * The unique data encoding for this fill
*/ */
private String currentUniqueDataFlag; private UniqueDataFlagKey currentUniqueDataFlag;
public ExcelWriteFillExecutor(WriteContext writeContext) { public ExcelWriteFillExecutor(WriteContext writeContext) {
super(writeContext); super(writeContext);
@ -159,15 +167,16 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
sheet.shiftRows(maxRowIndex + 1, lastRowIndex, number, true, false); sheet.shiftRows(maxRowIndex + 1, lastRowIndex, number, true, false);
// The current data is greater than unity rowindex increase // The current data is greater than unity rowindex increase
String tablePrefix = tablePrefix(currentUniqueDataFlag); increaseRowIndex(templateAnalysisCache, number, maxRowIndex);
increaseRowIndex(templateAnalysisCache, number, maxRowIndex, tablePrefix); increaseRowIndex(templateCollectionAnalysisCache, number, maxRowIndex);
increaseRowIndex(templateCollectionAnalysisCache, number, maxRowIndex, tablePrefix);
} }
private void increaseRowIndex(Map<String, List<AnalysisCell>> templateAnalysisCache, int number, int maxRowIndex, private void increaseRowIndex(Map<UniqueDataFlagKey, List<AnalysisCell>> templateAnalysisCache, int number,
String tablePrefix) { int maxRowIndex) {
for (Map.Entry<String, List<AnalysisCell>> entry : templateAnalysisCache.entrySet()) { for (Map.Entry<UniqueDataFlagKey, List<AnalysisCell>> entry : templateAnalysisCache.entrySet()) {
if (!tablePrefix.equals(tablePrefix(entry.getKey()))) { UniqueDataFlagKey uniqueDataFlagKey = entry.getKey();
if (!Objects.equals(currentUniqueDataFlag.getSheetNo(), uniqueDataFlagKey.getSheetNo()) || !Objects.equals(
currentUniqueDataFlag.getSheetName(), uniqueDataFlagKey.getSheetName())) {
continue; continue;
} }
for (AnalysisCell analysisCell : entry.getValue()) { for (AnalysisCell analysisCell : entry.getValue()) {
@ -183,28 +192,35 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
if (CollectionUtils.isEmpty(analysisCellList) || oneRowData == null) { if (CollectionUtils.isEmpty(analysisCellList) || oneRowData == null) {
return; return;
} }
Map<?, ?> dataMap; Map dataMap;
if (oneRowData instanceof Map) { if (oneRowData instanceof Map) {
dataMap = (Map<?, ?>)oneRowData; dataMap = (Map)oneRowData;
} else { } else {
dataMap = BeanMapUtils.create(oneRowData); dataMap = BeanMapUtils.create(oneRowData);
} }
WriteSheetHolder writeSheetHolder = writeContext.writeSheetHolder(); Set<String> dataKeySet = new HashSet<>(dataMap.keySet());
for (AnalysisCell analysisCell : analysisCellList) { for (AnalysisCell analysisCell : analysisCellList) {
CellWriteHandlerContext cellWriteHandlerContext = WriteHandlerUtils.createCellWriteHandlerContext(
writeContext, null, analysisCell.getRowIndex(), null, analysisCell.getColumnIndex(),
relativeRowIndex, Boolean.FALSE, ExcelContentProperty.EMPTY);
if (analysisCell.getOnlyOneVariable()) { if (analysisCell.getOnlyOneVariable()) {
String variable = analysisCell.getVariableList().get(0); String variable = analysisCell.getVariableList().get(0);
if (!dataMap.containsKey(variable)) { if (!dataKeySet.contains(variable)) {
continue; continue;
} }
Object value = dataMap.get(variable); Object value = dataMap.get(variable);
ExcelContentProperty excelContentProperty = ClassUtils.declaredExcelContentProperty(dataMap, ExcelContentProperty excelContentProperty = ClassUtils.declaredExcelContentProperty(dataMap,
writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadClazz(), variable); writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadClazz(), variable);
Cell cell = getOneCell(analysisCell, fillConfig, excelContentProperty); cellWriteHandlerContext.setExcelContentProperty(excelContentProperty);
createCell(analysisCell, fillConfig, cellWriteHandlerContext);
cellWriteHandlerContext.setOriginalValue(value);
cellWriteHandlerContext.setOriginalFieldClass(FieldUtils.getFieldClass(dataMap, variable, value));
WriteCellData<?> cellData = converterAndSet(writeSheetHolder, converterAndSet(cellWriteHandlerContext);
FieldUtils.getFieldClass(dataMap, variable, value), null, cell, value, excelContentProperty, null, WriteCellData<?> cellData = cellWriteHandlerContext.getFirstCellData();
relativeRowIndex, analysisCell.getRowIndex(), analysisCell.getColumnIndex());
cellData.setAnalysisCell(analysisCell);
// Restyle // Restyle
if (fillConfig.getAutoStyle()) { if (fillConfig.getAutoStyle()) {
@ -212,28 +228,33 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
.map(collectionFieldStyleMap -> collectionFieldStyleMap.get(analysisCell)) .map(collectionFieldStyleMap -> collectionFieldStyleMap.get(analysisCell))
.ifPresent(cellData::setOriginCellStyle); .ifPresent(cellData::setOriginCellStyle);
} }
WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, null, relativeRowIndex, Boolean.FALSE,
excelContentProperty);
} else { } else {
StringBuilder cellValueBuild = new StringBuilder(); StringBuilder cellValueBuild = new StringBuilder();
int index = 0; int index = 0;
List<WriteCellData<?>> cellDataList = new ArrayList<>(); List<WriteCellData<?>> cellDataList = new ArrayList<>();
Cell cell = getOneCell(analysisCell, fillConfig, ExcelContentProperty.EMPTY);
cellWriteHandlerContext.setExcelContentProperty(ExcelContentProperty.EMPTY);
cellWriteHandlerContext.setIgnoreFillStyle(Boolean.TRUE);
createCell(analysisCell, fillConfig, cellWriteHandlerContext);
Cell cell = cellWriteHandlerContext.getCell();
for (String variable : analysisCell.getVariableList()) { for (String variable : analysisCell.getVariableList()) {
cellValueBuild.append(analysisCell.getPrepareDataList().get(index++)); cellValueBuild.append(analysisCell.getPrepareDataList().get(index++));
if (!dataMap.containsKey(variable)) { if (!dataKeySet.contains(variable)) {
continue; continue;
} }
Object value = dataMap.get(variable); Object value = dataMap.get(variable);
ExcelContentProperty excelContentProperty = ClassUtils.declaredExcelContentProperty(dataMap, ExcelContentProperty excelContentProperty = ClassUtils.declaredExcelContentProperty(dataMap,
writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadClazz(), variable); writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadClazz(), variable);
WriteCellData<?> cellData = convert(writeSheetHolder, cellWriteHandlerContext.setOriginalValue(value);
FieldUtils.getFieldClass(dataMap, variable, value), CellDataTypeEnum.STRING, cell, value, cellWriteHandlerContext.setOriginalFieldClass(FieldUtils.getFieldClass(dataMap, variable, value));
excelContentProperty); cellWriteHandlerContext.setExcelContentProperty(excelContentProperty);
cellData.setAnalysisCell(analysisCell); cellWriteHandlerContext.setTargetCellDataType(CellDataTypeEnum.STRING);
WriteCellData<?> cellData = convert(cellWriteHandlerContext);
cellDataList.add(cellData); cellDataList.add(cellData);
CellDataTypeEnum type = cellData.getType(); CellDataTypeEnum type = cellData.getType();
if (type != null) { if (type != null) {
switch (type) { switch (type) {
@ -253,6 +274,10 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
} }
cellValueBuild.append(analysisCell.getPrepareDataList().get(index)); cellValueBuild.append(analysisCell.getPrepareDataList().get(index));
cell.setCellValue(cellValueBuild.toString()); cell.setCellValue(cellValueBuild.toString());
cellWriteHandlerContext.setCellDataList(cellDataList);
if (CollectionUtils.isNotEmpty(cellDataList)) {
cellWriteHandlerContext.setFirstCellData(cellDataList.get(0));
}
// Restyle // Restyle
if (fillConfig.getAutoStyle()) { if (fillConfig.getAutoStyle()) {
@ -260,10 +285,8 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
.map(collectionFieldStyleMap -> collectionFieldStyleMap.get(analysisCell)) .map(collectionFieldStyleMap -> collectionFieldStyleMap.get(analysisCell))
.ifPresent(cell::setCellStyle); .ifPresent(cell::setCellStyle);
} }
WriteHandlerUtils.afterCellDispose(writeContext, cellDataList, cell, null, relativeRowIndex,
Boolean.FALSE, ExcelContentProperty.EMPTY);
} }
WriteHandlerUtils.afterCellDispose(cellWriteHandlerContext);
} }
} }
@ -278,11 +301,14 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
return relativeRowIndex; return relativeRowIndex;
} }
private Cell getOneCell(AnalysisCell analysisCell, FillConfig fillConfig, private void createCell(AnalysisCell analysisCell, FillConfig fillConfig,
ExcelContentProperty excelContentProperty) { CellWriteHandlerContext cellWriteHandlerContext) {
Sheet cachedSheet = writeContext.writeSheetHolder().getCachedSheet(); Sheet cachedSheet = writeContext.writeSheetHolder().getCachedSheet();
if (WriteTemplateAnalysisCellTypeEnum.COMMON.equals(analysisCell.getCellType())) { if (WriteTemplateAnalysisCellTypeEnum.COMMON.equals(analysisCell.getCellType())) {
return cachedSheet.getRow(analysisCell.getRowIndex()).getCell(analysisCell.getColumnIndex()); Row row = cachedSheet.getRow(analysisCell.getRowIndex());
cellWriteHandlerContext.setRow(row);
Cell cell = row.getCell(analysisCell.getColumnIndex());
cellWriteHandlerContext.setCell(cell);
} }
Sheet sheet = writeContext.writeSheetHolder().getSheet(); Sheet sheet = writeContext.writeSheetHolder().getSheet();
@ -320,25 +346,31 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
} }
Row row = createRowIfNecessary(sheet, cachedSheet, lastRowIndex, fillConfig, analysisCell, isOriginalCell); Row row = createRowIfNecessary(sheet, cachedSheet, lastRowIndex, fillConfig, analysisCell, isOriginalCell);
Cell cell = createCellIfNecessary(row, lastColumnIndex, excelContentProperty); cellWriteHandlerContext.setRow(row);
cellWriteHandlerContext.setRowIndex(lastRowIndex);
cellWriteHandlerContext.setColumnIndex(lastColumnIndex);
Cell cell = createCellIfNecessary(row, lastColumnIndex, cellWriteHandlerContext);
cellWriteHandlerContext.setCell(cell);
if (isOriginalCell) { if (isOriginalCell) {
Map<AnalysisCell, CellStyle> collectionFieldStyleMap = collectionFieldStyleCache.computeIfAbsent( Map<AnalysisCell, CellStyle> collectionFieldStyleMap = collectionFieldStyleCache.computeIfAbsent(
currentUniqueDataFlag, key -> MapUtils.newHashMap()); currentUniqueDataFlag, key -> MapUtils.newHashMap());
collectionFieldStyleMap.put(analysisCell, cell.getCellStyle()); collectionFieldStyleMap.put(analysisCell, cell.getCellStyle());
} }
return cell;
} }
private Cell createCellIfNecessary(Row row, Integer lastColumnIndex, ExcelContentProperty excelContentProperty) { private Cell createCellIfNecessary(Row row, Integer lastColumnIndex,
CellWriteHandlerContext cellWriteHandlerContext) {
Cell cell = row.getCell(lastColumnIndex); Cell cell = row.getCell(lastColumnIndex);
if (cell != null) { if (cell != null) {
return cell; return cell;
} }
WriteHandlerUtils.beforeCellCreate(writeContext, row, null, lastColumnIndex, null, Boolean.FALSE, WriteHandlerUtils.beforeCellCreate(cellWriteHandlerContext);
excelContentProperty);
cell = row.createCell(lastColumnIndex); cell = row.createCell(lastColumnIndex);
WriteHandlerUtils.afterCellCreate(writeContext, cell, null, null, Boolean.FALSE, excelContentProperty); cellWriteHandlerContext.setCell(cell);
WriteHandlerUtils.afterCellCreate(cellWriteHandlerContext);
return cell; return cell;
} }
@ -351,7 +383,10 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
} }
row = cachedSheet.getRow(lastRowIndex); row = cachedSheet.getRow(lastRowIndex);
if (row == null) { if (row == null) {
WriteHandlerUtils.beforeRowCreate(writeContext, lastRowIndex, null, Boolean.FALSE); RowWriteHandlerContext rowWriteHandlerContext = WriteHandlerUtils.createRowWriteHandlerContext(writeContext,
lastRowIndex, null, Boolean.FALSE);
WriteHandlerUtils.beforeRowCreate(rowWriteHandlerContext);
if (fillConfig.getForceNewRow()) { if (fillConfig.getForceNewRow()) {
row = cachedSheet.createRow(lastRowIndex); row = cachedSheet.createRow(lastRowIndex);
} else { } else {
@ -364,8 +399,10 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
row = cachedSheet.createRow(lastRowIndex); row = cachedSheet.createRow(lastRowIndex);
} }
} }
rowWriteHandlerContext.setRow(row);
checkRowHeight(analysisCell, fillConfig, isOriginalCell, row); checkRowHeight(analysisCell, fillConfig, isOriginalCell, row);
WriteHandlerUtils.afterRowCreate(writeContext, row, null, Boolean.FALSE);
WriteHandlerUtils.afterRowCreate(rowWriteHandlerContext);
} else { } else {
checkRowHeight(analysisCell, fillConfig, isOriginalCell, row); checkRowHeight(analysisCell, fillConfig, isOriginalCell, row);
} }
@ -389,13 +426,13 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
} }
} }
private List<AnalysisCell> readTemplateData(Map<String, List<AnalysisCell>> analysisCache) { private List<AnalysisCell> readTemplateData(Map<UniqueDataFlagKey, List<AnalysisCell>> analysisCache) {
List<AnalysisCell> analysisCellList = analysisCache.get(currentUniqueDataFlag); List<AnalysisCell> analysisCellList = analysisCache.get(currentUniqueDataFlag);
if (analysisCellList != null) { if (analysisCellList != null) {
return analysisCellList; return analysisCellList;
} }
Sheet sheet = writeContext.writeSheetHolder().getCachedSheet(); Sheet sheet = writeContext.writeSheetHolder().getCachedSheet();
Map<String, Set<Integer>> firstRowCache = MapUtils.newHashMapWithExpectedSize(8); Map<UniqueDataFlagKey, Set<Integer>> firstRowCache = MapUtils.newHashMapWithExpectedSize(8);
for (int i = 0; i <= sheet.getLastRowNum(); i++) { for (int i = 0; i <= sheet.getLastRowNum(); i++) {
Row row = sheet.getRow(i); Row row = sheet.getRow(i);
if (row == null) { if (row == null) {
@ -425,7 +462,8 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
* @param firstRowCache first row cache * @param firstRowCache first row cache
* @return Returns the data that the cell needs to replace * @return Returns the data that the cell needs to replace
*/ */
private String prepareData(Cell cell, int rowIndex, int columnIndex, Map<String, Set<Integer>> firstRowCache) { private String prepareData(Cell cell, int rowIndex, int columnIndex,
Map<UniqueDataFlagKey, Set<Integer>> firstRowCache) {
if (!CellType.STRING.equals(cell.getCellType())) { if (!CellType.STRING.equals(cell.getCellType())) {
return null; return null;
} }
@ -508,7 +546,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
} }
private String dealAnalysisCell(AnalysisCell analysisCell, String value, int rowIndex, int lastPrepareDataIndex, private String dealAnalysisCell(AnalysisCell analysisCell, String value, int rowIndex, int lastPrepareDataIndex,
int length, Map<String, Set<Integer>> firstRowCache, StringBuilder preparedData) { int length, Map<UniqueDataFlagKey, Set<Integer>> firstRowCache, StringBuilder preparedData) {
if (analysisCell != null) { if (analysisCell != null) {
if (lastPrepareDataIndex == length) { if (lastPrepareDataIndex == length) {
analysisCell.getPrepareDataList().add(StringUtils.EMPTY); analysisCell.getPrepareDataList().add(StringUtils.EMPTY);
@ -516,7 +554,8 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
analysisCell.getPrepareDataList().add(convertPrepareData(value.substring(lastPrepareDataIndex))); analysisCell.getPrepareDataList().add(convertPrepareData(value.substring(lastPrepareDataIndex)));
analysisCell.setOnlyOneVariable(Boolean.FALSE); analysisCell.setOnlyOneVariable(Boolean.FALSE);
} }
String uniqueDataFlag = uniqueDataFlag(writeContext.writeSheetHolder(), analysisCell.getPrefix()); UniqueDataFlagKey uniqueDataFlag = uniqueDataFlag(writeContext.writeSheetHolder(),
analysisCell.getPrefix());
if (WriteTemplateAnalysisCellTypeEnum.COMMON.equals(analysisCell.getCellType())) { if (WriteTemplateAnalysisCellTypeEnum.COMMON.equals(analysisCell.getCellType())) {
List<AnalysisCell> analysisCellList = templateAnalysisCache.computeIfAbsent(uniqueDataFlag, List<AnalysisCell> analysisCellList = templateAnalysisCache.computeIfAbsent(uniqueDataFlag,
key -> ListUtils.newArrayList()); key -> ListUtils.newArrayList());
@ -560,21 +599,17 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
return prepareData; return prepareData;
} }
private String uniqueDataFlag(WriteSheetHolder writeSheetHolder, String wrapperName) { private UniqueDataFlagKey uniqueDataFlag(WriteSheetHolder writeSheetHolder, String wrapperName) {
String prefix; return new UniqueDataFlagKey(writeSheetHolder.getSheetNo(), writeSheetHolder.getSheetName(), wrapperName);
if (writeSheetHolder.getSheetNo() != null) {
prefix = writeSheetHolder.getSheetNo().toString();
} else {
prefix = writeSheetHolder.getSheetName();
}
if (StringUtils.isEmpty(wrapperName)) {
return prefix + "-";
}
return prefix + "-" + wrapperName;
} }
private String tablePrefix(String uniqueDataFlag) { @Getter
return uniqueDataFlag.substring(0, uniqueDataFlag.indexOf("-") + 1); @Setter
@EqualsAndHashCode
@AllArgsConstructor
public static class UniqueDataFlagKey {
private Integer sheetNo;
private String sheetName;
private String wrapperName;
} }
} }

67
src/main/java/com/alibaba/excel/write/handler/chain/CellHandlerExecutionChain.java

@ -0,0 +1,67 @@
package com.alibaba.excel.write.handler.chain;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* Execute the cell handler chain
*
* @author Jiaju Zhuang
*/
@Getter
@Setter
@EqualsAndHashCode
public class CellHandlerExecutionChain {
/**
* next chain
*/
private CellHandlerExecutionChain next;
/**
* handler
*/
private CellWriteHandler handler;
public CellHandlerExecutionChain(CellWriteHandler handler) {
this.handler = handler;
}
public void beforeCellCreate(CellWriteHandlerContext context) {
this.handler.beforeCellCreate(context);
if (this.next != null) {
this.next.beforeCellCreate(context);
}
}
public void afterCellCreate(CellWriteHandlerContext context) {
this.handler.afterCellCreate(context);
if (this.next != null) {
this.next.afterCellCreate(context);
}
}
public void afterCellDataConverted(CellWriteHandlerContext context) {
this.handler.afterCellDataConverted(context);
if (this.next != null) {
this.next.afterCellDataConverted(context);
}
}
public void afterCellDispose(CellWriteHandlerContext context) {
this.handler.afterCellDispose(context);
if (this.next != null) {
this.next.afterCellDispose(context);
}
}
public void addLast(CellWriteHandler handler) {
CellHandlerExecutionChain context = this;
while (context.next != null) {
context = context.next;
}
context.next = new CellHandlerExecutionChain(handler);
}
}

60
src/main/java/com/alibaba/excel/write/handler/chain/RowHandlerExecutionChain.java

@ -0,0 +1,60 @@
package com.alibaba.excel.write.handler.chain;
import com.alibaba.excel.write.handler.RowWriteHandler;
import com.alibaba.excel.write.handler.context.RowWriteHandlerContext;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* Execute the row handler chain
*
* @author Jiaju Zhuang
*/
@Getter
@Setter
@EqualsAndHashCode
public class RowHandlerExecutionChain {
/**
* next chain
*/
private RowHandlerExecutionChain next;
/**
* handler
*/
private RowWriteHandler handler;
public RowHandlerExecutionChain(RowWriteHandler handler) {
this.handler = handler;
}
public void beforeRowCreate(RowWriteHandlerContext context) {
this.handler.beforeRowCreate(context);
if (this.next != null) {
this.next.beforeRowCreate(context);
}
}
public void afterRowCreate(RowWriteHandlerContext context) {
this.handler.afterRowCreate(context);
if (this.next != null) {
this.next.afterRowCreate(context);
}
}
public void afterRowDispose(RowWriteHandlerContext context) {
this.handler.afterRowDispose(context);
if (this.next != null) {
this.next.afterRowDispose(context);
}
}
public void addLast(RowWriteHandler handler) {
RowHandlerExecutionChain context = this;
while (context.next != null) {
context = context.next;
}
context.next = new RowHandlerExecutionChain(handler);
}
}

52
src/main/java/com/alibaba/excel/write/handler/chain/SheetHandlerExecutionChain.java

@ -0,0 +1,52 @@
package com.alibaba.excel.write.handler.chain;
import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.handler.context.SheetWriteHandlerContext;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* Execute the sheet handler chain
*
* @author Jiaju Zhuang
*/
@Getter
@Setter
@EqualsAndHashCode
public class SheetHandlerExecutionChain {
/**
* next chain
*/
private SheetHandlerExecutionChain next;
/**
* handler
*/
private SheetWriteHandler handler;
public SheetHandlerExecutionChain(SheetWriteHandler handler) {
this.handler = handler;
}
public void beforeSheetCreate(SheetWriteHandlerContext context) {
this.handler.beforeSheetCreate(context);
if (this.next != null) {
this.next.beforeSheetCreate(context);
}
}
public void afterSheetCreate(SheetWriteHandlerContext context) {
this.handler.afterSheetCreate(context);
if (this.next != null) {
this.next.afterSheetCreate(context);
}
}
public void addLast(SheetWriteHandler handler) {
SheetHandlerExecutionChain context = this;
while (context.next != null) {
context = context.next;
}
context.next = new SheetHandlerExecutionChain(handler);
}
}

61
src/main/java/com/alibaba/excel/write/handler/chain/WorkbookHandlerExecutionChain.java

@ -0,0 +1,61 @@
package com.alibaba.excel.write.handler.chain;
import com.alibaba.excel.write.handler.WorkbookWriteHandler;
import com.alibaba.excel.write.handler.context.WorkbookWriteHandlerContext;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* Execute the workbook handler chain
*
* @author Jiaju Zhuang
*/
@Getter
@Setter
@EqualsAndHashCode
public class WorkbookHandlerExecutionChain {
/**
* next chain
*/
private WorkbookHandlerExecutionChain next;
/**
* handler
*/
private WorkbookWriteHandler handler;
public WorkbookHandlerExecutionChain(WorkbookWriteHandler handler) {
this.handler = handler;
}
public void beforeWorkbookCreate(WorkbookWriteHandlerContext context) {
this.handler.beforeWorkbookCreate(context);
if (this.next != null) {
this.next.beforeWorkbookCreate(context);
}
}
public void afterWorkbookCreate(WorkbookWriteHandlerContext context) {
this.handler.afterWorkbookCreate(context);
if (this.next != null) {
this.next.afterWorkbookCreate(context);
}
}
public void afterWorkbookDispose(WorkbookWriteHandlerContext context) {
this.handler.afterWorkbookDispose(context);
if (this.next != null) {
this.next.afterWorkbookDispose(context);
}
}
public void addLast(WorkbookWriteHandler handler) {
WorkbookHandlerExecutionChain context = this;
while (context.next != null) {
context = context.next;
}
context.next = new WorkbookHandlerExecutionChain(handler);
}
}

59
src/main/java/com/alibaba/excel/write/handler/context/CellWriteHandlerContext.java

@ -3,15 +3,18 @@ package com.alibaba.excel.write.handler.context;
import java.util.List; import java.util.List;
import com.alibaba.excel.context.WriteContext; import com.alibaba.excel.context.WriteContext;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData; import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.write.handler.impl.FillStyleCellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder; import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import lombok.AllArgsConstructor; import lombok.EqualsAndHashCode;
import lombok.Data; import lombok.Getter;
import lombok.Setter;
import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Row;
@ -20,8 +23,9 @@ import org.apache.poi.ss.usermodel.Row;
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@AllArgsConstructor @Setter
@EqualsAndHashCode
public class CellWriteHandlerContext { public class CellWriteHandlerContext {
/** /**
* write context * write context
@ -43,6 +47,10 @@ public class CellWriteHandlerContext {
* row * row
*/ */
private Row row; private Row row;
/**
* index
*/
private Integer rowIndex;
/** /**
* cell * cell
*/ */
@ -78,4 +86,47 @@ public class CellWriteHandlerContext {
* Field annotation configuration information. * Field annotation configuration information.
*/ */
private ExcelContentProperty excelContentProperty; private ExcelContentProperty excelContentProperty;
/**
* The value of the original
*/
private Object originalValue;
/**
* The original field type
*/
private Class<?> originalFieldClass;
/**
* Target cell data type
*/
private CellDataTypeEnum targetCellDataType;
/**
* Ignore the filling pattern and the {@code FillStyleCellWriteHandler} will not work.
*
* @see FillStyleCellWriteHandler
*/
private Boolean ignoreFillStyle;
public CellWriteHandlerContext(WriteContext writeContext,
WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder,
WriteTableHolder writeTableHolder, Row row, Integer rowIndex, Cell cell, Integer columnIndex,
Integer relativeRowIndex, Head headData, List<WriteCellData<?>> cellDataList, WriteCellData<?> firstCellData,
Boolean head, ExcelContentProperty excelContentProperty) {
this.writeContext = writeContext;
this.writeWorkbookHolder = writeWorkbookHolder;
this.writeSheetHolder = writeSheetHolder;
this.writeTableHolder = writeTableHolder;
this.row = row;
this.rowIndex = rowIndex;
this.cell = cell;
this.columnIndex = columnIndex;
this.relativeRowIndex = relativeRowIndex;
this.headData = headData;
this.cellDataList = cellDataList;
this.firstCellData = firstCellData;
this.head = head;
this.excelContentProperty = excelContentProperty;
}
} }

8
src/main/java/com/alibaba/excel/write/handler/context/RowWriteHandlerContext.java

@ -6,7 +6,9 @@ import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Row;
/** /**
@ -14,7 +16,9 @@ import org.apache.poi.ss.usermodel.Row;
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
@AllArgsConstructor @AllArgsConstructor
public class RowWriteHandlerContext { public class RowWriteHandlerContext {
/** /**

8
src/main/java/com/alibaba/excel/write/handler/context/SheetWriteHandlerContext.java

@ -5,14 +5,18 @@ import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* sheet context * sheet context
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
@AllArgsConstructor @AllArgsConstructor
public class SheetWriteHandlerContext { public class SheetWriteHandlerContext {
/** /**

8
src/main/java/com/alibaba/excel/write/handler/context/WorkbookWriteHandlerContext.java

@ -4,14 +4,18 @@ import com.alibaba.excel.context.WriteContext;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* workbook context * workbook context
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
@AllArgsConstructor @AllArgsConstructor
public class WorkbookWriteHandlerContext { public class WorkbookWriteHandlerContext {
/** /**

10
src/main/java/com/alibaba/excel/write/handler/impl/FillStyleCellWriteHandler.java

@ -1,16 +1,14 @@
package com.alibaba.excel.write.handler.impl; package com.alibaba.excel.write.handler.impl;
import java.util.List;
import com.alibaba.excel.constant.OrderConstant; import com.alibaba.excel.constant.OrderConstant;
import com.alibaba.excel.metadata.data.WriteCellData; import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.util.BooleanUtils;
import com.alibaba.excel.write.handler.CellWriteHandler; import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext; import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import com.alibaba.excel.write.metadata.style.WriteCellStyle; import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.CellStyle;
/** /**
@ -28,12 +26,12 @@ public class FillStyleCellWriteHandler implements CellWriteHandler {
@Override @Override
public void afterCellDispose(CellWriteHandlerContext context) { public void afterCellDispose(CellWriteHandlerContext context) {
List<WriteCellData<?>> cellDataList = context.getCellDataList(); if (BooleanUtils.isTrue(context.getIgnoreFillStyle())) {
if (CollectionUtils.size(cellDataList) != 1) {
return; return;
} }
WriteCellData<?> cellData = context.getFirstCellData(); WriteCellData<?> cellData = context.getFirstCellData();
if (cellData.getAnalysisCell() != null && !cellData.getAnalysisCell().getOnlyOneVariable()) { if (cellData == null) {
return; return;
} }
WriteCellStyle writeCellStyle = cellData.getWriteCellStyle(); WriteCellStyle writeCellStyle = cellData.getWriteCellStyle();

8
src/main/java/com/alibaba/excel/write/metadata/WriteBasicParameter.java

@ -7,14 +7,18 @@ import java.util.List;
import com.alibaba.excel.metadata.BasicParameter; import com.alibaba.excel.metadata.BasicParameter;
import com.alibaba.excel.write.handler.WriteHandler; import com.alibaba.excel.write.handler.WriteHandler;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* Write basic parameter * Write basic parameter
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
**/ **/
@Data @Getter
@Setter
@EqualsAndHashCode
public class WriteBasicParameter extends BasicParameter { public class WriteBasicParameter extends BasicParameter {
/** /**
* Writes the head relative to the existing contents of the sheet. Indexes are zero-based. * Writes the head relative to the existing contents of the sheet. Indexes are zero-based.

8
src/main/java/com/alibaba/excel/write/metadata/WriteSheet.java

@ -1,13 +1,17 @@
package com.alibaba.excel.write.metadata; package com.alibaba.excel.write.metadata;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* Write sheet * Write sheet
* *
* @author jipengfei * @author jipengfei
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class WriteSheet extends WriteBasicParameter { public class WriteSheet extends WriteBasicParameter {
/** /**
* Starting from 0 * Starting from 0

8
src/main/java/com/alibaba/excel/write/metadata/WriteTable.java

@ -1,13 +1,17 @@
package com.alibaba.excel.write.metadata; package com.alibaba.excel.write.metadata;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* table * table
* *
* @author jipengfei * @author jipengfei
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class WriteTable extends WriteBasicParameter { public class WriteTable extends WriteBasicParameter {
/** /**
* Starting from 0 * Starting from 0

8
src/main/java/com/alibaba/excel/write/metadata/WriteWorkbook.java

@ -7,14 +7,18 @@ import java.nio.charset.Charset;
import com.alibaba.excel.support.ExcelTypeEnum; import com.alibaba.excel.support.ExcelTypeEnum;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* Workbook * Workbook
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
**/ **/
@Data @Getter
@Setter
@EqualsAndHashCode
public class WriteWorkbook extends WriteBasicParameter { public class WriteWorkbook extends WriteBasicParameter {
/** /**
* Excel type.The default is xlsx * Excel type.The default is xlsx

8
src/main/java/com/alibaba/excel/write/metadata/fill/AnalysisCell.java

@ -4,14 +4,18 @@ import java.util.List;
import com.alibaba.excel.enums.WriteTemplateAnalysisCellTypeEnum; import com.alibaba.excel.enums.WriteTemplateAnalysisCellTypeEnum;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* Read the cells of the template while populating the data. * Read the cells of the template while populating the data.
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
**/ **/
@Data @Getter
@Setter
@EqualsAndHashCode
public class AnalysisCell { public class AnalysisCell {
private int columnIndex; private int columnIndex;
private int rowIndex; private int rowIndex;

8
src/main/java/com/alibaba/excel/write/metadata/fill/FillConfig.java

@ -4,15 +4,19 @@ import com.alibaba.excel.enums.WriteDirectionEnum;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter;
/** /**
* Fill config * Fill config
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
**/ **/
@Data @Getter
@Setter
@EqualsAndHashCode
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor

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

@ -15,7 +15,6 @@ import com.alibaba.excel.converters.ConverterKeyBuild;
import com.alibaba.excel.converters.DefaultConverterLoader; import com.alibaba.excel.converters.DefaultConverterLoader;
import com.alibaba.excel.enums.HeadKindEnum; import com.alibaba.excel.enums.HeadKindEnum;
import com.alibaba.excel.event.NotRepeatExecutor; import com.alibaba.excel.event.NotRepeatExecutor;
import com.alibaba.excel.event.Order;
import com.alibaba.excel.metadata.AbstractHolder; import com.alibaba.excel.metadata.AbstractHolder;
import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
@ -28,6 +27,10 @@ import com.alibaba.excel.write.handler.RowWriteHandler;
import com.alibaba.excel.write.handler.SheetWriteHandler; import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.handler.WorkbookWriteHandler; import com.alibaba.excel.write.handler.WorkbookWriteHandler;
import com.alibaba.excel.write.handler.WriteHandler; import com.alibaba.excel.write.handler.WriteHandler;
import com.alibaba.excel.write.handler.chain.CellHandlerExecutionChain;
import com.alibaba.excel.write.handler.chain.RowHandlerExecutionChain;
import com.alibaba.excel.write.handler.chain.SheetHandlerExecutionChain;
import com.alibaba.excel.write.handler.chain.WorkbookHandlerExecutionChain;
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext; import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
import com.alibaba.excel.write.merge.LoopMergeStrategy; import com.alibaba.excel.write.merge.LoopMergeStrategy;
import com.alibaba.excel.write.merge.OnceAbsoluteMergeStrategy; import com.alibaba.excel.write.merge.OnceAbsoluteMergeStrategy;
@ -38,8 +41,10 @@ import com.alibaba.excel.write.style.AbstractVerticalCellStyleStrategy;
import com.alibaba.excel.write.style.column.AbstractHeadColumnWidthStyleStrategy; import com.alibaba.excel.write.style.column.AbstractHeadColumnWidthStyleStrategy;
import com.alibaba.excel.write.style.row.SimpleRowHeightStyleStrategy; import com.alibaba.excel.write.style.row.SimpleRowHeightStyleStrategy;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
/** /**
@ -47,7 +52,9 @@ import org.apache.commons.collections4.CollectionUtils;
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
@NoArgsConstructor @NoArgsConstructor
public abstract class AbstractWriteHolder extends AbstractHolder implements WriteHolder { public abstract class AbstractWriteHolder extends AbstractHolder implements WriteHolder {
/** /**
@ -62,15 +69,6 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ
* Excel head property * Excel head property
*/ */
private ExcelWriteHeadProperty excelWriteHeadProperty; private ExcelWriteHeadProperty excelWriteHeadProperty;
/**
* Write handler
*/
private Map<Class<? extends WriteHandler>, List<WriteHandler>> writeHandlerMap;
/**
* Own write handler.Created in the sheet in the workbook interceptors will not be executed because the workbook to
* create an event long past. So when initializing sheet, supplementary workbook event.
*/
private Map<Class<? extends WriteHandler>, List<WriteHandler>> ownWriteHandlerMap;
/** /**
* Use the default style.Default is true. * Use the default style.Default is true.
*/ */
@ -97,6 +95,43 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ
*/ */
private Collection<String> includeColumnFieldNames; private Collection<String> includeColumnFieldNames;
/**
* Write handler
*/
private List<WriteHandler> writeHandlerList;
/**
* Execute the workbook handler chain
* Created in the sheet in the workbook interceptors will not be executed because the workbook to
* create an event long past. So when initializing sheet, supplementary workbook event.
*/
public WorkbookHandlerExecutionChain ownWorkbookHandlerExecutionChain;
/**
* Execute the sheet handler chain
* Created in the sheet in the workbook interceptors will not be executed because the workbook to
* create an event long past. So when initializing sheet, supplementary workbook event.
*/
public SheetHandlerExecutionChain ownSheetHandlerExecutionChain;
/**
* Execute the workbook handler chain
*/
public WorkbookHandlerExecutionChain workbookHandlerExecutionChain;
/**
* Execute the sheet handler chain
*/
public SheetHandlerExecutionChain sheetHandlerExecutionChain;
/**
* Execute the row handler chain
*/
public RowHandlerExecutionChain rowHandlerExecutionChain;
/**
* Execute the cell handler chain
*/
public CellHandlerExecutionChain cellHandlerExecutionChain;
public AbstractWriteHolder(WriteBasicParameter writeBasicParameter, AbstractWriteHolder parentAbstractWriteHolder) { public AbstractWriteHolder(WriteBasicParameter writeBasicParameter, AbstractWriteHolder parentAbstractWriteHolder) {
super(writeBasicParameter, parentAbstractWriteHolder); super(writeBasicParameter, parentAbstractWriteHolder);
@ -169,7 +204,7 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ
this.excelWriteHeadProperty = new ExcelWriteHeadProperty(this, getClazz(), getHead()); this.excelWriteHeadProperty = new ExcelWriteHeadProperty(this, getClazz(), getHead());
// Set writeHandlerMap // Set writeHandlerMap
List<WriteHandler> handlerList = new ArrayList<WriteHandler>(); List<WriteHandler> handlerList = new ArrayList<>();
// Initialization Annotation // Initialization Annotation
initAnnotationConfig(handlerList, writeBasicParameter); initAnnotationConfig(handlerList, writeBasicParameter);
@ -178,16 +213,16 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ
&& !writeBasicParameter.getCustomWriteHandlerList().isEmpty()) { && !writeBasicParameter.getCustomWriteHandlerList().isEmpty()) {
handlerList.addAll(writeBasicParameter.getCustomWriteHandlerList()); handlerList.addAll(writeBasicParameter.getCustomWriteHandlerList());
} }
sortAndClearUpHandler(handlerList, true);
this.ownWriteHandlerMap = sortAndClearUpHandler(handlerList);
Map<Class<? extends WriteHandler>, List<WriteHandler>> parentWriteHandlerMap = null;
if (parentAbstractWriteHolder != null) { if (parentAbstractWriteHolder != null) {
parentWriteHandlerMap = parentAbstractWriteHolder.getWriteHandlerMap(); if (CollectionUtils.isNotEmpty(parentAbstractWriteHolder.getWriteHandlerList())) {
handlerList.addAll(parentAbstractWriteHolder.getWriteHandlerList());
}
} else { } else {
handlerList.addAll(DefaultWriteHandlerLoader.loadDefaultHandler(useDefaultStyle)); handlerList.addAll(DefaultWriteHandlerLoader.loadDefaultHandler(useDefaultStyle));
} }
this.writeHandlerMap = sortAndClearUpAllHandler(handlerList, parentWriteHandlerMap); sortAndClearUpHandler(handlerList, false);
// Set converterMap // Set converterMap
if (parentAbstractWriteHolder == null) { if (parentAbstractWriteHolder == null) {
@ -212,15 +247,11 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ
} }
Map<Integer, Head> headMap = getExcelWriteHeadProperty().getHeadMap(); Map<Integer, Head> headMap = getExcelWriteHeadProperty().getHeadMap();
boolean hasColumnWidth = false; boolean hasColumnWidth = false;
boolean hasStyle = false;
for (Head head : headMap.values()) { for (Head head : headMap.values()) {
if (head.getColumnWidthProperty() != null) { if (head.getColumnWidthProperty() != null) {
hasColumnWidth = true; hasColumnWidth = true;
} }
if (head.getHeadStyleProperty() != null || head.getHeadFontProperty() != null) {
hasStyle = true;
}
dealLoopMerge(handlerList, head); dealLoopMerge(handlerList, head);
} }
@ -228,10 +259,7 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ
dealColumnWidth(handlerList); dealColumnWidth(handlerList);
} }
//if (hasStyle) {
dealStyle(handlerList); dealStyle(handlerList);
//}
dealRowHigh(handlerList); dealRowHigh(handlerList);
dealOnceAbsoluteMerge(handlerList); dealOnceAbsoluteMerge(handlerList);
} }
@ -310,38 +338,22 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ
handlerList.add(columnWidthStyleStrategy); handlerList.add(columnWidthStyleStrategy);
} }
protected Map<Class<? extends WriteHandler>, List<WriteHandler>> sortAndClearUpAllHandler( protected void sortAndClearUpHandler(List<WriteHandler> handlerList, boolean runOwn) {
List<WriteHandler> handlerList, Map<Class<? extends WriteHandler>, List<WriteHandler>> parentHandlerMap) {
// add
if (parentHandlerMap != null) {
List<WriteHandler> parentWriteHandler = parentHandlerMap.get(WriteHandler.class);
if (!CollectionUtils.isEmpty(parentWriteHandler)) {
handlerList.addAll(parentWriteHandler);
}
}
return sortAndClearUpHandler(handlerList);
}
protected Map<Class<? extends WriteHandler>, List<WriteHandler>> sortAndClearUpHandler(
List<WriteHandler> handlerList) {
// sort // sort
Map<Integer, List<WriteHandler>> orderExcelWriteHandlerMap = new TreeMap<Integer, List<WriteHandler>>(); Map<Integer, List<WriteHandler>> orderExcelWriteHandlerMap = new TreeMap<>();
for (WriteHandler handler : handlerList) { for (WriteHandler handler : handlerList) {
int order = Integer.MIN_VALUE; int order = handler.order();
if (handler instanceof Order) {
order = ((Order)handler).order();
}
if (orderExcelWriteHandlerMap.containsKey(order)) { if (orderExcelWriteHandlerMap.containsKey(order)) {
orderExcelWriteHandlerMap.get(order).add(handler); orderExcelWriteHandlerMap.get(order).add(handler);
} else { } else {
List<WriteHandler> tempHandlerList = new ArrayList<WriteHandler>(); List<WriteHandler> tempHandlerList = new ArrayList<>();
tempHandlerList.add(handler); tempHandlerList.add(handler);
orderExcelWriteHandlerMap.put(order, tempHandlerList); orderExcelWriteHandlerMap.put(order, tempHandlerList);
} }
} }
// clean up // clean up
Set<String> alreadyExistedHandlerSet = new HashSet<String>(); Set<String> alreadyExistedHandlerSet = new HashSet<>();
List<WriteHandler> cleanUpHandlerList = new ArrayList<WriteHandler>(); List<WriteHandler> cleanUpHandlerList = new ArrayList<>();
for (Map.Entry<Integer, List<WriteHandler>> entry : orderExcelWriteHandlerMap.entrySet()) { for (Map.Entry<Integer, List<WriteHandler>> entry : orderExcelWriteHandlerMap.entrySet()) {
for (WriteHandler handler : entry.getValue()) { for (WriteHandler handler : entry.getValue()) {
if (handler instanceof NotRepeatExecutor) { if (handler instanceof NotRepeatExecutor) {
@ -354,30 +366,70 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ
cleanUpHandlerList.add(handler); cleanUpHandlerList.add(handler);
} }
} }
// classify
Map<Class<? extends WriteHandler>, List<WriteHandler>> result = // build chain
new HashMap<Class<? extends WriteHandler>, List<WriteHandler>>(16); if (!runOwn) {
result.put(WriteHandler.class, new ArrayList<WriteHandler>()); this.writeHandlerList = new ArrayList<>();
result.put(WorkbookWriteHandler.class, new ArrayList<WriteHandler>()); }
result.put(SheetWriteHandler.class, new ArrayList<WriteHandler>());
result.put(RowWriteHandler.class, new ArrayList<WriteHandler>());
result.put(CellWriteHandler.class, new ArrayList<WriteHandler>());
for (WriteHandler writeHandler : cleanUpHandlerList) { for (WriteHandler writeHandler : cleanUpHandlerList) {
buildChain(writeHandler, runOwn);
}
}
protected void buildChain(WriteHandler writeHandler, boolean runOwn) {
if (writeHandler instanceof CellWriteHandler) { if (writeHandler instanceof CellWriteHandler) {
result.get(CellWriteHandler.class).add(writeHandler); if (!runOwn) {
if (cellHandlerExecutionChain == null) {
cellHandlerExecutionChain = new CellHandlerExecutionChain((CellWriteHandler)writeHandler);
} else {
cellHandlerExecutionChain.addLast((CellWriteHandler)writeHandler);
}
}
} }
if (writeHandler instanceof RowWriteHandler) { if (writeHandler instanceof RowWriteHandler) {
result.get(RowWriteHandler.class).add(writeHandler); if (!runOwn) {
if (rowHandlerExecutionChain == null) {
rowHandlerExecutionChain = new RowHandlerExecutionChain((RowWriteHandler)writeHandler);
} else {
rowHandlerExecutionChain.addLast((RowWriteHandler)writeHandler);
}
}
} }
if (writeHandler instanceof SheetWriteHandler) { if (writeHandler instanceof SheetWriteHandler) {
result.get(SheetWriteHandler.class).add(writeHandler); if (!runOwn) {
if (sheetHandlerExecutionChain == null) {
sheetHandlerExecutionChain = new SheetHandlerExecutionChain((SheetWriteHandler)writeHandler);
} else {
sheetHandlerExecutionChain.addLast((SheetWriteHandler)writeHandler);
}
} else {
if (ownSheetHandlerExecutionChain == null) {
ownSheetHandlerExecutionChain = new SheetHandlerExecutionChain((SheetWriteHandler)writeHandler);
} else {
ownSheetHandlerExecutionChain.addLast((SheetWriteHandler)writeHandler);
}
}
} }
if (writeHandler instanceof WorkbookWriteHandler) { if (writeHandler instanceof WorkbookWriteHandler) {
result.get(WorkbookWriteHandler.class).add(writeHandler); if (!runOwn) {
if (workbookHandlerExecutionChain == null) {
workbookHandlerExecutionChain = new WorkbookHandlerExecutionChain(
(WorkbookWriteHandler)writeHandler);
} else {
workbookHandlerExecutionChain.addLast((WorkbookWriteHandler)writeHandler);
}
} else {
if (ownWorkbookHandlerExecutionChain == null) {
ownWorkbookHandlerExecutionChain = new WorkbookHandlerExecutionChain(
(WorkbookWriteHandler)writeHandler);
} else {
ownWorkbookHandlerExecutionChain.addLast((WorkbookWriteHandler)writeHandler);
}
} }
result.get(WriteHandler.class).add(writeHandler);
} }
return result; if (!runOwn) {
this.writeHandlerList.add(writeHandler);
}
} }
@Override @Override
@ -406,16 +458,6 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ
return getExcelWriteHeadProperty(); return getExcelWriteHeadProperty();
} }
@Override
public Map<Class<? extends WriteHandler>, List<WriteHandler>> writeHandlerMap() {
return getWriteHandlerMap();
}
@Override
public Map<Class<? extends WriteHandler>, List<WriteHandler>> ownWriteHandlerMap() {
return getOwnWriteHandlerMap();
}
@Override @Override
public boolean needHead() { public boolean needHead() {
return getNeedHead(); return getNeedHead();
@ -430,4 +472,5 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ
public boolean automaticMergeHead() { public boolean automaticMergeHead() {
return getAutomaticMergeHead(); return getAutomaticMergeHead();
} }
} }

18
src/main/java/com/alibaba/excel/write/metadata/holder/WriteHolder.java

@ -1,10 +1,6 @@
package com.alibaba.excel.write.metadata.holder; package com.alibaba.excel.write.metadata.holder;
import java.util.List;
import java.util.Map;
import com.alibaba.excel.metadata.ConfigurationHolder; import com.alibaba.excel.metadata.ConfigurationHolder;
import com.alibaba.excel.write.handler.WriteHandler;
import com.alibaba.excel.write.property.ExcelWriteHeadProperty; import com.alibaba.excel.write.property.ExcelWriteHeadProperty;
/** /**
@ -21,20 +17,6 @@ public interface WriteHolder extends ConfigurationHolder {
*/ */
ExcelWriteHeadProperty excelWriteHeadProperty(); ExcelWriteHeadProperty excelWriteHeadProperty();
/**
* What handler does the currently operated cell need to execute
*
* @return
*/
Map<Class<? extends WriteHandler>, List<WriteHandler>> writeHandlerMap();
/**
* create your own write handler.
*
* @return
*/
Map<Class<? extends WriteHandler>, List<WriteHandler>> ownWriteHandlerMap();
/** /**
* Is to determine if a field needs to be ignored * Is to determine if a field needs to be ignored
* *

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

@ -8,7 +8,7 @@ import com.alibaba.excel.enums.WriteLastRowTypeEnum;
import com.alibaba.excel.util.StringUtils; import com.alibaba.excel.util.StringUtils;
import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.excel.write.metadata.WriteSheet;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
@ -22,7 +22,9 @@ import org.apache.poi.xssf.usermodel.XSSFSheet;
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
@NoArgsConstructor @NoArgsConstructor
public class WriteSheetHolder extends AbstractWriteHolder { public class WriteSheetHolder extends AbstractWriteHolder {
/** /**

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

@ -3,14 +3,18 @@ package com.alibaba.excel.write.metadata.holder;
import com.alibaba.excel.enums.HolderEnum; import com.alibaba.excel.enums.HolderEnum;
import com.alibaba.excel.write.metadata.WriteTable; import com.alibaba.excel.write.metadata.WriteTable;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* sheet holder * sheet holder
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class WriteTableHolder extends AbstractWriteHolder { public class WriteTableHolder extends AbstractWriteHolder {
/*** /***
* poi sheet * poi sheet

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

@ -19,11 +19,15 @@ import com.alibaba.excel.util.FileUtils;
import com.alibaba.excel.util.IoUtils; import com.alibaba.excel.util.IoUtils;
import com.alibaba.excel.util.MapUtils; import com.alibaba.excel.util.MapUtils;
import com.alibaba.excel.util.StyleUtil; import com.alibaba.excel.util.StyleUtil;
import com.alibaba.excel.write.handler.context.WorkbookWriteHandlerContext;
import com.alibaba.excel.write.metadata.WriteWorkbook; import com.alibaba.excel.write.metadata.WriteWorkbook;
import com.alibaba.excel.write.metadata.style.WriteCellStyle; import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont; import com.alibaba.excel.write.metadata.style.WriteFont;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString.Exclude;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.usermodel.HSSFWorkbook;
@ -39,7 +43,9 @@ import org.apache.poi.xssf.usermodel.XSSFWorkbook;
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
@Slf4j @Slf4j
public class WriteWorkbookHolder extends AbstractWriteHolder { public class WriteWorkbookHolder extends AbstractWriteHolder {
/*** /***
@ -143,6 +149,12 @@ public class WriteWorkbookHolder extends AbstractWriteHolder {
*/ */
private Map<DataFormatData, Short> dataFormatMap; private Map<DataFormatData, Short> dataFormatMap;
/**
* handler context
*/
@Exclude
private WorkbookWriteHandlerContext workbookWriteHandlerContext;
public WriteWorkbookHolder(WriteWorkbook writeWorkbook) { public WriteWorkbookHolder(WriteWorkbook writeWorkbook) {
super(writeWorkbook, null); super(writeWorkbook, null);
this.writeWorkbook = writeWorkbook; this.writeWorkbook = writeWorkbook;
@ -253,8 +265,6 @@ public class WriteWorkbookHolder extends AbstractWriteHolder {
if (writeCellStyle == null) { if (writeCellStyle == null) {
return originCellStyle; return originCellStyle;
} }
WriteCellStyle tempWriteCellStyle = new WriteCellStyle();
WriteCellStyle.merge(writeCellStyle, tempWriteCellStyle);
short styleIndex = -1; short styleIndex = -1;
Font originFont = null; Font originFont = null;
@ -271,14 +281,17 @@ public class WriteWorkbookHolder extends AbstractWriteHolder {
Map<WriteCellStyle, CellStyle> cellStyleMap = cellStyleIndexMap.computeIfAbsent(styleIndex, Map<WriteCellStyle, CellStyle> cellStyleMap = cellStyleIndexMap.computeIfAbsent(styleIndex,
key -> MapUtils.newHashMap()); key -> MapUtils.newHashMap());
CellStyle cellStyle = cellStyleMap.get(tempWriteCellStyle); CellStyle cellStyle = cellStyleMap.get(writeCellStyle);
if (cellStyle != null) { if (cellStyle != null) {
return cellStyle; return cellStyle;
} }
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.info("create new style:{},{}", tempWriteCellStyle, originCellStyle); log.info("create new style:{},{}", writeCellStyle, originCellStyle);
} }
cellStyle = StyleUtil.buildCellStyle(workbook, originCellStyle, writeCellStyle); WriteCellStyle tempWriteCellStyle = new WriteCellStyle();
WriteCellStyle.merge(writeCellStyle, tempWriteCellStyle);
cellStyle = StyleUtil.buildCellStyle(workbook, originCellStyle, tempWriteCellStyle);
Short dataFormat = createDataFormat(tempWriteCellStyle.getDataFormatData(), useCache); Short dataFormat = createDataFormat(tempWriteCellStyle.getDataFormatData(), useCache);
if (dataFormat != null) { if (dataFormat != null) {
cellStyle.setDataFormat(dataFormat); cellStyle.setDataFormat(dataFormat);

8
src/main/java/com/alibaba/excel/write/metadata/style/WriteCellStyle.java

@ -6,7 +6,9 @@ import com.alibaba.excel.metadata.property.FontProperty;
import com.alibaba.excel.metadata.property.StyleProperty; import com.alibaba.excel.metadata.property.StyleProperty;
import com.alibaba.excel.util.StringUtils; import com.alibaba.excel.util.StringUtils;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.apache.poi.ss.usermodel.BorderStyle; import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.FillPatternType; import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.HorizontalAlignment; import org.apache.poi.ss.usermodel.HorizontalAlignment;
@ -19,7 +21,9 @@ import org.apache.poi.ss.usermodel.VerticalAlignment;
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class WriteCellStyle { public class WriteCellStyle {
/** /**
* Set the data format (must be a valid format). Built in formats are defined at {@link BuiltinFormats}. * Set the data format (must be a valid format). Built in formats are defined at {@link BuiltinFormats}.

8
src/main/java/com/alibaba/excel/write/metadata/style/WriteFont.java

@ -2,7 +2,9 @@ package com.alibaba.excel.write.metadata.style;
import com.alibaba.excel.util.StringUtils; import com.alibaba.excel.util.StringUtils;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.apache.poi.common.usermodel.fonts.FontCharset; import org.apache.poi.common.usermodel.fonts.FontCharset;
import org.apache.poi.hssf.usermodel.HSSFPalette; import org.apache.poi.hssf.usermodel.HSSFPalette;
import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.usermodel.Font;
@ -13,7 +15,9 @@ import org.apache.poi.ss.usermodel.IndexedColors;
* *
* @author jipengfei * @author jipengfei
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class WriteFont { public class WriteFont {
/** /**
* The name for the font (i.e. Arial) * The name for the font (i.e. Arial)

19
src/main/java/com/alibaba/excel/write/property/ExcelWriteHeadProperty.java

@ -7,6 +7,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentLoopMerge; import com.alibaba.excel.annotation.write.style.ContentLoopMerge;
import com.alibaba.excel.annotation.write.style.ContentRowHeight; import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import com.alibaba.excel.annotation.write.style.HeadFontStyle; import com.alibaba.excel.annotation.write.style.HeadFontStyle;
@ -17,6 +18,7 @@ import com.alibaba.excel.enums.HeadKindEnum;
import com.alibaba.excel.metadata.CellRange; import com.alibaba.excel.metadata.CellRange;
import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.Holder; import com.alibaba.excel.metadata.Holder;
import com.alibaba.excel.metadata.property.ColumnWidthProperty;
import com.alibaba.excel.metadata.property.ExcelHeadProperty; import com.alibaba.excel.metadata.property.ExcelHeadProperty;
import com.alibaba.excel.metadata.property.FontProperty; import com.alibaba.excel.metadata.property.FontProperty;
import com.alibaba.excel.metadata.property.LoopMergeProperty; import com.alibaba.excel.metadata.property.LoopMergeProperty;
@ -24,14 +26,18 @@ import com.alibaba.excel.metadata.property.OnceAbsoluteMergeProperty;
import com.alibaba.excel.metadata.property.RowHeightProperty; import com.alibaba.excel.metadata.property.RowHeightProperty;
import com.alibaba.excel.metadata.property.StyleProperty; import com.alibaba.excel.metadata.property.StyleProperty;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* Define the header attribute of excel * Define the header attribute of excel
* *
* @author jipengfei * @author jipengfei
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class ExcelWriteHeadProperty extends ExcelHeadProperty { public class ExcelWriteHeadProperty extends ExcelHeadProperty {
private RowHeightProperty headRowHeightProperty; private RowHeightProperty headRowHeightProperty;
@ -50,9 +56,11 @@ public class ExcelWriteHeadProperty extends ExcelHeadProperty {
this.onceAbsoluteMergeProperty = this.onceAbsoluteMergeProperty =
OnceAbsoluteMergeProperty.build(headClazz.getAnnotation(OnceAbsoluteMerge.class)); OnceAbsoluteMergeProperty.build(headClazz.getAnnotation(OnceAbsoluteMerge.class));
ColumnWidth parentColumnWidth = headClazz.getAnnotation(ColumnWidth.class);
HeadStyle parentHeadStyle = headClazz.getAnnotation(HeadStyle.class); HeadStyle parentHeadStyle = headClazz.getAnnotation(HeadStyle.class);
HeadFontStyle parentHeadFontStyle = headClazz.getAnnotation(HeadFontStyle.class); HeadFontStyle parentHeadFontStyle = headClazz.getAnnotation(HeadFontStyle.class);
for (Map.Entry<Integer, Head> entry : getHeadMap().entrySet()) { for (Map.Entry<Integer, Head> entry : getHeadMap().entrySet()) {
Head headData = entry.getValue(); Head headData = entry.getValue();
if (headData == null) { if (headData == null) {
@ -61,6 +69,13 @@ public class ExcelWriteHeadProperty extends ExcelHeadProperty {
} }
Field field = headData.getField(); Field field = headData.getField();
ColumnWidth columnWidth = field.getAnnotation(ColumnWidth.class);
if (columnWidth == null) {
columnWidth = parentColumnWidth;
}
headData.setColumnWidthProperty(ColumnWidthProperty.build(columnWidth));
HeadStyle headStyle = field.getAnnotation(HeadStyle.class); HeadStyle headStyle = field.getAnnotation(HeadStyle.class);
if (headStyle == null) { if (headStyle == null) {
headStyle = parentHeadStyle; headStyle = parentHeadStyle;

8
src/main/java/com/alibaba/excel/write/style/HorizontalCellStyleStrategy.java

@ -7,7 +7,9 @@ import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext; import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
import com.alibaba.excel.write.metadata.style.WriteCellStyle; import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
/** /**
@ -15,7 +17,9 @@ import org.apache.commons.collections4.CollectionUtils;
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class HorizontalCellStyleStrategy extends AbstractCellStyleStrategy { public class HorizontalCellStyleStrategy extends AbstractCellStyleStrategy {
private WriteCellStyle headWriteCellStyle; private WriteCellStyle headWriteCellStyle;

16
src/test/java/com/alibaba/easyexcel/test/core/annotation/AnnotationData.java

@ -10,22 +10,28 @@ import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentRowHeight; import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import com.alibaba.excel.annotation.write.style.HeadRowHeight; import com.alibaba.excel.annotation.write.style.HeadRowHeight;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@ColumnWidth(30) @Setter
@HeadRowHeight(15) @EqualsAndHashCode
@ContentRowHeight(20) @ColumnWidth(50)
@HeadRowHeight(50)
@ContentRowHeight(100)
public class AnnotationData { public class AnnotationData {
@ExcelProperty("日期") @ExcelProperty("日期")
@DateTimeFormat("yyyy年MM月dd日HH时mm分ss秒") @DateTimeFormat("yyyy年MM月dd日HH时mm分ss秒")
private Date date; private Date date;
@ExcelProperty(value = "数字") @ExcelProperty(value = "数字")
@NumberFormat("#.##%") @NumberFormat("#.##%")
private Double number; private Double number;
@ExcelIgnore @ExcelIgnore
private String ignore; private String ignore;
private static final String staticFinal = "test"; private static final String staticFinal = "test";

19
src/test/java/com/alibaba/easyexcel/test/core/annotation/AnnotationDataTest.java

@ -8,6 +8,11 @@ import com.alibaba.easyexcel.test.util.TestFileUtil;
import com.alibaba.excel.EasyExcel; import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.util.DateUtils; import com.alibaba.excel.util.DateUtils;
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.junit.Assert;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
@ -46,6 +51,20 @@ public class AnnotationDataTest {
EasyExcel.write().file(file).head(AnnotationData.class).sheet().doWrite(data()); EasyExcel.write().file(file).head(AnnotationData.class).sheet().doWrite(data());
EasyExcel.read().file(file).head(AnnotationData.class).registerReadListener(new AnnotationDataListener()) EasyExcel.read().file(file).head(AnnotationData.class).registerReadListener(new AnnotationDataListener())
.sheet().doRead(); .sheet().doRead();
if (file == fileCsv) {
return;
}
Workbook workbook = WorkbookFactory.create(file);
Sheet sheet = workbook.getSheetAt(0);
Assert.assertEquals(50 * 256, sheet.getColumnWidth(0), 0);
Row row0 = sheet.getRow(0);
Assert.assertEquals(1000, row0.getHeight(), 0);
Row row1 = sheet.getRow(1);
Assert.assertEquals(2000, row1.getHeight(), 0);
} }
private List<AnnotationData> data() throws Exception { private List<AnnotationData> data() throws Exception {

8
src/test/java/com/alibaba/easyexcel/test/core/annotation/AnnotationIndexAndNameData.java

@ -2,12 +2,16 @@ package com.alibaba.easyexcel.test.core.annotation;
import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class AnnotationIndexAndNameData { public class AnnotationIndexAndNameData {
@ExcelProperty(value = "第四个", index = 4) @ExcelProperty(value = "第四个", index = 4)
private String index4; private String index4;

8
src/test/java/com/alibaba/easyexcel/test/core/celldata/CellDataReadData.java

@ -3,12 +3,16 @@ package com.alibaba.easyexcel.test.core.celldata;
import com.alibaba.excel.annotation.format.DateTimeFormat; import com.alibaba.excel.annotation.format.DateTimeFormat;
import com.alibaba.excel.metadata.data.ReadCellData; import com.alibaba.excel.metadata.data.ReadCellData;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class CellDataReadData { public class CellDataReadData {
@DateTimeFormat("yyyy年MM月dd日") @DateTimeFormat("yyyy年MM月dd日")
private ReadCellData<String> date; private ReadCellData<String> date;

8
src/test/java/com/alibaba/easyexcel/test/core/celldata/CellDataWriteData.java

@ -5,12 +5,16 @@ import java.util.Date;
import com.alibaba.excel.annotation.format.DateTimeFormat; import com.alibaba.excel.annotation.format.DateTimeFormat;
import com.alibaba.excel.metadata.data.WriteCellData; import com.alibaba.excel.metadata.data.WriteCellData;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class CellDataWriteData { public class CellDataWriteData {
@DateTimeFormat("yyyy年MM月dd日") @DateTimeFormat("yyyy年MM月dd日")
private WriteCellData<Date> date; private WriteCellData<Date> date;

8
src/test/java/com/alibaba/easyexcel/test/core/converter/ConverterReadData.java

@ -8,12 +8,16 @@ import java.util.Date;
import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.metadata.data.ReadCellData; import com.alibaba.excel.metadata.data.ReadCellData;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class ConverterReadData { public class ConverterReadData {
@ExcelProperty("日期") @ExcelProperty("日期")
private Date date; private Date date;

8
src/test/java/com/alibaba/easyexcel/test/core/converter/ConverterWriteData.java

@ -8,12 +8,16 @@ import java.util.Date;
import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.metadata.data.WriteCellData; import com.alibaba.excel.metadata.data.WriteCellData;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class ConverterWriteData { public class ConverterWriteData {
@ExcelProperty("日期") @ExcelProperty("日期")
private Date date; private Date date;

8
src/test/java/com/alibaba/easyexcel/test/core/converter/ImageData.java

@ -8,12 +8,16 @@ import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentRowHeight; import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import com.alibaba.excel.converters.string.StringImageConverter; import com.alibaba.excel.converters.string.StringImageConverter;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
@ContentRowHeight(500) @ContentRowHeight(500)
@ColumnWidth(500 / 8) @ColumnWidth(500 / 8)
public class ImageData { public class ImageData {

8
src/test/java/com/alibaba/easyexcel/test/core/converter/ReadAllConverterData.java

@ -5,12 +5,16 @@ import java.math.BigInteger;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Date; import java.util.Date;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class ReadAllConverterData { public class ReadAllConverterData {
private BigDecimal bigDecimalBoolean; private BigDecimal bigDecimalBoolean;
private BigDecimal bigDecimalNumber; private BigDecimal bigDecimalNumber;

8
src/test/java/com/alibaba/easyexcel/test/core/dataformat/DateFormatData.java

@ -1,11 +1,15 @@
package com.alibaba.easyexcel.test.core.dataformat; package com.alibaba.easyexcel.test.core.dataformat;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class DateFormatData { public class DateFormatData {
private String date; private String date;
private String dateStringCn; private String dateStringCn;

8
src/test/java/com/alibaba/easyexcel/test/core/encrypt/EncryptData.java

@ -2,12 +2,16 @@ package com.alibaba.easyexcel.test.core.encrypt;
import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class EncryptData { public class EncryptData {
@ExcelProperty("姓名") @ExcelProperty("姓名")
private String name; private String name;

8
src/test/java/com/alibaba/easyexcel/test/core/exception/ExceptionData.java

@ -2,12 +2,16 @@ package com.alibaba.easyexcel.test.core.exception;
import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class ExceptionData { public class ExceptionData {
@ExcelProperty("姓名") @ExcelProperty("姓名")
private String name; private String name;

8
src/test/java/com/alibaba/easyexcel/test/core/excludeorinclude/ExcludeOrIncludeData.java

@ -2,12 +2,16 @@ package com.alibaba.easyexcel.test.core.excludeorinclude;
import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class ExcludeOrIncludeData { public class ExcludeOrIncludeData {
@ExcelProperty(order = 1) @ExcelProperty(order = 1)
private String column1; private String column1;

8
src/test/java/com/alibaba/easyexcel/test/core/extra/ExtraData.java

@ -1,11 +1,15 @@
package com.alibaba.easyexcel.test.core.extra; package com.alibaba.easyexcel.test.core.extra;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class ExtraData { public class ExtraData {
private String row1; private String row1;

8
src/test/java/com/alibaba/easyexcel/test/core/fill/FillData.java

@ -4,12 +4,16 @@ import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.NumberFormat; import com.alibaba.excel.annotation.format.NumberFormat;
import com.alibaba.excel.converters.doubleconverter.DoubleStringConverter; import com.alibaba.excel.converters.doubleconverter.DoubleStringConverter;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class FillData { public class FillData {
private String name; private String name;
@NumberFormat("#") @NumberFormat("#")

8
src/test/java/com/alibaba/easyexcel/test/core/fill/style/FillStyleAnnotatedData.java

@ -7,12 +7,16 @@ import com.alibaba.excel.annotation.write.style.ContentStyle;
import com.alibaba.excel.enums.BooleanEnum; import com.alibaba.excel.enums.BooleanEnum;
import com.alibaba.excel.enums.poi.FillPatternTypeEnum; import com.alibaba.excel.enums.poi.FillPatternTypeEnum;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class FillStyleAnnotatedData { public class FillStyleAnnotatedData {
@ContentStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 13) @ContentStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 13)
@ContentFontStyle(bold = BooleanEnum.TRUE, color = 19) @ContentFontStyle(bold = BooleanEnum.TRUE, color = 19)

8
src/test/java/com/alibaba/easyexcel/test/core/fill/style/FillStyleData.java

@ -2,12 +2,16 @@ package com.alibaba.easyexcel.test.core.fill.style;
import java.util.Date; import java.util.Date;
import lombok.Data; import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/** /**
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Getter
@Setter
@EqualsAndHashCode
public class FillStyleData { public class FillStyleData {
private String name; private String name;
private Double number; private Double number;

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save