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比较有名的框架有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多一点
![img](img/readme/large.png)
@ -41,7 +41,7 @@ Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.0.1</version>
<version>3.0.2</version>
</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>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.0.1</version>
<version>3.0.2</version>
<packaging>jar</packaging>
<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
setStylesTable(xlsxReadWorkbookHolder, xssfReader);
sheetList = new ArrayList<ReadSheet>();
sheetMap = new HashMap<Integer, InputStream>();
commentsTableMap = new HashMap<Integer, CommentsTable>();
sheetList = new ArrayList<>();
sheetMap = new HashMap<>();
commentsTableMap = new HashMap<>();
XSSFReader.SheetIterator ite = (XSSFReader.SheetIterator)xssfReader.getSheetsData();
int index = 0;
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 com.alibaba.excel.constant.BuiltinFormats;
import com.alibaba.excel.constant.ExcelXmlConstants;
import com.alibaba.excel.context.xlsx.XlsxReadContext;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.data.DataFormatData;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.read.metadata.holder.xlsx.XlsxReadSheetHolder;
import com.alibaba.excel.util.BooleanUtils;
import com.alibaba.excel.util.PositionUtils;
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;
/**
@ -51,17 +47,9 @@ public class CellTagHandler extends AbstractXlsxTagHandler {
} else {
dateFormatIndexInteger = Integer.parseInt(dateFormatIndex);
}
StylesTable stylesTable = xlsxReadContext.xlsxReadWorkbookHolder().getStylesTable();
if (stylesTable == null) {
return;
}
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);
xlsxReadSheetHolder.getTempCellData().setDataFormatData(
xlsxReadContext.xlsxReadWorkbookHolder().dataFormatData(dateFormatIndexInteger));
}
@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.DateUtils;
import com.alibaba.excel.util.FileUtils;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.util.NumberDataFormatterUtils;
import com.alibaba.excel.util.StringUtils;
import com.alibaba.excel.util.WorkBookUtil;
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.WriteTable;
import com.alibaba.excel.write.metadata.WriteWorkbook;
@ -83,13 +88,16 @@ public class WriteContextImpl implements WriteContext {
LOGGER.debug("Begin to Initialization 'WriteContextImpl'");
}
initCurrentWorkbookHolder(writeWorkbook);
WriteHandlerUtils.beforeWorkbookCreate(this);
WorkbookWriteHandlerContext workbookWriteHandlerContext = WriteHandlerUtils.createWorkbookWriteHandlerContext(
this);
WriteHandlerUtils.beforeWorkbookCreate(workbookWriteHandlerContext);
try {
WorkBookUtil.createWorkBook(writeWorkbookHolder);
} catch (Exception e) {
throw new ExcelGenerateException("Create workbook failure", e);
}
WriteHandlerUtils.afterWorkbookCreate(this);
WriteHandlerUtils.afterWorkbookCreate(workbookWriteHandlerContext);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Initialization 'WriteContextImpl' complete");
}
@ -118,8 +126,10 @@ public class WriteContextImpl implements WriteContext {
initCurrentSheetHolder(writeSheet);
// Workbook handler need to supplementary execution
WriteHandlerUtils.beforeWorkbookCreate(this, true);
WriteHandlerUtils.afterWorkbookCreate(this, true);
WorkbookWriteHandlerContext workbookWriteHandlerContext = WriteHandlerUtils.createWorkbookWriteHandlerContext(
this);
WriteHandlerUtils.beforeWorkbookCreate(workbookWriteHandlerContext, true);
WriteHandlerUtils.afterWorkbookCreate(workbookWriteHandlerContext, true);
// Initialization current sheet
initSheet(writeType);
@ -162,7 +172,8 @@ public class WriteContextImpl implements WriteContext {
}
private void initSheet(WriteTypeEnum writeType) {
WriteHandlerUtils.beforeSheetCreate(this);
SheetWriteHandlerContext sheetWriteHandlerContext = WriteHandlerUtils.createSheetWriteHandlerContext(this);
WriteHandlerUtils.beforeSheetCreate(sheetWriteHandlerContext);
Sheet currentSheet;
try {
if (writeSheetHolder.getSheetNo() != null) {
@ -192,7 +203,7 @@ public class WriteContextImpl implements WriteContext {
currentSheet = createSheet();
}
writeSheetHolder.setSheet(currentSheet);
WriteHandlerUtils.afterSheetCreate(this);
WriteHandlerUtils.afterSheetCreate(sheetWriteHandlerContext);
if (WriteTypeEnum.ADD.equals(writeType)) {
// Initialization head
initHead(writeSheetHolder.excelWriteHeadProperty());
@ -226,11 +237,17 @@ public class WriteContextImpl implements WriteContext {
}
for (int relativeRowIndex = 0, i = newRowIndex; i < excelWriteHeadProperty.getHeadRowNumber()
+ 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);
WriteHandlerUtils.afterRowCreate(this, row, relativeRowIndex, Boolean.TRUE);
addOneRowOfHeadDataToExcel(row, excelWriteHeadProperty.getHeadMap(), relativeRowIndex);
WriteHandlerUtils.afterRowDispose(this, row, relativeRowIndex, Boolean.TRUE);
rowWriteHandlerContext.setRow(row);
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()) {
Head head = entry.getValue();
int columnIndex = entry.getKey();
ExcelContentProperty excelContentProperty = ClassUtils.declaredExcelContentProperty(null,
currentWriteHolder.excelWriteHeadProperty().getHeadClazz(), head.getFieldName());
WriteHandlerUtils.beforeCellCreate(this, row, head, columnIndex, relativeRowIndex, Boolean.TRUE,
excelContentProperty);
CellWriteHandlerContext cellWriteHandlerContext = WriteHandlerUtils.createCellWriteHandlerContext(this, row,
rowIndex, head, columnIndex, relativeRowIndex, Boolean.TRUE, excelContentProperty);
WriteHandlerUtils.beforeCellCreate(cellWriteHandlerContext);
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));
cell.setCellValue(writeCellData.getStringValue());
cellWriteHandlerContext.setCellDataList(ListUtils.newArrayList(writeCellData));
cellWriteHandlerContext.setFirstCellData(writeCellData);
WriteHandlerUtils.afterCellDispose(this, writeCellData, cell, head, relativeRowIndex, Boolean.TRUE,
excelContentProperty);
WriteHandlerUtils.afterCellDispose(cellWriteHandlerContext);
}
}
@ -288,10 +309,14 @@ public class WriteContextImpl implements WriteContext {
initCurrentTableHolder(writeTable);
// Workbook and sheet handler need to supplementary execution
WriteHandlerUtils.beforeWorkbookCreate(this, true);
WriteHandlerUtils.afterWorkbookCreate(this, true);
WriteHandlerUtils.beforeSheetCreate(this, true);
WriteHandlerUtils.afterSheetCreate(this, true);
WorkbookWriteHandlerContext workbookWriteHandlerContext = WriteHandlerUtils.createWorkbookWriteHandlerContext(
this);
WriteHandlerUtils.beforeWorkbookCreate(workbookWriteHandlerContext, true);
WriteHandlerUtils.afterWorkbookCreate(workbookWriteHandlerContext, true);
SheetWriteHandlerContext sheetWriteHandlerContext = WriteHandlerUtils.createSheetWriteHandlerContext(this);
WriteHandlerUtils.beforeSheetCreate(sheetWriteHandlerContext, true);
WriteHandlerUtils.afterSheetCreate(sheetWriteHandlerContext, true);
initHead(writeTableHolder.excelWriteHeadProperty());
}
@ -331,7 +356,7 @@ public class WriteContextImpl implements WriteContext {
return;
}
finished = true;
WriteHandlerUtils.afterWorkbookDispose(this);
WriteHandlerUtils.afterWorkbookDispose(writeWorkbookHolder.getWorkbookWriteHandlerContext());
if (writeWorkbookHolder == null) {
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.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.
*
@ -12,33 +17,37 @@ import com.alibaba.excel.util.MapUtils;
*/
public class ConverterKeyBuild {
private static final Map<String, String> BOXING_MAP = MapUtils.newHashMap();
private static final Map<Class<?>, Class<?>> BOXING_MAP = MapUtils.newHashMap();
static {
BOXING_MAP.put(int.class.getName(), Integer.class.getName());
BOXING_MAP.put(byte.class.getName(), Byte.class.getName());
BOXING_MAP.put(long.class.getName(), Long.class.getName());
BOXING_MAP.put(double.class.getName(), Double.class.getName());
BOXING_MAP.put(float.class.getName(), Float.class.getName());
BOXING_MAP.put(char.class.getName(), Character.class.getName());
BOXING_MAP.put(short.class.getName(), Short.class.getName());
BOXING_MAP.put(boolean.class.getName(), Boolean.class.getName());
BOXING_MAP.put(int.class, Integer.class);
BOXING_MAP.put(byte.class, Byte.class);
BOXING_MAP.put(long.class, Long.class);
BOXING_MAP.put(double.class, Double.class);
BOXING_MAP.put(float.class, Float.class);
BOXING_MAP.put(char.class, Character.class);
BOXING_MAP.put(short.class, Short.class);
BOXING_MAP.put(boolean.class, Boolean.class);
}
public static String buildKey(Class<?> clazz) {
String className = clazz.getName();
String boxingClassName = BOXING_MAP.get(clazz.getName());
if (boxingClassName == null) {
return className;
}
return boxingClassName;
public static ConverterKey buildKey(Class<?> clazz) {
return buildKey(clazz, null);
}
public static String buildKey(Class<?> clazz, CellDataTypeEnum cellDataTypeEnum) {
String key = buildKey(clazz);
if (cellDataTypeEnum == null) {
return key;
public static ConverterKey buildKey(Class<?> clazz, CellDataTypeEnum cellDataTypeEnum) {
Class<?> boxingClass = BOXING_MAP.get(clazz);
if (boxingClass != null) {
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 com.alibaba.excel.converters.ConverterKeyBuild.ConverterKey;
import com.alibaba.excel.converters.bigdecimal.BigDecimalBooleanConverter;
import com.alibaba.excel.converters.bigdecimal.BigDecimalNumberConverter;
import com.alibaba.excel.converters.bigdecimal.BigDecimalStringConverter;
@ -52,8 +53,8 @@ import com.alibaba.excel.util.MapUtils;
* @author Jiaju Zhuang
*/
public class DefaultConverterLoader {
private static Map<String, Converter<?>> defaultWriteConverter;
private static Map<String, Converter<?>> allConverter;
private static Map<ConverterKey, Converter<?>> defaultWriteConverter;
private static Map<ConverterKey, Converter<?>> allConverter;
static {
initDefaultWriteConverter();
@ -153,7 +154,7 @@ public class DefaultConverterLoader {
*
* @return
*/
public static Map<String, Converter<?>> loadDefaultWriteConverter() {
public static Map<ConverterKey, Converter<?>> loadDefaultWriteConverter() {
return defaultWriteConverter;
}
@ -171,7 +172,7 @@ public class DefaultConverterLoader {
*
* @return
*/
public static Map<String, Converter<?>> loadDefaultReadConverter() {
public static Map<ConverterKey, Converter<?>> loadDefaultReadConverter() {
return loadAllConverter();
}
@ -180,7 +181,7 @@ public class DefaultConverterLoader {
*
* @return
*/
public static Map<String, Converter<?>> loadAllConverter() {
public static Map<ConverterKey, Converter<?>> loadAllConverter() {
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 lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* read converter context
*
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
@AllArgsConstructor
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 lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/**
* write converter context
*
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
@NoArgsConstructor
@AllArgsConstructor
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.write.builder.ExcelWriterBuilder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* Data convert exception
*
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class ExcelDataConvertException extends RuntimeException {
/**
* NotNull.
@ -32,7 +36,7 @@ public class ExcelDataConvertException extends RuntimeException {
*/
private ExcelContentProperty excelContentProperty;
public ExcelDataConvertException(Integer rowIndex, Integer columnIndex, CellData cellData,
public ExcelDataConvertException(Integer rowIndex, Integer columnIndex, CellData<?> cellData,
ExcelContentProperty excelContentProperty, String message) {
super(message);
this.rowIndex = rowIndex;
@ -41,7 +45,7 @@ public class ExcelDataConvertException extends RuntimeException {
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) {
super(message, cause);
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;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* cell
*
* @author Jiaju Zhuang
**/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class AbstractCell implements Cell {
/**
* 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 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.Setter;
/**
* Write/read holder
*
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
@NoArgsConstructor
public abstract class AbstractHolder implements ConfigurationHolder {
/**
@ -38,7 +43,7 @@ public abstract class AbstractHolder implements ConfigurationHolder {
* <p>
* Write key:
*/
private Map<String, Converter<?>> converterMap;
private Map<ConverterKey, Converter<?>> converterMap;
public AbstractHolder(BasicParameter basicParameter, AbstractHolder prentAbstractHolder) {
this.newInitialization = Boolean.TRUE;
@ -81,7 +86,7 @@ public abstract class AbstractHolder implements ConfigurationHolder {
}
@Override
public Map<String, Converter<?>> converterMap() {
public Map<ConverterKey, Converter<?>> converterMap() {
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 lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* Basic parameter
*
* @author Jiaju Zhuang
**/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class BasicParameter {
/**
* 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;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* @author jipengfei
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class CellRange {
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 com.alibaba.excel.converters.Converter;
import com.alibaba.excel.converters.ConverterKeyBuild.ConverterKey;
/**
*
* Get the corresponding holder
*
* @author Jiaju Zhuang
@ -13,7 +13,6 @@ import com.alibaba.excel.converters.Converter;
public interface ConfigurationHolder extends Holder {
/**
*
* 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
*/
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 lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* Global configuration
*
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class GlobalConfiguration {
/**
* 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.StyleProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* excel head
*
* @author Jiaju Zhuang
**/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class 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 lombok.AccessLevel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.apache.poi.ss.SpreadsheetVersion;
@ -29,7 +29,9 @@ import org.apache.poi.ss.util.CellRangeAddress;
*
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
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 lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Color;
@ -16,7 +18,9 @@ import org.apache.poi.ss.usermodel.VerticalAlignment;
*
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
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.List;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.poi.ss.usermodel.Cell;
@ -17,7 +19,9 @@ import org.apache.poi.ss.usermodel.Sheet;
*
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
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.StringUtils;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import org.apache.poi.ss.usermodel.AutoFilter;
@ -45,7 +47,9 @@ import org.apache.poi.ss.util.PaneInformation;
*
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class CsvSheet implements Sheet, Closeable {
/**
* 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.Locale;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.compress.utils.Lists;
import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.ss.formula.udf.UDFFinder;
@ -26,7 +28,9 @@ import org.apache.poi.ss.usermodel.Workbook;
*
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class CsvWorkbook implements Workbook {
/**
* 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.util.StringUtils;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* Excel internal cell data.
@ -15,7 +17,9 @@ import lombok.Data;
*
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class CellData<T> extends AbstractCell {
/**
* cell type

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

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

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

@ -1,13 +1,17 @@
package com.alibaba.excel.metadata.data;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* comment
*
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class CommentData extends ClientAnchorData {
/**
* 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;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* coordinate.
*
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class CoordinateData {
/**
* 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 lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* data format
*
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class DataFormatData {
/**
* index

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

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

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

@ -1,14 +1,17 @@
package com.alibaba.excel.metadata.data;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* hyperlink
*
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class HyperlinkData extends CoordinateData {
/**
* 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;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* image
*
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
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 lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/**
* read cell data
*
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
@NoArgsConstructor
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 lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/**
* rich text string
*
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
@NoArgsConstructor
public class RichTextStringData {
private String textString;
@ -25,7 +29,9 @@ public class RichTextStringData {
this.textString = textString;
}
@Data
@Getter
@Setter
@EqualsAndHashCode
@AllArgsConstructor
public static class IntervalFont {
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.util.ListUtils;
import com.alibaba.excel.write.metadata.fill.AnalysisCell;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.apache.poi.ss.usermodel.CellStyle;
/**
@ -20,7 +21,9 @@ import org.apache.poi.ss.usermodel.CellStyle;
*
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
@NoArgsConstructor
public class WriteCellData<T> extends CellData<T> {
/**
@ -56,10 +59,6 @@ public class WriteCellData<T> extends CellData<T> {
*/
private CellStyle originCellStyle;
/**
* Only in the case of the fill is not null
*/
private AnalysisCell analysisCell;
public WriteCellData(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 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
* ("#").
@ -644,8 +646,7 @@ public class DataFormatter {
*/
private String getFormattedNumberString(BigDecimal data, Short dataFormat, String dataFormatString) {
Format numberFormat = getFormat(data.doubleValue(), dataFormat, dataFormatString);
String formatted = numberFormat.format(data);
return formatted.replaceFirst("E(\\d)", "E+$1"); // to match Excel's E-notation
return E_NOTATION_PATTERN.matcher(numberFormat.format(data)).replaceFirst("E+$1");
}
/**

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.util.BooleanUtils;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* Configuration from annotations
*
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class DateTimeFormatProperty {
private String format;
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 lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* @author jipengfei
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class 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.write.metadata.holder.AbstractWriteHolder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -27,7 +29,9 @@ import org.slf4j.LoggerFactory;
*
* @author jipengfei
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class ExcelHeadProperty {
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.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.hssf.usermodel.HSSFPalette;
import org.apache.poi.ss.usermodel.Font;
@ -15,7 +17,9 @@ import org.apache.poi.ss.usermodel.IndexedColors;
*
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class FontProperty {
/**
* 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.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.BuiltinFormats;
import org.apache.poi.ss.usermodel.FillPatternType;
@ -19,7 +21,9 @@ import org.apache.poi.ss.usermodel.VerticalAlignment;
*
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class StyleProperty {
/**
* 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);
}
Map<Integer, Head> headMap = excelReadHeadProperty.getHeadMap();
Map<String, Object> map = MapUtils.newHashMapWithExpectedSize(headMap.size());
BeanMap dataMap = BeanMapUtils.create(resultModel);
for (Map.Entry<Integer, Head> entry : headMap.entrySet()) {
Integer index = entry.getKey();
@ -105,10 +104,9 @@ public class ModelBuildEventListener implements ReadListener<Map<Integer, ReadCe
ClassUtils.declaredExcelContentProperty(dataMap, readSheetHolder.excelReadHeadProperty().getHeadClazz(),
fieldName), readSheetHolder.converterMap(), context, context.readRowHolder().getRowIndex(), index);
if (value != null) {
map.put(fieldName, value);
dataMap.put(fieldName, value);
}
}
dataMap.putAll(map);
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.read.listener.ReadListener;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* Read basic parameter
*
* @author Jiaju Zhuang
**/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class ReadBasicParameter extends BasicParameter {
/**
* 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.support.ExcelTypeEnum;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* Workbook
*
* @author Jiaju Zhuang
**/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class ReadWorkbook extends ReadBasicParameter {
/**
* 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.util.ListUtils;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/**
* Read Holder
*
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
@NoArgsConstructor
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.read.metadata.ReadSheet;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/**
* sheet holder
*
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
@NoArgsConstructor
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.support.ExcelTypeEnum;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/**
* Workbook holder
*
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
@NoArgsConstructor
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.ReadWorkbookHolder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* sheet holder
*
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class CsvReadSheetHolder extends ReadSheetHolder {
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.support.ExcelTypeEnum;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.csv.CSVFormat;
/**
@ -12,7 +14,9 @@ import org.apache.commons.csv.CSVFormat;
*
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class CsvReadWorkbookHolder extends ReadWorkbookHolder {
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.ReadWorkbookHolder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* sheet holder
*
* @author Jiaju Zhuang
*/
@Getter
@Setter
@EqualsAndHashCode
public class XlsxReadSheetHolder extends ReadSheetHolder {
/**
* Record the label of the current operation to prevent NPE.
@ -34,36 +41,4 @@ public class XlsxReadSheetHolder extends ReadSheetHolder {
super(readSheet, readWorkbookHolder);
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;
import javax.xml.parsers.SAXParserFactory;
import java.util.Map;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xssf.model.StylesTable;
import javax.xml.parsers.SAXParserFactory;
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.holder.ReadWorkbookHolder;
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
*
* @author Jiaju Zhuang
*/
@Getter
@Setter
@EqualsAndHashCode
public class XlsxReadWorkbookHolder extends ReadWorkbookHolder {
/**
* Package
@ -34,34 +46,30 @@ public class XlsxReadWorkbookHolder extends ReadWorkbookHolder {
* Current style information
*/
private StylesTable stylesTable;
/**
* cache data format
*/
private Map<Integer, DataFormatData> dataFormatDataCache;
public XlsxReadWorkbookHolder(ReadWorkbook readWorkbook) {
super(readWorkbook);
this.saxParserFactoryName = readWorkbook.getXlsxSAXParserFactoryName();
setExcelType(ExcelTypeEnum.XLSX);
dataFormatDataCache = MapUtils.newHashMap();
}
public OPCPackage getOpcPackage() {
return opcPackage;
public DataFormatData dataFormatData(int dateFormatIndexInteger) {
return dataFormatDataCache.computeIfAbsent(dateFormatIndexInteger, key -> {
DataFormatData dataFormatData = new DataFormatData();
if (stylesTable == null) {
return null;
}
public void setOpcPackage(OPCPackage opcPackage) {
this.opcPackage = opcPackage;
}
public String getSaxParserFactoryName() {
return saxParserFactoryName;
}
public void setSaxParserFactoryName(String saxParserFactoryName) {
this.saxParserFactoryName = saxParserFactoryName;
}
public StylesTable getStylesTable() {
return stylesTable;
XSSFCellStyle xssfCellStyle = stylesTable.getStyleAt(dateFormatIndexInteger);
dataFormatData.setIndex(xssfCellStyle.getDataFormat());
dataFormatData.setFormat(BuiltinFormats.getBuiltinFormat(dataFormatData.getIndex(),
xssfCellStyle.getDataFormatString(), globalConfiguration().getLocale()));
return dataFormatData;
});
}
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.write.metadata.holder.WriteHolder;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import net.sf.cglib.beans.BeanMap;
/**
@ -51,7 +55,7 @@ public class ClassUtils {
/**
* 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
@ -117,20 +121,8 @@ public class ClassUtils {
}
}
private static String buildKey(Class<?> clazz, Class<?> headClass, String fieldName) {
String key = "";
if (clazz != null) {
key += clazz.getName();
}
key += "-";
if (headClass != null) {
key += headClass.getName();
}
key += "-";
if (fieldName != null) {
key += fieldName;
}
return key;
private static ContentPropertyKey buildKey(Class<?> clazz, Class<?> headClass, String fieldName) {
return new ContentPropertyKey(clazz, headClass, fieldName);
}
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.converters.Converter;
import com.alibaba.excel.converters.ConverterKeyBuild;
import com.alibaba.excel.converters.ConverterKeyBuild.ConverterKey;
import com.alibaba.excel.converters.NullableObjectConverter;
import com.alibaba.excel.converters.ReadConverterContext;
import com.alibaba.excel.enums.CellDataTypeEnum;
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.property.ExcelContentProperty;
import com.alibaba.excel.read.metadata.holder.ReadSheetHolder;
@ -80,7 +82,7 @@ public class ConverterUtils {
* @return
*/
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) {
Class<?> clazz;
if (field == null) {
@ -88,7 +90,7 @@ public class ConverterUtils {
} else {
clazz = field.getType();
}
if (clazz == ReadCellData.class) {
if (clazz == CellData.class || clazz == ReadCellData.class) {
Class<?> classGeneric = getClassGeneric(field.getGenericType());
ReadCellData<Object> cellDataReturn = cellData.clone();
cellDataReturn.setData(doConvertToJavaObject(cellData, classGeneric, contentProperty, converterMap,
@ -126,7 +128,7 @@ public class ConverterUtils {
* @return
*/
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) {
Converter<?> converter = null;
if (contentProperty != null) {

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

@ -1,11 +1,7 @@
package com.alibaba.excel.util;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.poi.ss.util.CellReference;
/**
* @author jipengfei
*/
@ -18,14 +14,6 @@ public class 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) {
int row;
if (rowTagt != null) {
@ -37,47 +25,40 @@ public class PositionUtils {
}
return before + 1;
}
}
public static int getRow(String currentCellIndex) {
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;
}
if (currentCellIndex == null) {
return -1;
}
public static int getCol(String currentCellIndex, Integer before) {
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);
int firstNumber = currentCellIndex.length() - 1;
for (; firstNumber >= 0; firstNumber--) {
char c = currentCellIndex.charAt(firstNumber);
if (c < '0' || c > '9') {
break;
}
String col = matcher.group(1);
if (col.length() > 0 && col.charAt(0) == REDUNDANT_CHARACTERS) {
col = col.substring(1);
}
if (col.length() == 0) {
return -1;
} else {
return CellReference.convertColStringToIndex(col);
return Integer.parseUnsignedInt(currentCellIndex.substring(firstNumber + 1)) - 1;
}
} else {
public static int getCol(String currentCellIndex, Integer before) {
if (currentCellIndex == null) {
if (before == null) {
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;
import java.util.Optional;
import com.alibaba.excel.constant.BuiltinFormats;
import com.alibaba.excel.metadata.data.DataFormatData;
import com.alibaba.excel.metadata.data.HyperlinkData;
@ -189,7 +191,11 @@ public class StyleUtil {
xssfFont.setStrikeout(xssfOriginFont.getStrikeout());
// Colors cannot be overwritten
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.setUnderline(xssfOriginFont.getUnderline());

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

@ -1,24 +1,19 @@
package com.alibaba.excel.util;
import java.util.List;
import java.util.Map;
import com.alibaba.excel.context.WriteContext;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.handler.RowWriteHandler;
import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.handler.WorkbookWriteHandler;
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.RowWriteHandlerContext;
import com.alibaba.excel.write.handler.context.SheetWriteHandlerContext;
import com.alibaba.excel.write.handler.context.WorkbookWriteHandlerContext;
import com.alibaba.excel.write.metadata.holder.AbstractWriteHolder;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.ss.usermodel.Cell;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Row;
/**
@ -26,228 +21,162 @@ import org.apache.poi.ss.usermodel.Row;
*
* @author Jiaju Zhuang
*/
@Slf4j
public class WriteHandlerUtils {
private WriteHandlerUtils() {}
public static void beforeWorkbookCreate(WriteContext writeContext) {
beforeWorkbookCreate(writeContext, false);
public static WorkbookWriteHandlerContext createWorkbookWriteHandlerContext(WriteContext writeContext) {
WorkbookWriteHandlerContext context = new WorkbookWriteHandlerContext(writeContext,
writeContext.writeWorkbookHolder());
writeContext.writeWorkbookHolder().setWorkbookWriteHandlerContext(context);
return context;
}
public static void beforeWorkbookCreate(WriteContext writeContext, boolean runOwn) {
List<WriteHandler> handlerList = getHandlerList(writeContext, WorkbookWriteHandler.class, runOwn);
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) {
beforeWorkbookCreate(context, false);
}
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) {
afterWorkbookCreate(writeContext, false);
public static void afterWorkbookCreate(WorkbookWriteHandlerContext context) {
afterWorkbookCreate(context, false);
}
public static void afterWorkbookCreate(WriteContext writeContext, boolean runOwn) {
List<WriteHandler> handlerList = getHandlerList(writeContext, WorkbookWriteHandler.class, runOwn);
if (handlerList == null || handlerList.isEmpty()) {
return;
}
WorkbookWriteHandlerContext context = new WorkbookWriteHandlerContext(writeContext,
writeContext.writeWorkbookHolder());
for (WriteHandler writeHandler : handlerList) {
if (writeHandler instanceof WorkbookWriteHandler) {
((WorkbookWriteHandler)writeHandler).afterWorkbookCreate(context);
}
public static void afterWorkbookCreate(WorkbookWriteHandlerContext context, boolean runOwn) {
WorkbookHandlerExecutionChain workbookHandlerExecutionChain = getWorkbookHandlerExecutionChain(context, runOwn);
if (workbookHandlerExecutionChain != null) {
workbookHandlerExecutionChain.afterWorkbookCreate(context);
}
}
public static void afterWorkbookDispose(WriteContext writeContext) {
List<WriteHandler> handlerList =
writeContext.currentWriteHolder().writeHandlerMap().get(WorkbookWriteHandler.class);
if (handlerList == null || handlerList.isEmpty()) {
return;
private static WorkbookHandlerExecutionChain getWorkbookHandlerExecutionChain(WorkbookWriteHandlerContext context,
boolean runOwn) {
AbstractWriteHolder abstractWriteHolder = (AbstractWriteHolder)context.getWriteContext().currentWriteHolder();
if (runOwn) {
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) {
beforeSheetCreate(writeContext, false);
public static SheetWriteHandlerContext createSheetWriteHandlerContext(WriteContext writeContext) {
return new SheetWriteHandlerContext(writeContext, writeContext.writeWorkbookHolder(),
writeContext.writeSheetHolder());
}
public static void beforeSheetCreate(WriteContext writeContext, boolean runOwn) {
List<WriteHandler> handlerList = getHandlerList(writeContext, SheetWriteHandler.class, runOwn);
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) {
beforeSheetCreate(context, false);
}
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) {
afterSheetCreate(writeContext, false);
public static void afterSheetCreate(SheetWriteHandlerContext context) {
afterSheetCreate(context, false);
}
public static void afterSheetCreate(WriteContext writeContext, boolean runOwn) {
List<WriteHandler> handlerList = getHandlerList(writeContext, SheetWriteHandler.class, runOwn);
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).afterSheetCreate(context);
}
public static void afterSheetCreate(SheetWriteHandlerContext context, boolean runOwn) {
SheetHandlerExecutionChain sheetHandlerExecutionChain = getSheetHandlerExecutionChain(context, runOwn);
if (sheetHandlerExecutionChain != null) {
sheetHandlerExecutionChain.afterSheetCreate(context);
}
}
public static void beforeCellCreate(WriteContext writeContext, Row row, Head head, Integer columnIndex,
Integer relativeRowIndex, Boolean isHead, ExcelContentProperty excelContentProperty) {
List<WriteHandler> handlerList =
writeContext.currentWriteHolder().writeHandlerMap().get(CellWriteHandler.class);
if (handlerList == null || handlerList.isEmpty()) {
return;
}
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);
}
private static SheetHandlerExecutionChain getSheetHandlerExecutionChain(SheetWriteHandlerContext context,
boolean runOwn) {
AbstractWriteHolder abstractWriteHolder = (AbstractWriteHolder)context.getWriteContext().currentWriteHolder();
if (runOwn) {
return abstractWriteHolder.getOwnSheetHandlerExecutionChain();
} else {
return abstractWriteHolder.getSheetHandlerExecutionChain();
}
}
public static void afterCellCreate(WriteContext writeContext, 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;
}
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 CellWriteHandlerContext createCellWriteHandlerContext(WriteContext writeContext, Row row,
Integer rowIndex, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead,
ExcelContentProperty excelContentProperty) {
return new CellWriteHandlerContext(writeContext, writeContext.writeWorkbookHolder(),
writeContext.writeSheetHolder(), writeContext.writeTableHolder(), row, rowIndex, null, columnIndex,
relativeRowIndex, head, null, null, isHead, excelContentProperty);
}
public static void afterCellDataConverted(WriteContext writeContext, WriteCellData<?> cellData, 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;
}
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 beforeCellCreate(CellWriteHandlerContext context) {
CellHandlerExecutionChain cellHandlerExecutionChain = ((AbstractWriteHolder)context.getWriteContext()
.currentWriteHolder()).getCellHandlerExecutionChain();
if (cellHandlerExecutionChain != null) {
cellHandlerExecutionChain.beforeCellCreate(context);
}
}
public static void afterCellDispose(WriteContext writeContext, WriteCellData<?> cellData, Cell cell, Head head,
Integer relativeRowIndex, Boolean isHead, ExcelContentProperty excelContentProperty) {
List<WriteCellData<?>> cellDataList = cellData == null ? null : ListUtils.newArrayList(cellData);
afterCellDispose(writeContext, cellDataList, cell, head, relativeRowIndex, isHead, excelContentProperty);
public static void afterCellCreate(CellWriteHandlerContext context) {
CellHandlerExecutionChain cellHandlerExecutionChain = ((AbstractWriteHolder)context.getWriteContext()
.currentWriteHolder()).getCellHandlerExecutionChain();
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)) {
cellData = cellDataList.get(0);
public static void afterCellDataConverted(CellWriteHandlerContext context) {
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,
Boolean isHead) {
List<WriteHandler> handlerList = writeContext.currentWriteHolder().writeHandlerMap().get(RowWriteHandler.class);
if (handlerList == null || handlerList.isEmpty()) {
return;
}
RowWriteHandlerContext context = new RowWriteHandlerContext(writeContext, writeContext.writeWorkbookHolder(),
public static RowWriteHandlerContext createRowWriteHandlerContext(WriteContext writeContext, Integer rowIndex,
Integer relativeRowIndex, Boolean isHead) {
return new RowWriteHandlerContext(writeContext, writeContext.writeWorkbookHolder(),
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) {
List<WriteHandler> handlerList = writeContext.currentWriteHolder().writeHandlerMap().get(RowWriteHandler.class);
if (handlerList == null || handlerList.isEmpty()) {
return;
}
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 beforeRowCreate(RowWriteHandlerContext context) {
RowHandlerExecutionChain rowHandlerExecutionChain = ((AbstractWriteHolder)context.getWriteContext()
.currentWriteHolder()).getRowHandlerExecutionChain();
if (rowHandlerExecutionChain != null) {
rowHandlerExecutionChain.beforeRowCreate(context);
}
}
public static void afterRowDispose(WriteContext writeContext, Row row, Integer relativeRowIndex, Boolean isHead) {
List<WriteHandler> handlerList = writeContext.currentWriteHolder().writeHandlerMap().get(RowWriteHandler.class);
if (handlerList == null || handlerList.isEmpty()) {
return;
}
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);
}
public static void afterRowCreate(RowWriteHandlerContext context) {
RowHandlerExecutionChain rowHandlerExecutionChain = ((AbstractWriteHolder)context.getWriteContext()
.currentWriteHolder()).getRowHandlerExecutionChain();
if (rowHandlerExecutionChain != null) {
rowHandlerExecutionChain.afterRowCreate(context);
}
}
private static List<WriteHandler> getHandlerList(WriteContext writeContext, Class<? extends WriteHandler> clazz,
boolean runOwn) {
Map<Class<? extends WriteHandler>, List<WriteHandler>> writeHandlerMap;
if (runOwn) {
writeHandlerMap = writeContext.currentWriteHolder().ownWriteHandlerMap();
} else {
writeHandlerMap = writeContext.currentWriteHolder().writeHandlerMap();
public static void afterRowDispose(RowWriteHandlerContext context) {
RowHandlerExecutionChain rowHandlerExecutionChain = ((AbstractWriteHolder)context.getWriteContext()
.currentWriteHolder()).getRowHandlerExecutionChain();
if (rowHandlerExecutionChain != null) {
rowHandlerExecutionChain.afterRowDispose(context);
}
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.WriteConverterContext;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.exception.ExcelWriteDataConvertException;
import com.alibaba.excel.metadata.data.CommentData;
import com.alibaba.excel.metadata.data.FormulaData;
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.util.DateUtils;
import com.alibaba.excel.util.FileTypeUtils;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.util.StyleUtil;
import com.alibaba.excel.util.WorkBookUtil;
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.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.Hyperlink;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
/**
@ -47,124 +48,140 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor {
this.writeContext = writeContext;
}
protected WriteCellData<?> converterAndSet(WriteHolder currentWriteHolder, Class<?> clazz,
CellDataTypeEnum targetType, Cell cell, Object value, ExcelContentProperty excelContentProperty, Head head,
Integer relativeRowIndex, int rowIndex, int columnIndex) {
boolean needTrim = value != null && (value instanceof String && currentWriteHolder.globalConfiguration()
.getAutoTrim());
if (needTrim) {
value = ((String)value).trim();
}
WriteCellData<?> cellData = convert(currentWriteHolder, clazz, targetType, cell, value, excelContentProperty);
WriteHandlerUtils.afterCellDataConverted(writeContext, cellData, cell, head, relativeRowIndex, Boolean.FALSE,
excelContentProperty);
/**
* Transform the data and then to set into the cell
*
* @param cellWriteHandlerContext context
* @return
*/
protected void converterAndSet(CellWriteHandlerContext cellWriteHandlerContext) {
WriteCellData<?> cellData = convert(cellWriteHandlerContext);
cellWriteHandlerContext.setCellDataList(ListUtils.newArrayList(cellData));
cellWriteHandlerContext.setFirstCellData(cellData);
WriteHandlerUtils.afterCellDataConverted(cellWriteHandlerContext);
// Fill in picture information
fillImage(cell, cellData.getImageDataList());
fillImage(cellWriteHandlerContext, cellData.getImageDataList());
// Fill in comment information
fillComment(cell, cellData.getCommentData());
fillComment(cellWriteHandlerContext, cellData.getCommentData());
// Fill in hyper link information
fillHyperLink(cell, cellData.getHyperlinkData());
fillHyperLink(cellWriteHandlerContext, cellData.getHyperlinkData());
// Fill in formula information
fillFormula(cell, cellData.getFormulaData());
fillFormula(cellWriteHandlerContext, cellData.getFormulaData());
// Fill index
cellData.setRowIndex(rowIndex);
cellData.setColumnIndex(columnIndex);
cellData.setRowIndex(cellWriteHandlerContext.getRowIndex());
cellData.setColumnIndex(cellWriteHandlerContext.getColumnIndex());
if (cellData.getType() == null) {
cellData.setType(CellDataTypeEnum.EMPTY);
}
Cell cell = cellWriteHandlerContext.getCell();
switch (cellData.getType()) {
case STRING:
cell.setCellValue(cellData.getStringValue());
return cellData;
return;
case BOOLEAN:
cell.setCellValue(cellData.getBooleanValue());
return cellData;
return;
case NUMBER:
cell.setCellValue(cellData.getNumberValue().doubleValue());
return cellData;
return;
case DATE:
cell.setCellValue(cellData.getDateValue());
return cellData;
return;
case RICH_TEXT_STRING:
cell.setCellValue(StyleUtil
.buildRichTextString(writeContext.writeWorkbookHolder(), cellData.getRichTextStringDataValue()));
return cellData;
return;
case EMPTY:
return cellData;
return;
default:
throw new ExcelDataConvertException(cell.getRow().getRowNum(), cell.getColumnIndex(), cellData,
excelContentProperty, "Not supported data:" + value + " return type:" + cell.getCellType()
+ "at row:" + cell.getRow().getRowNum());
throw new ExcelWriteDataConvertException(cellWriteHandlerContext,
"Not supported data:" + cellWriteHandlerContext.getOriginalValue() + " return type:"
+ cellData.getType()
+ "at row:" + cellWriteHandlerContext.getRowIndex());
}
}
private void fillFormula(Cell cell, FormulaData formulaData) {
private void fillFormula(CellWriteHandlerContext cellWriteHandlerContext, FormulaData formulaData) {
if (formulaData == null) {
return;
}
Cell cell = cellWriteHandlerContext.getCell();
if (formulaData.getFormulaValue() != null) {
cell.setCellFormula(formulaData.getFormulaValue());
}
}
private void fillHyperLink(Cell cell, HyperlinkData hyperlinkData) {
private void fillHyperLink(CellWriteHandlerContext cellWriteHandlerContext, HyperlinkData hyperlinkData) {
if (hyperlinkData == null) {
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.setAddress(hyperlinkData.getAddress());
hyperlink.setFirstRow(StyleUtil.getCellCoordinate(cell.getRow().getRowNum(), hyperlinkData.getFirstRowIndex(),
hyperlink.setFirstRow(StyleUtil.getCellCoordinate(rowIndex, hyperlinkData.getFirstRowIndex(),
hyperlinkData.getRelativeFirstRowIndex()));
hyperlink.setFirstColumn(StyleUtil.getCellCoordinate(cell.getColumnIndex(), hyperlinkData.getFirstColumnIndex(),
hyperlink.setFirstColumn(StyleUtil.getCellCoordinate(columnIndex, hyperlinkData.getFirstColumnIndex(),
hyperlinkData.getRelativeFirstColumnIndex()));
hyperlink.setLastRow(StyleUtil.getCellCoordinate(cell.getRow().getRowNum(), hyperlinkData.getLastRowIndex(),
hyperlink.setLastRow(StyleUtil.getCellCoordinate(rowIndex, hyperlinkData.getLastRowIndex(),
hyperlinkData.getRelativeLastRowIndex()));
hyperlink.setLastColumn(StyleUtil.getCellCoordinate(cell.getColumnIndex(), hyperlinkData.getLastColumnIndex(),
hyperlink.setLastColumn(StyleUtil.getCellCoordinate(columnIndex, hyperlinkData.getLastColumnIndex(),
hyperlinkData.getRelativeLastColumnIndex()));
cell.setHyperlink(hyperlink);
}
private void fillComment(Cell cell, CommentData commentData) {
private void fillComment(CellWriteHandlerContext cellWriteHandlerContext, CommentData commentData) {
if (commentData == null) {
return;
}
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) {
anchor = new XSSFClientAnchor(StyleUtil.getCoordinate(commentData.getLeft()),
StyleUtil.getCoordinate(commentData.getTop()),
StyleUtil.getCoordinate(commentData.getRight()),
StyleUtil.getCoordinate(commentData.getBottom()),
StyleUtil.getCellCoordinate(cell.getColumnIndex(), commentData.getFirstColumnIndex(),
StyleUtil.getCellCoordinate(columnIndex, commentData.getFirstColumnIndex(),
commentData.getRelativeFirstColumnIndex()),
StyleUtil.getCellCoordinate(cell.getRow().getRowNum(), commentData.getFirstRowIndex(),
StyleUtil.getCellCoordinate(rowIndex, commentData.getFirstRowIndex(),
commentData.getRelativeFirstRowIndex()),
StyleUtil.getCellCoordinate(cell.getColumnIndex(), commentData.getLastColumnIndex(),
StyleUtil.getCellCoordinate(columnIndex, commentData.getLastColumnIndex(),
commentData.getRelativeLastColumnIndex()) + 1,
StyleUtil.getCellCoordinate(cell.getRow().getRowNum(), commentData.getLastRowIndex(),
StyleUtil.getCellCoordinate(rowIndex, commentData.getLastRowIndex(),
commentData.getRelativeLastRowIndex()) + 1);
} else {
anchor = new HSSFClientAnchor(StyleUtil.getCoordinate(commentData.getLeft()),
StyleUtil.getCoordinate(commentData.getTop()),
StyleUtil.getCoordinate(commentData.getRight()),
StyleUtil.getCoordinate(commentData.getBottom()),
(short)StyleUtil.getCellCoordinate(cell.getColumnIndex(), commentData.getFirstColumnIndex(),
(short)StyleUtil.getCellCoordinate(columnIndex, commentData.getFirstColumnIndex(),
commentData.getRelativeFirstColumnIndex()),
StyleUtil.getCellCoordinate(cell.getRow().getRowNum(), commentData.getFirstRowIndex(),
StyleUtil.getCellCoordinate(rowIndex, commentData.getFirstRowIndex(),
commentData.getRelativeFirstRowIndex()),
(short)(StyleUtil.getCellCoordinate(cell.getColumnIndex(), commentData.getLastColumnIndex(),
(short)(StyleUtil.getCellCoordinate(columnIndex, commentData.getLastColumnIndex(),
commentData.getRelativeLastColumnIndex()) + 1),
StyleUtil.getCellCoordinate(cell.getRow().getRowNum(), commentData.getLastRowIndex(),
StyleUtil.getCellCoordinate(rowIndex, commentData.getLastRowIndex(),
commentData.getRelativeLastRowIndex()) + 1);
}
Comment comment = cell.getSheet().createDrawingPatriarch().createCellComment(anchor);
Comment comment = sheet.createDrawingPatriarch().createCellComment(anchor);
if (commentData.getRichTextStringData() != null) {
comment.setString(
StyleUtil.buildRichTextString(writeContext.writeWorkbookHolder(), commentData.getRichTextStringData()));
@ -175,18 +192,22 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor {
cell.setCellComment(comment);
}
protected void fillImage(Cell cell, List<ImageData> imageDataList) {
protected void fillImage(CellWriteHandlerContext cellWriteHandlerContext, List<ImageData> imageDataList) {
if (CollectionUtils.isEmpty(imageDataList)) {
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();
if (drawing == null) {
drawing = sheet.createDrawingPatriarch();
}
CreationHelper helper = sheet.getWorkbook().getCreationHelper();
for (ImageData imageData : imageDataList) {
int index = sheet.getWorkbook().addPicture(imageData.getImage(),
int index = workbook.addPicture(imageData.getImage(),
FileTypeUtils.getImageTypeFormat(imageData.getImage()));
ClientAnchor anchor = helper.createClientAnchor();
if (imageData.getTop() != null) {
@ -201,13 +222,13 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor {
if (imageData.getLeft() != null) {
anchor.setDx1(StyleUtil.getCoordinate(imageData.getLeft()));
}
anchor.setRow1(StyleUtil.getCellCoordinate(cell.getRow().getRowNum(), imageData.getFirstRowIndex(),
anchor.setRow1(StyleUtil.getCellCoordinate(rowIndex, imageData.getFirstRowIndex(),
imageData.getRelativeFirstRowIndex()));
anchor.setCol1(StyleUtil.getCellCoordinate(cell.getColumnIndex(), imageData.getFirstColumnIndex(),
anchor.setCol1(StyleUtil.getCellCoordinate(columnIndex, imageData.getFirstColumnIndex(),
imageData.getRelativeFirstColumnIndex()));
anchor.setRow2(StyleUtil.getCellCoordinate(cell.getRow().getRowNum(), imageData.getLastRowIndex(),
anchor.setRow2(StyleUtil.getCellCoordinate(rowIndex, imageData.getLastRowIndex(),
imageData.getRelativeLastRowIndex()) + 1);
anchor.setCol2(StyleUtil.getCellCoordinate(cell.getColumnIndex(), imageData.getLastColumnIndex(),
anchor.setCol2(StyleUtil.getCellCoordinate(columnIndex, imageData.getLastColumnIndex(),
imageData.getRelativeLastColumnIndex()) + 1);
if (imageData.getAnchorType() != null) {
anchor.setAnchorType(imageData.getAnchorType().getValue());
@ -216,17 +237,16 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor {
}
}
protected WriteCellData<?> convert(WriteHolder currentWriteHolder, Class<?> clazz, CellDataTypeEnum targetType,
Cell cell, Object value, ExcelContentProperty excelContentProperty) {
protected WriteCellData<?> convert(CellWriteHandlerContext cellWriteHandlerContext) {
// This means that the user has defined the data.
if (clazz == WriteCellData.class) {
if (value == null) {
if (cellWriteHandlerContext.getOriginalFieldClass() == WriteCellData.class) {
if (cellWriteHandlerContext.getOriginalValue() == null) {
return new WriteCellData<>(CellDataTypeEnum.EMPTY);
}
WriteCellData<?> cellDataValue = (WriteCellData<?>)value;
WriteCellData<?> cellDataValue = (WriteCellData<?>)cellWriteHandlerContext.getOriginalValue();
if (cellDataValue.getType() != null) {
// Configuration information may not be read here
fillProperty(cellDataValue, excelContentProperty);
fillProperty(cellDataValue, cellWriteHandlerContext.getExcelContentProperty());
return cellDataValue;
} else {
@ -235,8 +255,7 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor {
return cellDataValue;
}
}
WriteCellData<?> cellDataReturn = doConvert(currentWriteHolder, cellDataValue.getData().getClass(),
targetType, cell, cellDataValue.getData(), excelContentProperty);
WriteCellData<?> cellDataReturn = doConvert(cellWriteHandlerContext);
if (cellDataValue.getImageDataList() != null) {
cellDataReturn.setImageDataList(cellDataValue.getImageDataList());
@ -256,7 +275,7 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor {
}
return cellDataReturn;
}
return doConvert(currentWriteHolder, clazz, targetType, cell, value, excelContentProperty);
return doConvert(cellWriteHandlerContext);
}
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,
Cell cell, Object value, ExcelContentProperty excelContentProperty) {
private WriteCellData<?> doConvert(CellWriteHandlerContext cellWriteHandlerContext) {
ExcelContentProperty excelContentProperty = cellWriteHandlerContext.getExcelContentProperty();
Converter<?> converter = null;
if (excelContentProperty != null) {
converter = excelContentProperty.getConverter();
@ -289,31 +309,34 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor {
if (converter == null) {
// csv is converted to string by default
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);
}
if (converter == null) {
throw new ExcelDataConvertException(cell.getRow().getRowNum(), cell.getColumnIndex(),
new WriteCellData<>(CellDataTypeEnum.EMPTY), excelContentProperty,
"Can not find 'Converter' support class " + clazz.getSimpleName() + ".");
throw new ExcelWriteDataConvertException(cellWriteHandlerContext,
"Can not find 'Converter' support class " + cellWriteHandlerContext.getOriginalFieldClass()
.getSimpleName() + ".");
}
WriteCellData<?> cellData;
try {
cellData = ((Converter<Object>)converter).convertToExcelData(
new WriteConverterContext<>(value, excelContentProperty, writeContext));
new WriteConverterContext<>(cellWriteHandlerContext.getOriginalValue(), excelContentProperty,
writeContext));
} catch (Exception e) {
throw new ExcelDataConvertException(cell.getRow().getRowNum(), cell.getColumnIndex(),
new WriteCellData<>(CellDataTypeEnum.EMPTY), excelContentProperty,
"Convert data:" + value + " error, at row:" + cell.getRow().getRowNum(), e);
throw new ExcelWriteDataConvertException(cellWriteHandlerContext,
"Convert data:" + cellWriteHandlerContext.getOriginalValue() + " error, at row:"
+ cellWriteHandlerContext.getRowIndex(), e);
}
if (cellData == null || cellData.getType() == null) {
throw new ExcelDataConvertException(cell.getRow().getRowNum(), cell.getColumnIndex(),
new WriteCellData<>(CellDataTypeEnum.EMPTY), excelContentProperty,
"Convert data:" + value + " return null, at row:" + cell.getRow().getRowNum());
throw new ExcelWriteDataConvertException(cellWriteHandlerContext,
"Convert data:" + cellWriteHandlerContext.getOriginalValue() + " return null, at row:"
+ cellWriteHandlerContext.getRowIndex());
}
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.enums.HeadKindEnum;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.util.BeanMapUtils;
import com.alibaba.excel.util.ClassUtils;
import com.alibaba.excel.util.FieldUtils;
import com.alibaba.excel.util.WorkBookUtil;
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.MapRowData;
import com.alibaba.excel.write.metadata.RowData;
@ -64,9 +65,14 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor {
if (oneRowData == null) {
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);
WriteHandlerUtils.afterRowCreate(writeContext, row, relativeRowIndex, Boolean.FALSE);
rowWriteHandlerContext.setRow(row);
WriteHandlerUtils.afterRowCreate(rowWriteHandlerContext);
if (oneRowData instanceof Collection<?>) {
addBasicTypeToExcel(new CollectionRowData((Collection<?>)oneRowData), row, rowIndex, relativeRowIndex);
@ -75,7 +81,8 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor {
} else {
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) {
@ -114,23 +121,30 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor {
writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadClazz(),
head == null ? null : head.getFieldName());
WriteHandlerUtils.beforeCellCreate(writeContext, row, head, columnIndex, relativeRowIndex, Boolean.FALSE,
excelContentProperty);
CellWriteHandlerContext cellWriteHandlerContext = WriteHandlerUtils.createCellWriteHandlerContext(writeContext,
row, rowIndex, head, columnIndex, relativeRowIndex, Boolean.FALSE, excelContentProperty);
WriteHandlerUtils.beforeCellCreate(cellWriteHandlerContext);
Cell cell = WorkBookUtil.createCell(row, columnIndex);
WriteHandlerUtils.afterCellCreate(writeContext, cell, head, relativeRowIndex, Boolean.FALSE,
excelContentProperty);
Object value = oneRowData.get(dataIndex);
WriteCellData<?> cellData = converterAndSet(writeContext.currentWriteHolder(),
FieldUtils.getFieldClass(value), null, cell, value, null, head, relativeRowIndex, rowIndex, columnIndex);
WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, head, relativeRowIndex, Boolean.FALSE,
excelContentProperty);
cellWriteHandlerContext.setCell(cell);
WriteHandlerUtils.afterCellCreate(cellWriteHandlerContext);
cellWriteHandlerContext.setOriginalValue(oneRowData.get(dataIndex));
cellWriteHandlerContext.setOriginalFieldClass(
FieldUtils.getFieldClass(cellWriteHandlerContext.getOriginalValue()));
converterAndSet(cellWriteHandlerContext);
WriteHandlerUtils.afterCellDispose(cellWriteHandlerContext);
}
private void addJavaObjectToExcel(Object oneRowData, Row row, int rowIndex, int relativeRowIndex,
Map<Integer, Field> sortedAllFiledMap) {
WriteHolder currentWriteHolder = writeContext.currentWriteHolder();
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;
// If it's a class it needs to be cast by type
if (HeadKindEnum.CLASS.equals(writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadKind())) {
@ -139,21 +153,28 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor {
int columnIndex = entry.getKey();
Head head = entry.getValue();
String name = head.getFieldName();
if (!beanMap.containsKey(name)) {
if (!beanKeySet.contains(name)) {
continue;
}
ExcelContentProperty excelContentProperty = ClassUtils.declaredExcelContentProperty(beanMap,
currentWriteHolder.excelWriteHeadProperty().getHeadClazz(), name);
WriteHandlerUtils.beforeCellCreate(writeContext, row, head, columnIndex, relativeRowIndex,
Boolean.FALSE, excelContentProperty);
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,
CellWriteHandlerContext cellWriteHandlerContext = WriteHandlerUtils.createCellWriteHandlerContext(
writeContext, row, rowIndex, head, columnIndex, relativeRowIndex, Boolean.FALSE,
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);
maxCellIndex = Math.max(maxCellIndex, columnIndex);
}
@ -169,7 +190,7 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor {
for (Map.Entry<Integer, Field> entry : sortedAllFiledMap.entrySet()) {
Field field = entry.getValue();
String filedName = FieldUtils.resolveCglibFieldName(field);
boolean uselessData = !beanMap.containsKey(filedName) || beanMapHandledSet.contains(filedName)
boolean uselessData = !beanKeySet.contains(filedName) || beanMapHandledSet.contains(filedName)
|| ignoreMap.containsKey(filedName);
if (uselessData) {
continue;
@ -177,18 +198,23 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor {
Object value = beanMap.get(filedName);
ExcelContentProperty excelContentProperty = ClassUtils.declaredExcelContentProperty(beanMap,
currentWriteHolder.excelWriteHeadProperty().getHeadClazz(), filedName);
WriteHandlerUtils.beforeCellCreate(writeContext, row, null, maxCellIndex, relativeRowIndex, Boolean.FALSE,
excelContentProperty);
CellWriteHandlerContext cellWriteHandlerContext = WriteHandlerUtils.createCellWriteHandlerContext(
writeContext, row, rowIndex, null, maxCellIndex, relativeRowIndex, Boolean.FALSE, excelContentProperty);
WriteHandlerUtils.beforeCellCreate(cellWriteHandlerContext);
// fix https://github.com/alibaba/easyexcel/issues/1870
// If there is data, it is written to the next cell
Cell cell = WorkBookUtil.createCell(row, maxCellIndex++);
WriteHandlerUtils.afterCellCreate(writeContext, cell, null, relativeRowIndex, Boolean.FALSE,
excelContentProperty);
WriteCellData<?> cellData = converterAndSet(currentWriteHolder,
FieldUtils.getFieldClass(beanMap, filedName, value), null, cell, value, null, null, relativeRowIndex,
rowIndex, maxCellIndex);
WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, null, relativeRowIndex, Boolean.FALSE,
excelContentProperty);
Cell cell = WorkBookUtil.createCell(row, maxCellIndex);
cellWriteHandlerContext.setCell(cell);
WriteHandlerUtils.afterCellCreate(cellWriteHandlerContext);
cellWriteHandlerContext.setOriginalValue(value);
cellWriteHandlerContext.setOriginalFieldClass(FieldUtils.getFieldClass(beanMap, filedName, value));
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.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
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.StringUtils;
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.FillConfig;
import com.alibaba.excel.write.metadata.fill.FillWrapper;
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.poi.hssf.usermodel.PoiUtils;
import org.apache.poi.ss.usermodel.Cell;
@ -53,29 +60,30 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
/**
* 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
*/
private final Map<String, List<AnalysisCell>> templateCollectionAnalysisCache = MapUtils.newHashMap();
private final Map<UniqueDataFlagKey, List<AnalysisCell>> templateCollectionAnalysisCache = MapUtils.newHashMap();
/**
* 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
*/
private final Map<String, Short> collectionRowHeightCache = MapUtils.newHashMap();
private final Map<UniqueDataFlagKey, Short> collectionRowHeightCache = MapUtils.newHashMap();
/**
* 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
*/
private String currentUniqueDataFlag;
private UniqueDataFlagKey currentUniqueDataFlag;
public ExcelWriteFillExecutor(WriteContext writeContext) {
super(writeContext);
@ -159,15 +167,16 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
sheet.shiftRows(maxRowIndex + 1, lastRowIndex, number, true, false);
// The current data is greater than unity rowindex increase
String tablePrefix = tablePrefix(currentUniqueDataFlag);
increaseRowIndex(templateAnalysisCache, number, maxRowIndex, tablePrefix);
increaseRowIndex(templateCollectionAnalysisCache, number, maxRowIndex, tablePrefix);
increaseRowIndex(templateAnalysisCache, number, maxRowIndex);
increaseRowIndex(templateCollectionAnalysisCache, number, maxRowIndex);
}
private void increaseRowIndex(Map<String, List<AnalysisCell>> templateAnalysisCache, int number, int maxRowIndex,
String tablePrefix) {
for (Map.Entry<String, List<AnalysisCell>> entry : templateAnalysisCache.entrySet()) {
if (!tablePrefix.equals(tablePrefix(entry.getKey()))) {
private void increaseRowIndex(Map<UniqueDataFlagKey, List<AnalysisCell>> templateAnalysisCache, int number,
int maxRowIndex) {
for (Map.Entry<UniqueDataFlagKey, List<AnalysisCell>> entry : templateAnalysisCache.entrySet()) {
UniqueDataFlagKey uniqueDataFlagKey = entry.getKey();
if (!Objects.equals(currentUniqueDataFlag.getSheetNo(), uniqueDataFlagKey.getSheetNo()) || !Objects.equals(
currentUniqueDataFlag.getSheetName(), uniqueDataFlagKey.getSheetName())) {
continue;
}
for (AnalysisCell analysisCell : entry.getValue()) {
@ -183,28 +192,35 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
if (CollectionUtils.isEmpty(analysisCellList) || oneRowData == null) {
return;
}
Map<?, ?> dataMap;
Map dataMap;
if (oneRowData instanceof Map) {
dataMap = (Map<?, ?>)oneRowData;
dataMap = (Map)oneRowData;
} else {
dataMap = BeanMapUtils.create(oneRowData);
}
WriteSheetHolder writeSheetHolder = writeContext.writeSheetHolder();
Set<String> dataKeySet = new HashSet<>(dataMap.keySet());
for (AnalysisCell analysisCell : analysisCellList) {
CellWriteHandlerContext cellWriteHandlerContext = WriteHandlerUtils.createCellWriteHandlerContext(
writeContext, null, analysisCell.getRowIndex(), null, analysisCell.getColumnIndex(),
relativeRowIndex, Boolean.FALSE, ExcelContentProperty.EMPTY);
if (analysisCell.getOnlyOneVariable()) {
String variable = analysisCell.getVariableList().get(0);
if (!dataMap.containsKey(variable)) {
if (!dataKeySet.contains(variable)) {
continue;
}
Object value = dataMap.get(variable);
ExcelContentProperty excelContentProperty = ClassUtils.declaredExcelContentProperty(dataMap,
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,
FieldUtils.getFieldClass(dataMap, variable, value), null, cell, value, excelContentProperty, null,
relativeRowIndex, analysisCell.getRowIndex(), analysisCell.getColumnIndex());
cellData.setAnalysisCell(analysisCell);
converterAndSet(cellWriteHandlerContext);
WriteCellData<?> cellData = cellWriteHandlerContext.getFirstCellData();
// Restyle
if (fillConfig.getAutoStyle()) {
@ -212,28 +228,33 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
.map(collectionFieldStyleMap -> collectionFieldStyleMap.get(analysisCell))
.ifPresent(cellData::setOriginCellStyle);
}
WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, null, relativeRowIndex, Boolean.FALSE,
excelContentProperty);
} else {
StringBuilder cellValueBuild = new StringBuilder();
int index = 0;
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()) {
cellValueBuild.append(analysisCell.getPrepareDataList().get(index++));
if (!dataMap.containsKey(variable)) {
if (!dataKeySet.contains(variable)) {
continue;
}
Object value = dataMap.get(variable);
ExcelContentProperty excelContentProperty = ClassUtils.declaredExcelContentProperty(dataMap,
writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadClazz(), variable);
WriteCellData<?> cellData = convert(writeSheetHolder,
FieldUtils.getFieldClass(dataMap, variable, value), CellDataTypeEnum.STRING, cell, value,
excelContentProperty);
cellData.setAnalysisCell(analysisCell);
cellWriteHandlerContext.setOriginalValue(value);
cellWriteHandlerContext.setOriginalFieldClass(FieldUtils.getFieldClass(dataMap, variable, value));
cellWriteHandlerContext.setExcelContentProperty(excelContentProperty);
cellWriteHandlerContext.setTargetCellDataType(CellDataTypeEnum.STRING);
WriteCellData<?> cellData = convert(cellWriteHandlerContext);
cellDataList.add(cellData);
CellDataTypeEnum type = cellData.getType();
if (type != null) {
switch (type) {
@ -253,6 +274,10 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
}
cellValueBuild.append(analysisCell.getPrepareDataList().get(index));
cell.setCellValue(cellValueBuild.toString());
cellWriteHandlerContext.setCellDataList(cellDataList);
if (CollectionUtils.isNotEmpty(cellDataList)) {
cellWriteHandlerContext.setFirstCellData(cellDataList.get(0));
}
// Restyle
if (fillConfig.getAutoStyle()) {
@ -260,10 +285,8 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
.map(collectionFieldStyleMap -> collectionFieldStyleMap.get(analysisCell))
.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;
}
private Cell getOneCell(AnalysisCell analysisCell, FillConfig fillConfig,
ExcelContentProperty excelContentProperty) {
private void createCell(AnalysisCell analysisCell, FillConfig fillConfig,
CellWriteHandlerContext cellWriteHandlerContext) {
Sheet cachedSheet = writeContext.writeSheetHolder().getCachedSheet();
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();
@ -320,25 +346,31 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
}
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) {
Map<AnalysisCell, CellStyle> collectionFieldStyleMap = collectionFieldStyleCache.computeIfAbsent(
currentUniqueDataFlag, key -> MapUtils.newHashMap());
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);
if (cell != null) {
return cell;
}
WriteHandlerUtils.beforeCellCreate(writeContext, row, null, lastColumnIndex, null, Boolean.FALSE,
excelContentProperty);
WriteHandlerUtils.beforeCellCreate(cellWriteHandlerContext);
cell = row.createCell(lastColumnIndex);
WriteHandlerUtils.afterCellCreate(writeContext, cell, null, null, Boolean.FALSE, excelContentProperty);
cellWriteHandlerContext.setCell(cell);
WriteHandlerUtils.afterCellCreate(cellWriteHandlerContext);
return cell;
}
@ -351,7 +383,10 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
}
row = cachedSheet.getRow(lastRowIndex);
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()) {
row = cachedSheet.createRow(lastRowIndex);
} else {
@ -364,8 +399,10 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
row = cachedSheet.createRow(lastRowIndex);
}
}
rowWriteHandlerContext.setRow(row);
checkRowHeight(analysisCell, fillConfig, isOriginalCell, row);
WriteHandlerUtils.afterRowCreate(writeContext, row, null, Boolean.FALSE);
WriteHandlerUtils.afterRowCreate(rowWriteHandlerContext);
} else {
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);
if (analysisCellList != null) {
return analysisCellList;
}
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++) {
Row row = sheet.getRow(i);
if (row == null) {
@ -425,7 +462,8 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
* @param firstRowCache first row cache
* @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())) {
return null;
}
@ -508,7 +546,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
}
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 (lastPrepareDataIndex == length) {
analysisCell.getPrepareDataList().add(StringUtils.EMPTY);
@ -516,7 +554,8 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
analysisCell.getPrepareDataList().add(convertPrepareData(value.substring(lastPrepareDataIndex)));
analysisCell.setOnlyOneVariable(Boolean.FALSE);
}
String uniqueDataFlag = uniqueDataFlag(writeContext.writeSheetHolder(), analysisCell.getPrefix());
UniqueDataFlagKey uniqueDataFlag = uniqueDataFlag(writeContext.writeSheetHolder(),
analysisCell.getPrefix());
if (WriteTemplateAnalysisCellTypeEnum.COMMON.equals(analysisCell.getCellType())) {
List<AnalysisCell> analysisCellList = templateAnalysisCache.computeIfAbsent(uniqueDataFlag,
key -> ListUtils.newArrayList());
@ -560,21 +599,17 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
return prepareData;
}
private String uniqueDataFlag(WriteSheetHolder writeSheetHolder, String wrapperName) {
String prefix;
if (writeSheetHolder.getSheetNo() != null) {
prefix = writeSheetHolder.getSheetNo().toString();
} else {
prefix = writeSheetHolder.getSheetName();
}
if (StringUtils.isEmpty(wrapperName)) {
return prefix + "-";
}
return prefix + "-" + wrapperName;
private UniqueDataFlagKey uniqueDataFlag(WriteSheetHolder writeSheetHolder, String wrapperName) {
return new UniqueDataFlagKey(writeSheetHolder.getSheetNo(), writeSheetHolder.getSheetName(), wrapperName);
}
private String tablePrefix(String uniqueDataFlag) {
return uniqueDataFlag.substring(0, uniqueDataFlag.indexOf("-") + 1);
@Getter
@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 com.alibaba.excel.context.WriteContext;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
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.WriteTableHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
@ -20,8 +23,9 @@ import org.apache.poi.ss.usermodel.Row;
*
* @author Jiaju Zhuang
*/
@Data
@AllArgsConstructor
@Getter
@Setter
@EqualsAndHashCode
public class CellWriteHandlerContext {
/**
* write context
@ -43,6 +47,10 @@ public class CellWriteHandlerContext {
* row
*/
private Row row;
/**
* index
*/
private Integer rowIndex;
/**
* cell
*/
@ -78,4 +86,47 @@ public class CellWriteHandlerContext {
* Field annotation configuration information.
*/
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 lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.apache.poi.ss.usermodel.Row;
/**
@ -14,7 +16,9 @@ import org.apache.poi.ss.usermodel.Row;
*
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
@AllArgsConstructor
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 lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* sheet context
*
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
@AllArgsConstructor
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 lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* workbook context
*
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
@AllArgsConstructor
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;
import java.util.List;
import com.alibaba.excel.constant.OrderConstant;
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.context.CellWriteHandlerContext;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.ss.usermodel.CellStyle;
/**
@ -28,12 +26,12 @@ public class FillStyleCellWriteHandler implements CellWriteHandler {
@Override
public void afterCellDispose(CellWriteHandlerContext context) {
List<WriteCellData<?>> cellDataList = context.getCellDataList();
if (CollectionUtils.size(cellDataList) != 1) {
if (BooleanUtils.isTrue(context.getIgnoreFillStyle())) {
return;
}
WriteCellData<?> cellData = context.getFirstCellData();
if (cellData.getAnalysisCell() != null && !cellData.getAnalysisCell().getOnlyOneVariable()) {
if (cellData == null) {
return;
}
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.write.handler.WriteHandler;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* Write basic parameter
*
* @author Jiaju Zhuang
**/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class WriteBasicParameter extends BasicParameter {
/**
* 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;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* Write sheet
*
* @author jipengfei
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class WriteSheet extends WriteBasicParameter {
/**
* Starting from 0

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

@ -1,13 +1,17 @@
package com.alibaba.excel.write.metadata;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* table
*
* @author jipengfei
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class WriteTable extends WriteBasicParameter {
/**
* 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 lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* Workbook
*
* @author Jiaju Zhuang
**/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class WriteWorkbook extends WriteBasicParameter {
/**
* 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 lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* Read the cells of the template while populating the data.
*
* @author Jiaju Zhuang
**/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class AnalysisCell {
private int columnIndex;
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.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/**
* Fill config
*
* @author Jiaju Zhuang
**/
@Data
@Getter
@Setter
@EqualsAndHashCode
@Builder
@NoArgsConstructor
@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.enums.HeadKindEnum;
import com.alibaba.excel.event.NotRepeatExecutor;
import com.alibaba.excel.event.Order;
import com.alibaba.excel.metadata.AbstractHolder;
import com.alibaba.excel.metadata.Head;
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.WorkbookWriteHandler;
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.merge.LoopMergeStrategy;
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.row.SimpleRowHeightStyleStrategy;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.apache.commons.collections4.CollectionUtils;
/**
@ -47,7 +52,9 @@ import org.apache.commons.collections4.CollectionUtils;
*
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
@NoArgsConstructor
public abstract class AbstractWriteHolder extends AbstractHolder implements WriteHolder {
/**
@ -62,15 +69,6 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ
* Excel head property
*/
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.
*/
@ -97,6 +95,43 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ
*/
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) {
super(writeBasicParameter, parentAbstractWriteHolder);
@ -169,7 +204,7 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ
this.excelWriteHeadProperty = new ExcelWriteHeadProperty(this, getClazz(), getHead());
// Set writeHandlerMap
List<WriteHandler> handlerList = new ArrayList<WriteHandler>();
List<WriteHandler> handlerList = new ArrayList<>();
// Initialization Annotation
initAnnotationConfig(handlerList, writeBasicParameter);
@ -178,16 +213,16 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ
&& !writeBasicParameter.getCustomWriteHandlerList().isEmpty()) {
handlerList.addAll(writeBasicParameter.getCustomWriteHandlerList());
}
sortAndClearUpHandler(handlerList, true);
this.ownWriteHandlerMap = sortAndClearUpHandler(handlerList);
Map<Class<? extends WriteHandler>, List<WriteHandler>> parentWriteHandlerMap = null;
if (parentAbstractWriteHolder != null) {
parentWriteHandlerMap = parentAbstractWriteHolder.getWriteHandlerMap();
if (CollectionUtils.isNotEmpty(parentAbstractWriteHolder.getWriteHandlerList())) {
handlerList.addAll(parentAbstractWriteHolder.getWriteHandlerList());
}
} else {
handlerList.addAll(DefaultWriteHandlerLoader.loadDefaultHandler(useDefaultStyle));
}
this.writeHandlerMap = sortAndClearUpAllHandler(handlerList, parentWriteHandlerMap);
sortAndClearUpHandler(handlerList, false);
// Set converterMap
if (parentAbstractWriteHolder == null) {
@ -212,15 +247,11 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ
}
Map<Integer, Head> headMap = getExcelWriteHeadProperty().getHeadMap();
boolean hasColumnWidth = false;
boolean hasStyle = false;
for (Head head : headMap.values()) {
if (head.getColumnWidthProperty() != null) {
hasColumnWidth = true;
}
if (head.getHeadStyleProperty() != null || head.getHeadFontProperty() != null) {
hasStyle = true;
}
dealLoopMerge(handlerList, head);
}
@ -228,10 +259,7 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ
dealColumnWidth(handlerList);
}
//if (hasStyle) {
dealStyle(handlerList);
//}
dealRowHigh(handlerList);
dealOnceAbsoluteMerge(handlerList);
}
@ -310,38 +338,22 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ
handlerList.add(columnWidthStyleStrategy);
}
protected Map<Class<? extends WriteHandler>, List<WriteHandler>> sortAndClearUpAllHandler(
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) {
protected void sortAndClearUpHandler(List<WriteHandler> handlerList, boolean runOwn) {
// sort
Map<Integer, List<WriteHandler>> orderExcelWriteHandlerMap = new TreeMap<Integer, List<WriteHandler>>();
Map<Integer, List<WriteHandler>> orderExcelWriteHandlerMap = new TreeMap<>();
for (WriteHandler handler : handlerList) {
int order = Integer.MIN_VALUE;
if (handler instanceof Order) {
order = ((Order)handler).order();
}
int order = handler.order();
if (orderExcelWriteHandlerMap.containsKey(order)) {
orderExcelWriteHandlerMap.get(order).add(handler);
} else {
List<WriteHandler> tempHandlerList = new ArrayList<WriteHandler>();
List<WriteHandler> tempHandlerList = new ArrayList<>();
tempHandlerList.add(handler);
orderExcelWriteHandlerMap.put(order, tempHandlerList);
}
}
// clean up
Set<String> alreadyExistedHandlerSet = new HashSet<String>();
List<WriteHandler> cleanUpHandlerList = new ArrayList<WriteHandler>();
Set<String> alreadyExistedHandlerSet = new HashSet<>();
List<WriteHandler> cleanUpHandlerList = new ArrayList<>();
for (Map.Entry<Integer, List<WriteHandler>> entry : orderExcelWriteHandlerMap.entrySet()) {
for (WriteHandler handler : entry.getValue()) {
if (handler instanceof NotRepeatExecutor) {
@ -354,30 +366,70 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ
cleanUpHandlerList.add(handler);
}
}
// classify
Map<Class<? extends WriteHandler>, List<WriteHandler>> result =
new HashMap<Class<? extends WriteHandler>, List<WriteHandler>>(16);
result.put(WriteHandler.class, new ArrayList<WriteHandler>());
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>());
// build chain
if (!runOwn) {
this.writeHandlerList = new ArrayList<>();
}
for (WriteHandler writeHandler : cleanUpHandlerList) {
buildChain(writeHandler, runOwn);
}
}
protected void buildChain(WriteHandler writeHandler, boolean runOwn) {
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) {
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) {
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) {
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
@ -406,16 +458,6 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ
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
public boolean needHead() {
return getNeedHead();
@ -430,4 +472,5 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ
public boolean automaticMergeHead() {
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;
import java.util.List;
import java.util.Map;
import com.alibaba.excel.metadata.ConfigurationHolder;
import com.alibaba.excel.write.handler.WriteHandler;
import com.alibaba.excel.write.property.ExcelWriteHeadProperty;
/**
@ -21,20 +17,6 @@ public interface WriteHolder extends ConfigurationHolder {
*/
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
*

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.write.metadata.WriteSheet;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@ -22,7 +22,9 @@ import org.apache.poi.xssf.usermodel.XSSFSheet;
*
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
@NoArgsConstructor
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.write.metadata.WriteTable;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* sheet holder
*
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class WriteTableHolder extends AbstractWriteHolder {
/***
* 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.MapUtils;
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.style.WriteCellStyle;
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 org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
@ -39,7 +43,9 @@ import org.apache.poi.xssf.usermodel.XSSFWorkbook;
*
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
@Slf4j
public class WriteWorkbookHolder extends AbstractWriteHolder {
/***
@ -143,6 +149,12 @@ public class WriteWorkbookHolder extends AbstractWriteHolder {
*/
private Map<DataFormatData, Short> dataFormatMap;
/**
* handler context
*/
@Exclude
private WorkbookWriteHandlerContext workbookWriteHandlerContext;
public WriteWorkbookHolder(WriteWorkbook writeWorkbook) {
super(writeWorkbook, null);
this.writeWorkbook = writeWorkbook;
@ -253,8 +265,6 @@ public class WriteWorkbookHolder extends AbstractWriteHolder {
if (writeCellStyle == null) {
return originCellStyle;
}
WriteCellStyle tempWriteCellStyle = new WriteCellStyle();
WriteCellStyle.merge(writeCellStyle, tempWriteCellStyle);
short styleIndex = -1;
Font originFont = null;
@ -271,14 +281,17 @@ public class WriteWorkbookHolder extends AbstractWriteHolder {
Map<WriteCellStyle, CellStyle> cellStyleMap = cellStyleIndexMap.computeIfAbsent(styleIndex,
key -> MapUtils.newHashMap());
CellStyle cellStyle = cellStyleMap.get(tempWriteCellStyle);
CellStyle cellStyle = cellStyleMap.get(writeCellStyle);
if (cellStyle != null) {
return cellStyle;
}
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);
if (dataFormat != null) {
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.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.FillPatternType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
@ -19,7 +21,9 @@ import org.apache.poi.ss.usermodel.VerticalAlignment;
*
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class WriteCellStyle {
/**
* 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 lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.apache.poi.common.usermodel.fonts.FontCharset;
import org.apache.poi.hssf.usermodel.HSSFPalette;
import org.apache.poi.ss.usermodel.Font;
@ -13,7 +15,9 @@ import org.apache.poi.ss.usermodel.IndexedColors;
*
* @author jipengfei
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class WriteFont {
/**
* 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.Set;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentLoopMerge;
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
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.Head;
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.FontProperty;
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.StyleProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* Define the header attribute of excel
*
* @author jipengfei
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class ExcelWriteHeadProperty extends ExcelHeadProperty {
private RowHeightProperty headRowHeightProperty;
@ -50,9 +56,11 @@ public class ExcelWriteHeadProperty extends ExcelHeadProperty {
this.onceAbsoluteMergeProperty =
OnceAbsoluteMergeProperty.build(headClazz.getAnnotation(OnceAbsoluteMerge.class));
ColumnWidth parentColumnWidth = headClazz.getAnnotation(ColumnWidth.class);
HeadStyle parentHeadStyle = headClazz.getAnnotation(HeadStyle.class);
HeadFontStyle parentHeadFontStyle = headClazz.getAnnotation(HeadFontStyle.class);
for (Map.Entry<Integer, Head> entry : getHeadMap().entrySet()) {
Head headData = entry.getValue();
if (headData == null) {
@ -61,6 +69,13 @@ public class ExcelWriteHeadProperty extends ExcelHeadProperty {
}
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);
if (headStyle == null) {
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.metadata.style.WriteCellStyle;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.collections4.CollectionUtils;
/**
@ -15,7 +17,9 @@ import org.apache.commons.collections4.CollectionUtils;
*
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class HorizontalCellStyleStrategy extends AbstractCellStyleStrategy {
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.HeadRowHeight;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* @author Jiaju Zhuang
*/
@Data
@ColumnWidth(30)
@HeadRowHeight(15)
@ContentRowHeight(20)
@Getter
@Setter
@EqualsAndHashCode
@ColumnWidth(50)
@HeadRowHeight(50)
@ContentRowHeight(100)
public class AnnotationData {
@ExcelProperty("日期")
@DateTimeFormat("yyyy年MM月dd日HH时mm分ss秒")
private Date date;
@ExcelProperty(value = "数字")
@NumberFormat("#.##%")
private Double number;
@ExcelIgnore
private String ignore;
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.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.Test;
@ -46,6 +51,20 @@ public class AnnotationDataTest {
EasyExcel.write().file(file).head(AnnotationData.class).sheet().doWrite(data());
EasyExcel.read().file(file).head(AnnotationData.class).registerReadListener(new AnnotationDataListener())
.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 {

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 lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class AnnotationIndexAndNameData {
@ExcelProperty(value = "第四个", index = 4)
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.metadata.data.ReadCellData;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class CellDataReadData {
@DateTimeFormat("yyyy年MM月dd日")
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.metadata.data.WriteCellData;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class CellDataWriteData {
@DateTimeFormat("yyyy年MM月dd日")
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.metadata.data.ReadCellData;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class ConverterReadData {
@ExcelProperty("日期")
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.metadata.data.WriteCellData;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class ConverterWriteData {
@ExcelProperty("日期")
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.converters.string.StringImageConverter;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
@ContentRowHeight(500)
@ColumnWidth(500 / 8)
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.util.Date;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class ReadAllConverterData {
private BigDecimal bigDecimalBoolean;
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;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class DateFormatData {
private String date;
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 lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class EncryptData {
@ExcelProperty("姓名")
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 lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class ExceptionData {
@ExcelProperty("姓名")
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 lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class ExcludeOrIncludeData {
@ExcelProperty(order = 1)
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;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class ExtraData {
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.converters.doubleconverter.DoubleStringConverter;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class FillData {
private String name;
@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.poi.FillPatternTypeEnum;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class FillStyleAnnotatedData {
@ContentStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 13)
@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 lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* @author Jiaju Zhuang
*/
@Data
@Getter
@Setter
@EqualsAndHashCode
public class FillStyleData {
private String name;
private Double number;

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

Loading…
Cancel
Save