Browse Source

Merge pull request #2144 from alibaba/bugfix

Bugfix
pull/2122/merge
Jiaju Zhuang 3 years ago committed by GitHub
parent
commit
d51185c2e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 9
      README.md
  2. 2
      pom.xml
  3. 2
      src/main/java/com/alibaba/excel/annotation/ExcelProperty.java
  4. 14
      src/main/java/com/alibaba/excel/context/WriteContextImpl.java
  5. 109
      src/main/java/com/alibaba/excel/metadata/Head.java
  6. 14
      src/main/java/com/alibaba/excel/metadata/data/WriteCellData.java
  7. 21
      src/main/java/com/alibaba/excel/metadata/property/ExcelContentProperty.java
  8. 48
      src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java
  9. 19
      src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java
  10. 7
      src/main/java/com/alibaba/excel/read/processor/DefaultAnalysisEventProcessor.java
  11. 190
      src/main/java/com/alibaba/excel/util/ClassUtils.java
  12. 15
      src/main/java/com/alibaba/excel/util/FieldUtils.java
  13. 17
      src/main/java/com/alibaba/excel/util/ListUtils.java
  14. 17
      src/main/java/com/alibaba/excel/util/MapUtils.java
  15. 1
      src/main/java/com/alibaba/excel/util/NumberUtils.java
  16. 7
      src/main/java/com/alibaba/excel/util/StringUtils.java
  17. 67
      src/main/java/com/alibaba/excel/util/StyleUtil.java
  18. 23
      src/main/java/com/alibaba/excel/util/WriteHandlerUtils.java
  19. 22
      src/main/java/com/alibaba/excel/write/executor/AbstractExcelWriteExecutor.java
  20. 92
      src/main/java/com/alibaba/excel/write/executor/ExcelWriteAddExecutor.java
  21. 68
      src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java
  22. 5
      src/main/java/com/alibaba/excel/write/handler/context/CellWriteHandlerContext.java
  23. 13
      src/main/java/com/alibaba/excel/write/handler/impl/FillStyleCellWriteHandler.java
  24. 24
      src/main/java/com/alibaba/excel/write/metadata/holder/AbstractWriteHolder.java
  25. 85
      src/main/java/com/alibaba/excel/write/metadata/holder/WriteWorkbookHolder.java
  26. 74
      src/main/java/com/alibaba/excel/write/property/ExcelWriteHeadProperty.java
  27. 28
      src/main/java/com/alibaba/excel/write/style/AbstractVerticalCellStyleStrategy.java
  28. 43
      src/test/java/com/alibaba/easyexcel/test/core/StyleTestUtils.java
  29. 35
      src/test/java/com/alibaba/easyexcel/test/core/fill/FillDataTest.java
  30. 29
      src/test/java/com/alibaba/easyexcel/test/core/fill/style/FillStyleAnnotatedData.java
  31. 325
      src/test/java/com/alibaba/easyexcel/test/core/fill/style/FillStyleAnnotatedTest.java
  32. 16
      src/test/java/com/alibaba/easyexcel/test/core/fill/style/FillStyleData.java
  33. 344
      src/test/java/com/alibaba/easyexcel/test/core/fill/style/FillStyleDataTest.java
  34. 46
      src/test/java/com/alibaba/easyexcel/test/core/large/LargeDataTest.java
  35. 5
      src/test/java/com/alibaba/easyexcel/test/core/noncamel/UnCamelDataListener.java
  36. 65
      src/test/java/com/alibaba/easyexcel/test/core/style/StyleDataTest.java
  37. 4
      src/test/java/com/alibaba/easyexcel/test/demo/fill/FillData.java
  38. 1
      src/test/java/com/alibaba/easyexcel/test/demo/fill/FillTest.java
  39. 132
      src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiTest.java
  40. 17
      src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiWriteTest.java
  41. BIN
      src/test/resources/demo/fill/list.xlsx
  42. 2
      src/test/resources/fill/simple.csv
  43. BIN
      src/test/resources/fill/style.xls
  44. BIN
      src/test/resources/fill/style.xlsx
  45. 9
      update.md

9
README.md

@ -37,6 +37,15 @@ Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都
* 大版本升级后建议相关内容重新测试下 * 大版本升级后建议相关内容重新测试下
* 要升级涉及到 * 要升级涉及到
### 最新版本
```xml
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.0.1</version>
</dependency>
```
## 广告位 ## 广告位
### 支付宝扫一扫红包 ### 支付宝扫一扫红包
本项目都是个人业余时间写的,所以比较贫穷。推广下支付宝,赚个建群的费用。有空的同学帮忙扫一扫 本项目都是个人业余时间写的,所以比较贫穷。推广下支付宝,赚个建群的费用。有空的同学帮忙扫一扫

2
pom.xml

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

2
src/main/java/com/alibaba/excel/annotation/ExcelProperty.java

@ -54,7 +54,7 @@ public @interface ExcelProperty {
* *
* @return Converter * @return Converter
*/ */
Class<? extends Converter> converter() default AutoConverter.class; Class<? extends Converter<?>> converter() default AutoConverter.class;
/** /**
* *

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

@ -10,7 +10,9 @@ import com.alibaba.excel.enums.WriteTypeEnum;
import com.alibaba.excel.exception.ExcelGenerateException; import com.alibaba.excel.exception.ExcelGenerateException;
import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData; import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.support.ExcelTypeEnum; import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.util.ClassUtils;
import com.alibaba.excel.util.DateUtils; import com.alibaba.excel.util.DateUtils;
import com.alibaba.excel.util.FileUtils; import com.alibaba.excel.util.FileUtils;
import com.alibaba.excel.util.NumberDataFormatterUtils; import com.alibaba.excel.util.NumberDataFormatterUtils;
@ -244,17 +246,21 @@ public class WriteContextImpl implements WriteContext {
for (Map.Entry<Integer, Head> entry : headMap.entrySet()) { for (Map.Entry<Integer, Head> entry : headMap.entrySet()) {
Head head = entry.getValue(); Head head = entry.getValue();
int columnIndex = entry.getKey(); int columnIndex = entry.getKey();
WriteHandlerUtils.beforeCellCreate(this, row, head, columnIndex, relativeRowIndex, Boolean.TRUE); ExcelContentProperty excelContentProperty = ClassUtils.declaredExcelContentProperty(null,
currentWriteHolder.excelWriteHeadProperty().getHeadClazz(), head.getFieldName());
WriteHandlerUtils.beforeCellCreate(this, row, head, columnIndex, relativeRowIndex, Boolean.TRUE,
excelContentProperty);
Cell cell = row.createCell(columnIndex); Cell cell = row.createCell(columnIndex);
WriteHandlerUtils.afterCellCreate(this, cell, head, relativeRowIndex, Boolean.TRUE); WriteHandlerUtils.afterCellCreate(this, cell, head, relativeRowIndex, Boolean.TRUE, excelContentProperty);
WriteCellData<String> writeCellData = new WriteCellData<>(head.getHeadNameList().get(relativeRowIndex)); WriteCellData<String> writeCellData = new WriteCellData<>(head.getHeadNameList().get(relativeRowIndex));
cell.setCellValue(writeCellData.getStringValue()); cell.setCellValue(writeCellData.getStringValue());
WriteHandlerUtils.afterCellDispose(this, writeCellData, cell, head, relativeRowIndex, WriteHandlerUtils.afterCellDispose(this, writeCellData, cell, head, relativeRowIndex, Boolean.TRUE,
Boolean.TRUE); excelContentProperty);
} }
} }

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

@ -1,5 +1,6 @@
package com.alibaba.excel.metadata; package com.alibaba.excel.metadata;
import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -9,16 +10,23 @@ import com.alibaba.excel.metadata.property.FontProperty;
import com.alibaba.excel.metadata.property.LoopMergeProperty; import com.alibaba.excel.metadata.property.LoopMergeProperty;
import com.alibaba.excel.metadata.property.StyleProperty; import com.alibaba.excel.metadata.property.StyleProperty;
import lombok.Data;
/** /**
* excel head * excel head
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
**/ **/
@Data
public class Head { public class Head {
/** /**
* Column index of head * Column index of head
*/ */
private Integer columnIndex; private Integer columnIndex;
/**
* It only has values when passed in {@link Sheet#setClazz(Class)} and {@link Table#setClazz(Class)}
*/
private Field field;
/** /**
* It only has values when passed in {@link Sheet#setClazz(Class)} and {@link Table#setClazz(Class)} * It only has values when passed in {@link Sheet#setClazz(Class)} and {@link Table#setClazz(Class)}
*/ */
@ -35,10 +43,12 @@ public class Head {
* Whether to specify a name * Whether to specify a name
*/ */
private Boolean forceName; private Boolean forceName;
/** /**
* column with * column with
*/ */
private ColumnWidthProperty columnWidthProperty; private ColumnWidthProperty columnWidthProperty;
/** /**
* Loop merge * Loop merge
*/ */
@ -47,22 +57,15 @@ public class Head {
* Head style * Head style
*/ */
private StyleProperty headStyleProperty; private StyleProperty headStyleProperty;
/**
* Content style
*/
private StyleProperty contentStyleProperty;
/** /**
* Head font * Head font
*/ */
private FontProperty headFontProperty; private FontProperty headFontProperty;
/**
* Content font
*/
private FontProperty contentFontProperty;
public Head(Integer columnIndex, String fieldName, List<String> headNameList, Boolean forceIndex, public Head(Integer columnIndex, Field field, String fieldName, List<String> headNameList, Boolean forceIndex,
Boolean forceName) { Boolean forceName) {
this.columnIndex = columnIndex; this.columnIndex = columnIndex;
this.field = field;
this.fieldName = fieldName; this.fieldName = fieldName;
if (headNameList == null) { if (headNameList == null) {
this.headNameList = new ArrayList<>(); this.headNameList = new ArrayList<>();
@ -77,92 +80,4 @@ public class Head {
this.forceIndex = forceIndex; this.forceIndex = forceIndex;
this.forceName = forceName; this.forceName = forceName;
} }
public Integer getColumnIndex() {
return columnIndex;
}
public void setColumnIndex(Integer columnIndex) {
this.columnIndex = columnIndex;
}
public String getFieldName() {
return fieldName;
}
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}
public List<String> getHeadNameList() {
return headNameList;
}
public void setHeadNameList(List<String> headNameList) {
this.headNameList = headNameList;
}
public ColumnWidthProperty getColumnWidthProperty() {
return columnWidthProperty;
}
public void setColumnWidthProperty(ColumnWidthProperty columnWidthProperty) {
this.columnWidthProperty = columnWidthProperty;
}
public Boolean getForceIndex() {
return forceIndex;
}
public void setForceIndex(Boolean forceIndex) {
this.forceIndex = forceIndex;
}
public Boolean getForceName() {
return forceName;
}
public void setForceName(Boolean forceName) {
this.forceName = forceName;
}
public LoopMergeProperty getLoopMergeProperty() {
return loopMergeProperty;
}
public void setLoopMergeProperty(LoopMergeProperty loopMergeProperty) {
this.loopMergeProperty = loopMergeProperty;
}
public StyleProperty getHeadStyleProperty() {
return headStyleProperty;
}
public void setHeadStyleProperty(StyleProperty headStyleProperty) {
this.headStyleProperty = headStyleProperty;
}
public StyleProperty getContentStyleProperty() {
return contentStyleProperty;
}
public void setContentStyleProperty(StyleProperty contentStyleProperty) {
this.contentStyleProperty = contentStyleProperty;
}
public FontProperty getHeadFontProperty() {
return headFontProperty;
}
public void setHeadFontProperty(FontProperty headFontProperty) {
this.headFontProperty = headFontProperty;
}
public FontProperty getContentFontProperty() {
return contentFontProperty;
}
public void setContentFontProperty(FontProperty contentFontProperty) {
this.contentFontProperty = contentFontProperty;
}
} }

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

@ -8,10 +8,12 @@ import java.util.List;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.util.ListUtils; import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.write.metadata.fill.AnalysisCell;
import com.alibaba.excel.write.metadata.style.WriteCellStyle; import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.apache.poi.ss.usermodel.CellStyle;
/** /**
* wirte cell data * wirte cell data
@ -42,11 +44,23 @@ public class WriteCellData<T> extends CellData<T> {
* hyper link * hyper link
*/ */
private HyperlinkData hyperlinkData; private HyperlinkData hyperlinkData;
/** /**
* style * style
*/ */
private WriteCellStyle writeCellStyle; private WriteCellStyle writeCellStyle;
/**
* If originCellStyle is empty, one will be created.
* If both writeCellStyle and originCellStyle exist, copy from writeCellStyle to originCellStyle.
*/
private CellStyle originCellStyle;
/**
* Only in the case of the fill is not null
*/
private AnalysisCell analysisCell;
public WriteCellData(String stringValue) { public WriteCellData(String stringValue) {
this(CellDataTypeEnum.STRING, stringValue); this(CellDataTypeEnum.STRING, stringValue);
} }

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

@ -3,7 +3,6 @@ package com.alibaba.excel.metadata.property;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.metadata.Head;
import lombok.Data; import lombok.Data;
@ -12,18 +11,30 @@ import lombok.Data;
*/ */
@Data @Data
public class ExcelContentProperty { public class ExcelContentProperty {
public static final ExcelContentProperty EMPTY = new ExcelContentProperty();
/** /**
* Java filed * Java filed
*/ */
private Field field; private Field field;
/**
* Excel head
*/
private Head head;
/** /**
* Custom defined converters * Custom defined converters
*/ */
private Converter<?> converter; private Converter<?> converter;
/**
* date time format
*/
private DateTimeFormatProperty dateTimeFormatProperty; private DateTimeFormatProperty dateTimeFormatProperty;
/**
* number format
*/
private NumberFormatProperty numberFormatProperty; private NumberFormatProperty numberFormatProperty;
/**
* Content style
*/
private StyleProperty contentStyleProperty;
/**
* Content font
*/
private FontProperty contentFontProperty;
} }

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

@ -8,15 +8,11 @@ import java.util.Map;
import java.util.TreeMap; import java.util.TreeMap;
import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.DateTimeFormat;
import com.alibaba.excel.annotation.format.NumberFormat;
import com.alibaba.excel.converters.AutoConverter;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.HeadKindEnum; import com.alibaba.excel.enums.HeadKindEnum;
import com.alibaba.excel.exception.ExcelCommonException;
import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.Holder; import com.alibaba.excel.metadata.Holder;
import com.alibaba.excel.util.ClassUtils; import com.alibaba.excel.util.ClassUtils;
import com.alibaba.excel.util.FieldUtils;
import com.alibaba.excel.util.MapUtils; import com.alibaba.excel.util.MapUtils;
import com.alibaba.excel.util.StringUtils; import com.alibaba.excel.util.StringUtils;
import com.alibaba.excel.write.metadata.holder.AbstractWriteHolder; import com.alibaba.excel.write.metadata.holder.AbstractWriteHolder;
@ -38,7 +34,7 @@ public class ExcelHeadProperty {
/** /**
* Custom class * Custom class
*/ */
private Class headClazz; private Class<?> headClazz;
/** /**
* The types of head * The types of head
*/ */
@ -51,24 +47,14 @@ public class ExcelHeadProperty {
* Configuration header information * Configuration header information
*/ */
private Map<Integer, Head> headMap; private Map<Integer, Head> headMap;
/**
* Configuration column information
*/
private Map<Integer, ExcelContentProperty> contentPropertyMap;
/**
* Configuration column information
*/
private Map<String, ExcelContentProperty> fieldNameContentPropertyMap;
/** /**
* Fields ignored * Fields ignored
*/ */
private Map<String, Field> ignoreMap; private Map<String, Field> ignoreMap;
public ExcelHeadProperty(Holder holder, Class headClazz, List<List<String>> head) { public ExcelHeadProperty(Holder holder, Class<?> headClazz, List<List<String>> head) {
this.headClazz = headClazz; this.headClazz = headClazz;
headMap = new TreeMap<>(); headMap = new TreeMap<>();
contentPropertyMap = new TreeMap<>();
fieldNameContentPropertyMap = MapUtils.newHashMap();
ignoreMap = MapUtils.newHashMap(); ignoreMap = MapUtils.newHashMap();
headKind = HeadKindEnum.NONE; headKind = HeadKindEnum.NONE;
headRowNumber = 0; headRowNumber = 0;
@ -80,8 +66,7 @@ public class ExcelHeadProperty {
continue; continue;
} }
} }
headMap.put(headIndex, new Head(headIndex, null, head.get(i), Boolean.FALSE, Boolean.TRUE)); headMap.put(headIndex, new Head(headIndex, null, null, head.get(i), Boolean.FALSE, Boolean.TRUE));
contentPropertyMap.put(headIndex, null);
headIndex++; headIndex++;
} }
headKind = HeadKindEnum.STRING; headKind = HeadKindEnum.STRING;
@ -148,39 +133,20 @@ public class ExcelHeadProperty {
private void initOneColumnProperty(int index, Field field, Boolean forceIndex) { private void initOneColumnProperty(int index, Field field, Boolean forceIndex) {
ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class); ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
List<String> tmpHeadList = new ArrayList<String>(); List<String> tmpHeadList = new ArrayList<String>();
String fieldName = FieldUtils.resolveCglibFieldName(field);
boolean notForceName = excelProperty == null || excelProperty.value().length <= 0 boolean notForceName = excelProperty == null || excelProperty.value().length <= 0
|| (excelProperty.value().length == 1 && StringUtils.isEmpty((excelProperty.value())[0])); || (excelProperty.value().length == 1 && StringUtils.isEmpty((excelProperty.value())[0]));
if (headMap.containsKey(index)) { if (headMap.containsKey(index)) {
tmpHeadList.addAll(headMap.get(index).getHeadNameList()); tmpHeadList.addAll(headMap.get(index).getHeadNameList());
} else { } else {
if (notForceName) { if (notForceName) {
tmpHeadList.add(field.getName()); tmpHeadList.add(fieldName);
} else { } else {
Collections.addAll(tmpHeadList, excelProperty.value()); Collections.addAll(tmpHeadList, excelProperty.value());
} }
} }
Head head = new Head(index, field.getName(), tmpHeadList, forceIndex, !notForceName); Head head = new Head(index, field, fieldName, tmpHeadList, forceIndex, !notForceName);
ExcelContentProperty excelContentProperty = new ExcelContentProperty();
if (excelProperty != null) {
Class<? extends Converter> convertClazz = excelProperty.converter();
if (convertClazz != AutoConverter.class) {
try {
Converter converter = convertClazz.newInstance();
excelContentProperty.setConverter(converter);
} catch (Exception e) {
throw new ExcelCommonException("Can not instance custom converter:" + convertClazz.getName());
}
}
}
excelContentProperty.setHead(head);
excelContentProperty.setField(field);
excelContentProperty
.setDateTimeFormatProperty(DateTimeFormatProperty.build(field.getAnnotation(DateTimeFormat.class)));
excelContentProperty
.setNumberFormatProperty(NumberFormatProperty.build(field.getAnnotation(NumberFormat.class)));
headMap.put(index, head); headMap.put(index, head);
contentPropertyMap.put(index, excelContentProperty);
fieldNameContentPropertyMap.put(field.getName(), excelContentProperty);
} }
public boolean hasHead() { public boolean hasHead() {

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

@ -8,14 +8,14 @@ import com.alibaba.excel.enums.HeadKindEnum;
import com.alibaba.excel.exception.ExcelDataConvertException; import com.alibaba.excel.exception.ExcelDataConvertException;
import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.ReadCellData; import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.read.metadata.holder.ReadSheetHolder; import com.alibaba.excel.read.metadata.holder.ReadSheetHolder;
import com.alibaba.excel.read.metadata.property.ExcelReadHeadProperty; import com.alibaba.excel.read.metadata.property.ExcelReadHeadProperty;
import com.alibaba.excel.util.BeanMapUtils; import com.alibaba.excel.util.BeanMapUtils;
import com.alibaba.excel.util.ClassUtils;
import com.alibaba.excel.util.ConverterUtils; import com.alibaba.excel.util.ConverterUtils;
import com.alibaba.excel.util.FieldUtils;
import com.alibaba.excel.util.MapUtils; import com.alibaba.excel.util.MapUtils;
import net.sf.cglib.beans.BeanMap;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
/** /**
@ -92,22 +92,23 @@ public class ModelBuildEventListener implements ReadListener<Map<Integer, ReadCe
} }
Map<Integer, Head> headMap = excelReadHeadProperty.getHeadMap(); Map<Integer, Head> headMap = excelReadHeadProperty.getHeadMap();
Map<String, Object> map = MapUtils.newHashMapWithExpectedSize(headMap.size()); Map<String, Object> map = MapUtils.newHashMapWithExpectedSize(headMap.size());
Map<Integer, ExcelContentProperty> contentPropertyMap = excelReadHeadProperty.getContentPropertyMap(); BeanMap dataMap = BeanMapUtils.create(resultModel);
for (Map.Entry<Integer, Head> entry : headMap.entrySet()) { for (Map.Entry<Integer, Head> entry : headMap.entrySet()) {
Integer index = entry.getKey(); Integer index = entry.getKey();
Head head = entry.getValue();
String fieldName = head.getFieldName();
if (!cellDataMap.containsKey(index)) { if (!cellDataMap.containsKey(index)) {
continue; continue;
} }
ReadCellData<?> cellData = cellDataMap.get(index); ReadCellData<?> cellData = cellDataMap.get(index);
ExcelContentProperty excelContentProperty = contentPropertyMap.get(index); Object value = ConverterUtils.convertToJavaObject(cellData, head.getField(),
Object value = ConverterUtils.convertToJavaObject(cellData, excelContentProperty.getField(), ClassUtils.declaredExcelContentProperty(dataMap, readSheetHolder.excelReadHeadProperty().getHeadClazz(),
excelContentProperty, readSheetHolder.converterMap(), context, fieldName), readSheetHolder.converterMap(), context, context.readRowHolder().getRowIndex(), index);
context.readRowHolder().getRowIndex(), index);
if (value != null) { if (value != null) {
map.put(FieldUtils.resolveCglibFieldName(excelContentProperty.getField()), value); map.put(fieldName, value);
} }
} }
BeanMapUtils.create(resultModel).putAll(map); dataMap.putAll(map);
return resultModel; return resultModel;
} }

7
src/main/java/com/alibaba/excel/read/processor/DefaultAnalysisEventProcessor.java

@ -11,7 +11,6 @@ import com.alibaba.excel.exception.ExcelAnalysisException;
import com.alibaba.excel.exception.ExcelAnalysisStopException; import com.alibaba.excel.exception.ExcelAnalysisStopException;
import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.ReadCellData; import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.read.listener.ReadListener; import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.read.metadata.holder.ReadRowHolder; import com.alibaba.excel.read.metadata.holder.ReadRowHolder;
import com.alibaba.excel.read.metadata.property.ExcelReadHeadProperty; import com.alibaba.excel.read.metadata.property.ExcelReadHeadProperty;
@ -118,15 +117,11 @@ public class DefaultAnalysisEventProcessor implements AnalysisEventProcessor {
Map<Integer, String> dataMap = ConverterUtils.convertToStringMap(cellDataMap, analysisContext); Map<Integer, String> dataMap = ConverterUtils.convertToStringMap(cellDataMap, analysisContext);
ExcelReadHeadProperty excelHeadPropertyData = analysisContext.readSheetHolder().excelReadHeadProperty(); ExcelReadHeadProperty excelHeadPropertyData = analysisContext.readSheetHolder().excelReadHeadProperty();
Map<Integer, Head> headMapData = excelHeadPropertyData.getHeadMap(); Map<Integer, Head> headMapData = excelHeadPropertyData.getHeadMap();
Map<Integer, ExcelContentProperty> contentPropertyMapData = excelHeadPropertyData.getContentPropertyMap();
Map<Integer, Head> tmpHeadMap = new HashMap<Integer, Head>(headMapData.size() * 4 / 3 + 1); Map<Integer, Head> tmpHeadMap = new HashMap<Integer, Head>(headMapData.size() * 4 / 3 + 1);
Map<Integer, ExcelContentProperty> tmpContentPropertyMap =
new HashMap<Integer, ExcelContentProperty>(contentPropertyMapData.size() * 4 / 3 + 1);
for (Map.Entry<Integer, Head> entry : headMapData.entrySet()) { for (Map.Entry<Integer, Head> entry : headMapData.entrySet()) {
Head headData = entry.getValue(); Head headData = entry.getValue();
if (headData.getForceIndex() || !headData.getForceName()) { if (headData.getForceIndex() || !headData.getForceName()) {
tmpHeadMap.put(entry.getKey(), headData); tmpHeadMap.put(entry.getKey(), headData);
tmpContentPropertyMap.put(entry.getKey(), contentPropertyMapData.get(entry.getKey()));
continue; continue;
} }
List<String> headNameList = headData.getHeadNameList(); List<String> headNameList = headData.getHeadNameList();
@ -146,12 +141,10 @@ public class DefaultAnalysisEventProcessor implements AnalysisEventProcessor {
if (headName.equals(headString)) { if (headName.equals(headString)) {
headData.setColumnIndex(stringKey); headData.setColumnIndex(stringKey);
tmpHeadMap.put(stringKey, headData); tmpHeadMap.put(stringKey, headData);
tmpContentPropertyMap.put(stringKey, contentPropertyMapData.get(entry.getKey()));
break; break;
} }
} }
} }
excelHeadPropertyData.setHeadMap(tmpHeadMap); excelHeadPropertyData.setHeadMap(tmpHeadMap);
excelHeadPropertyData.setContentPropertyMap(tmpContentPropertyMap);
} }
} }

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

@ -1,6 +1,5 @@
package com.alibaba.excel.util; package com.alibaba.excel.util;
import java.lang.ref.SoftReference;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.ArrayList; import java.util.ArrayList;
@ -10,16 +9,30 @@ import java.util.HashSet;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import com.alibaba.excel.annotation.ExcelIgnore; import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.DateTimeFormat;
import com.alibaba.excel.annotation.format.NumberFormat;
import com.alibaba.excel.annotation.write.style.ContentFontStyle;
import com.alibaba.excel.annotation.write.style.ContentStyle;
import com.alibaba.excel.converters.AutoConverter;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.exception.ExcelCommonException; import com.alibaba.excel.exception.ExcelCommonException;
import com.alibaba.excel.metadata.Holder; import com.alibaba.excel.metadata.Holder;
import com.alibaba.excel.metadata.property.DateTimeFormatProperty;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.metadata.property.FontProperty;
import com.alibaba.excel.metadata.property.NumberFormatProperty;
import com.alibaba.excel.metadata.property.StyleProperty;
import com.alibaba.excel.write.metadata.holder.WriteHolder; import com.alibaba.excel.write.metadata.holder.WriteHolder;
import net.sf.cglib.beans.BeanMap;
/** /**
* Class utils * Class utils
* *
@ -27,7 +40,156 @@ import com.alibaba.excel.write.metadata.holder.WriteHolder;
**/ **/
public class ClassUtils { public class ClassUtils {
public static final Map<Class<?>, SoftReference<FieldCache>> FIELD_CACHE = new ConcurrentHashMap<>(); public static final Map<Class<?>, FieldCache> FIELD_CACHE = new ConcurrentHashMap<>();
/**
* The cache configuration information for each of the class
*/
public static final Map<Class<?>, Map<String, ExcelContentProperty>> CLASS_CONTENT_CACHE
= new ConcurrentHashMap<>();
/**
* The cache configuration information for each of the class
*/
public static final Map<String, ExcelContentProperty> CONTENT_CACHE = new ConcurrentHashMap<>();
/**
* Calculate the configuration information for the class
*
* @param dataMap
* @param headClazz
* @param fieldName
* @return
*/
public static ExcelContentProperty declaredExcelContentProperty(Map<?, ?> dataMap, Class<?> headClazz,
String fieldName) {
Class<?> clazz = null;
if (dataMap instanceof BeanMap) {
Object bean = ((BeanMap)dataMap).getBean();
if (bean != null) {
clazz = bean.getClass();
}
}
return getExcelContentProperty(clazz, headClazz, fieldName);
}
private static ExcelContentProperty getExcelContentProperty(Class<?> clazz, Class<?> headClass, String fieldName) {
return CONTENT_CACHE.computeIfAbsent(buildKey(clazz, headClass, fieldName), key -> {
ExcelContentProperty excelContentProperty = Optional.ofNullable(declaredFieldContentMap(clazz))
.map(map -> map.get(fieldName))
.orElse(null);
ExcelContentProperty headExcelContentProperty = Optional.ofNullable(declaredFieldContentMap(headClass))
.map(map -> map.get(fieldName))
.orElse(null);
ExcelContentProperty combineExcelContentProperty = new ExcelContentProperty();
combineExcelContentProperty(combineExcelContentProperty, headExcelContentProperty);
if (clazz != headClass) {
combineExcelContentProperty(combineExcelContentProperty, excelContentProperty);
}
return combineExcelContentProperty;
});
}
public static void combineExcelContentProperty(ExcelContentProperty combineExcelContentProperty,
ExcelContentProperty excelContentProperty) {
if (excelContentProperty == null) {
return;
}
if (excelContentProperty.getField() != null) {
combineExcelContentProperty.setField(excelContentProperty.getField());
}
if (excelContentProperty.getConverter() != null) {
combineExcelContentProperty.setConverter(excelContentProperty.getConverter());
}
if (excelContentProperty.getDateTimeFormatProperty() != null) {
combineExcelContentProperty.setDateTimeFormatProperty(excelContentProperty.getDateTimeFormatProperty());
}
if (excelContentProperty.getNumberFormatProperty() != null) {
combineExcelContentProperty.setNumberFormatProperty(excelContentProperty.getNumberFormatProperty());
}
if (excelContentProperty.getContentStyleProperty() != null) {
combineExcelContentProperty.setContentStyleProperty(excelContentProperty.getContentStyleProperty());
}
if (excelContentProperty.getContentFontProperty() != null) {
combineExcelContentProperty.setContentFontProperty(excelContentProperty.getContentFontProperty());
}
}
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 Map<String, ExcelContentProperty> declaredFieldContentMap(Class<?> clazz) {
if (clazz == null) {
return null;
}
return CLASS_CONTENT_CACHE.computeIfAbsent(clazz, key -> {
List<Field> tempFieldList = new ArrayList<>();
Class<?> tempClass = clazz;
while (tempClass != null) {
Collections.addAll(tempFieldList, tempClass.getDeclaredFields());
// Get the parent class and give it to yourself
tempClass = tempClass.getSuperclass();
}
ContentStyle parentContentStyle = clazz.getAnnotation(ContentStyle.class);
ContentFontStyle parentContentFontStyle = clazz.getAnnotation(ContentFontStyle.class);
Map<String, ExcelContentProperty> fieldContentMap = MapUtils.newHashMapWithExpectedSize(
tempFieldList.size());
for (Field field : tempFieldList) {
ExcelContentProperty excelContentProperty = new ExcelContentProperty();
excelContentProperty.setField(field);
ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
if (excelProperty != null) {
Class<? extends Converter<?>> convertClazz = excelProperty.converter();
if (convertClazz != AutoConverter.class) {
try {
Converter<?> converter = convertClazz.newInstance();
excelContentProperty.setConverter(converter);
} catch (Exception e) {
throw new ExcelCommonException(
"Can not instance custom converter:" + convertClazz.getName());
}
}
}
ContentStyle contentStyle = field.getAnnotation(ContentStyle.class);
if (contentStyle == null) {
contentStyle = parentContentStyle;
}
excelContentProperty.setContentStyleProperty(StyleProperty.build(contentStyle));
ContentFontStyle contentFontStyle = field.getAnnotation(ContentFontStyle.class);
if (contentFontStyle == null) {
contentFontStyle = parentContentFontStyle;
}
excelContentProperty.setContentFontProperty(FontProperty.build(contentFontStyle));
excelContentProperty.setDateTimeFormatProperty(
DateTimeFormatProperty.build(field.getAnnotation(DateTimeFormat.class)));
excelContentProperty.setNumberFormatProperty(
NumberFormatProperty.build(field.getAnnotation(NumberFormat.class)));
fieldContentMap.put(field.getName(), excelContentProperty);
}
return fieldContentMap;
});
}
/** /**
* Parsing filed in the class * Parsing filed in the class
@ -41,7 +203,7 @@ public class ClassUtils {
*/ */
public static void declaredFields(Class<?> clazz, Map<Integer, Field> sortedAllFiledMap, public static void declaredFields(Class<?> clazz, Map<Integer, Field> sortedAllFiledMap,
Map<Integer, Field> indexFiledMap, Map<String, Field> ignoreMap, Boolean needIgnore, Holder holder) { Map<Integer, Field> indexFiledMap, Map<String, Field> ignoreMap, Boolean needIgnore, Holder holder) {
FieldCache fieldCache = getFieldCache(clazz); FieldCache fieldCache = declaredFields(clazz);
if (fieldCache == null) { if (fieldCache == null) {
return; return;
} }
@ -92,25 +254,11 @@ public class ClassUtils {
declaredFields(clazz, sortedAllFiledMap, null, null, needIgnore, writeHolder); declaredFields(clazz, sortedAllFiledMap, null, null, needIgnore, writeHolder);
} }
private static FieldCache getFieldCache(Class<?> clazz) { private static FieldCache declaredFields(Class<?> clazz) {
if (clazz == null) { if (clazz == null) {
return null; return null;
} }
SoftReference<FieldCache> fieldCacheSoftReference = FIELD_CACHE.get(clazz); return FIELD_CACHE.computeIfAbsent(clazz, key -> {
if (fieldCacheSoftReference != null && fieldCacheSoftReference.get() != null) {
return fieldCacheSoftReference.get();
}
synchronized (clazz) {
fieldCacheSoftReference = FIELD_CACHE.get(clazz);
if (fieldCacheSoftReference != null && fieldCacheSoftReference.get() != null) {
return fieldCacheSoftReference.get();
}
declaredFields(clazz);
}
return FIELD_CACHE.get(clazz).get();
}
private static void declaredFields(Class<?> clazz) {
List<Field> tempFieldList = new ArrayList<>(); List<Field> tempFieldList = new ArrayList<>();
Class<?> tempClass = clazz; Class<?> tempClass = clazz;
// When the parent class is null, it indicates that the parent class (Object class) has reached the top // When the parent class is null, it indicates that the parent class (Object class) has reached the top
@ -129,8 +277,8 @@ public class ClassUtils {
for (Field field : tempFieldList) { for (Field field : tempFieldList) {
declaredOneField(field, orderFiledMap, indexFiledMap, ignoreMap, excelIgnoreUnannotated); declaredOneField(field, orderFiledMap, indexFiledMap, ignoreMap, excelIgnoreUnannotated);
} }
FIELD_CACHE.put(clazz, new SoftReference<FieldCache>( return new FieldCache(buildSortedAllFiledMap(orderFiledMap, indexFiledMap), indexFiledMap, ignoreMap);
new FieldCache(buildSortedAllFiledMap(orderFiledMap, indexFiledMap), indexFiledMap, ignoreMap))); });
} }
private static Map<Integer, Field> buildSortedAllFiledMap(Map<Integer, List<Field>> orderFiledMap, private static Map<Integer, Field> buildSortedAllFiledMap(Map<Integer, List<Field>> orderFiledMap,

15
src/main/java/com/alibaba/excel/util/FieldUtils.java

@ -5,7 +5,6 @@ import java.lang.reflect.Modifier;
import java.util.Map; import java.util.Map;
import com.alibaba.excel.metadata.NullObject; import com.alibaba.excel.metadata.NullObject;
import com.alibaba.excel.write.metadata.RowData;
import net.sf.cglib.beans.BeanMap; import net.sf.cglib.beans.BeanMap;
@ -20,19 +19,17 @@ public class FieldUtils {
private static final int START_RESOLVE_FIELD_LENGTH = 2; private static final int START_RESOLVE_FIELD_LENGTH = 2;
public static Class<?> getFieldClass(Map dataMap, String filedName) { public static Class<?> getFieldClass(Map dataMap, String filedName, Object value) {
if (dataMap instanceof BeanMap) { if (dataMap instanceof BeanMap) {
return ((BeanMap)dataMap).getPropertyType(filedName); Class<?> fieldClass = ((BeanMap)dataMap).getPropertyType(filedName);
if (fieldClass != null) {
return fieldClass;
} }
Object value = dataMap.get(filedName);
if (value != null) {
return value.getClass();
} }
return nullObjectClass; return getFieldClass(value);
} }
public static Class<?> getFieldClass(RowData rowData, int dataIndex) { public static Class<?> getFieldClass(Object value) {
Object value = rowData.get(dataIndex);
if (value != null) { if (value != null) {
return value.getClass(); return value.getClass();
} }

17
src/main/java/com/alibaba/excel/util/ListUtils.java

@ -10,10 +10,21 @@ import lombok.NonNull;
import org.apache.commons.compress.utils.Iterators; import org.apache.commons.compress.utils.Iterators;
/** /**
* List utils * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
* *
* @author Jiaju Zhuang * Unless required by applicable law or agreed to in writing, software
**/ * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @author Apache Software Foundation (ASF)
*/
public class ListUtils { public class ListUtils {
private ListUtils() {} private ListUtils() {}

17
src/main/java/com/alibaba/excel/util/MapUtils.java

@ -5,10 +5,21 @@ import java.util.LinkedHashMap;
import java.util.TreeMap; import java.util.TreeMap;
/** /**
* Map utils * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
* *
* @author Jiaju Zhuang * Unless required by applicable law or agreed to in writing, software
**/ * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @author Apache Software Foundation (ASF)
*/
public class MapUtils { public class MapUtils {
private MapUtils() {} private MapUtils() {}

1
src/main/java/com/alibaba/excel/util/NumberUtils.java

@ -186,4 +186,5 @@ public class NumberUtils {
decimalFormat.setParseBigDecimal(true); decimalFormat.setParseBigDecimal(true);
return decimalFormat.parse(string); return decimalFormat.parse(string);
} }
} }

7
src/main/java/com/alibaba/excel/util/StringUtils.java

@ -1,5 +1,6 @@
package com.alibaba.excel.util; package com.alibaba.excel.util;
/*
/**
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
@ -12,8 +13,9 @@ package com.alibaba.excel.util;
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*
* @author Apache Software Foundation (ASF)
*/ */
public class StringUtils { public class StringUtils {
private StringUtils() {} private StringUtils() {}
@ -194,7 +196,6 @@ public class StringUtils {
return true; return true;
} }
/** /**
* <p>Checks if the CharSequence contains only Unicode digits. * <p>Checks if the CharSequence contains only Unicode digits.
* A decimal point is not a Unicode digit and returns false.</p> * A decimal point is not a Unicode digit and returns false.</p>

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

@ -10,8 +10,10 @@ import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import com.alibaba.excel.write.metadata.style.WriteCellStyle; import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont; import com.alibaba.excel.write.metadata.style.WriteFont;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.common.usermodel.HyperlinkType; import org.apache.poi.common.usermodel.HyperlinkType;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRichTextString; import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.DataFormat; import org.apache.poi.ss.usermodel.DataFormat;
@ -19,11 +21,14 @@ import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.RichTextString; import org.apache.poi.ss.usermodel.RichTextString;
import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.util.Units; import org.apache.poi.util.Units;
import org.apache.poi.xssf.usermodel.XSSFColor;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFRichTextString; import org.apache.poi.xssf.usermodel.XSSFRichTextString;
/** /**
* @author jipengfei * @author jipengfei
*/ */
@Slf4j
public class StyleUtil { public class StyleUtil {
private StyleUtil() {} private StyleUtil() {}
@ -32,11 +37,16 @@ public class StyleUtil {
* Build cell style * Build cell style
* *
* @param workbook * @param workbook
* @param originCellStyle
* @param writeCellStyle * @param writeCellStyle
* @return * @return
*/ */
public static CellStyle buildCellStyle(Workbook workbook, WriteCellStyle writeCellStyle) { public static CellStyle buildCellStyle(Workbook workbook, CellStyle originCellStyle,
WriteCellStyle writeCellStyle) {
CellStyle cellStyle = workbook.createCellStyle(); CellStyle cellStyle = workbook.createCellStyle();
if (originCellStyle != null) {
cellStyle.cloneStyleFrom(originCellStyle);
}
if (writeCellStyle == null) { if (writeCellStyle == null) {
return cellStyle; return cellStyle;
} }
@ -115,14 +125,23 @@ public class StyleUtil {
return dataFormatData.getIndex(); return dataFormatData.getIndex();
} }
if (StringUtils.isNotBlank(dataFormatData.getFormat())) { if (StringUtils.isNotBlank(dataFormatData.getFormat())) {
if (log.isDebugEnabled()) {
log.info("create new data fromat:{}", dataFormatData);
}
DataFormat dataFormatCreate = workbook.createDataFormat(); DataFormat dataFormatCreate = workbook.createDataFormat();
return dataFormatCreate.getFormat(dataFormatData.getFormat()); return dataFormatCreate.getFormat(dataFormatData.getFormat());
} }
return BuiltinFormats.GENERAL; return BuiltinFormats.GENERAL;
} }
public static Font buildFont(Workbook workbook, WriteFont writeFont) { public static Font buildFont(Workbook workbook, Font originFont, WriteFont writeFont) {
Font font = workbook.createFont(); if (log.isDebugEnabled()) {
log.info("create new font:{},{}", writeFont, originFont);
}
if (writeFont == null && originFont == null) {
return null;
}
Font font = createFont(workbook, originFont, writeFont);
if (writeFont == null || font == null) { if (writeFont == null || font == null) {
return font; return font;
} }
@ -156,6 +175,44 @@ public class StyleUtil {
return font; return font;
} }
private static Font createFont(Workbook workbook, Font originFont, WriteFont writeFont) {
Font font = workbook.createFont();
if (originFont == null) {
return font;
}
if (originFont instanceof XSSFFont) {
XSSFFont xssfFont = (XSSFFont)font;
XSSFFont xssfOriginFont = ((XSSFFont)originFont);
xssfFont.setFontName(xssfOriginFont.getFontName());
xssfFont.setFontHeightInPoints(xssfOriginFont.getFontHeightInPoints());
xssfFont.setItalic(xssfOriginFont.getItalic());
xssfFont.setStrikeout(xssfOriginFont.getStrikeout());
// Colors cannot be overwritten
if (writeFont == null || writeFont.getColor() == null) {
xssfFont.setColor(new XSSFColor(xssfOriginFont.getXSSFColor().getRGB(), null));
}
xssfFont.setTypeOffset(xssfOriginFont.getTypeOffset());
xssfFont.setUnderline(xssfOriginFont.getUnderline());
xssfFont.setCharSet(xssfOriginFont.getCharSet());
xssfFont.setBold(xssfOriginFont.getBold());
return xssfFont;
} else if (originFont instanceof HSSFFont) {
HSSFFont hssfFont = (HSSFFont)font;
HSSFFont hssfOriginFont = (HSSFFont)originFont;
hssfFont.setFontName(hssfOriginFont.getFontName());
hssfFont.setFontHeightInPoints(hssfOriginFont.getFontHeightInPoints());
hssfFont.setItalic(hssfOriginFont.getItalic());
hssfFont.setStrikeout(hssfOriginFont.getStrikeout());
hssfFont.setColor(hssfOriginFont.getColor());
hssfFont.setTypeOffset(hssfOriginFont.getTypeOffset());
hssfFont.setUnderline(hssfOriginFont.getUnderline());
hssfFont.setCharSet(hssfOriginFont.getCharSet());
hssfFont.setBold(hssfOriginFont.getBold());
return hssfFont;
}
return font;
}
public static RichTextString buildRichTextString(WriteWorkbookHolder writeWorkbookHolder, public static RichTextString buildRichTextString(WriteWorkbookHolder writeWorkbookHolder,
RichTextStringData richTextStringData) { RichTextStringData richTextStringData) {
if (richTextStringData == null) { if (richTextStringData == null) {
@ -168,12 +225,12 @@ public class StyleUtil {
richTextString = new HSSFRichTextString(richTextStringData.getTextString()); richTextString = new HSSFRichTextString(richTextStringData.getTextString());
} }
if (richTextStringData.getWriteFont() != null) { if (richTextStringData.getWriteFont() != null) {
richTextString.applyFont(writeWorkbookHolder.createFont(richTextStringData.getWriteFont())); richTextString.applyFont(writeWorkbookHolder.createFont(richTextStringData.getWriteFont(), null, true));
} }
if (CollectionUtils.isNotEmpty(richTextStringData.getIntervalFontList())) { if (CollectionUtils.isNotEmpty(richTextStringData.getIntervalFontList())) {
for (IntervalFont intervalFont : richTextStringData.getIntervalFontList()) { for (IntervalFont intervalFont : richTextStringData.getIntervalFontList()) {
richTextString.applyFont(intervalFont.getStartIndex(), intervalFont.getEndIndex(), richTextString.applyFont(intervalFont.getStartIndex(), intervalFont.getEndIndex(),
writeWorkbookHolder.createFont(intervalFont.getWriteFont())); writeWorkbookHolder.createFont(intervalFont.getWriteFont(), null, true));
} }
} }
return richTextString; return richTextString;

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

@ -6,6 +6,7 @@ import java.util.Map;
import com.alibaba.excel.context.WriteContext; import com.alibaba.excel.context.WriteContext;
import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData; import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.write.handler.CellWriteHandler; import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.handler.RowWriteHandler; import com.alibaba.excel.write.handler.RowWriteHandler;
import com.alibaba.excel.write.handler.SheetWriteHandler; import com.alibaba.excel.write.handler.SheetWriteHandler;
@ -116,7 +117,7 @@ public class WriteHandlerUtils {
} }
public static void beforeCellCreate(WriteContext writeContext, Row row, Head head, Integer columnIndex, public static void beforeCellCreate(WriteContext writeContext, Row row, Head head, Integer columnIndex,
Integer relativeRowIndex, Boolean isHead) { Integer relativeRowIndex, Boolean isHead, ExcelContentProperty excelContentProperty) {
List<WriteHandler> handlerList = List<WriteHandler> handlerList =
writeContext.currentWriteHolder().writeHandlerMap().get(CellWriteHandler.class); writeContext.currentWriteHolder().writeHandlerMap().get(CellWriteHandler.class);
if (handlerList == null || handlerList.isEmpty()) { if (handlerList == null || handlerList.isEmpty()) {
@ -124,7 +125,7 @@ public class WriteHandlerUtils {
} }
CellWriteHandlerContext context = new CellWriteHandlerContext(writeContext, writeContext.writeWorkbookHolder(), CellWriteHandlerContext context = new CellWriteHandlerContext(writeContext, writeContext.writeWorkbookHolder(),
writeContext.writeSheetHolder(), writeContext.writeTableHolder(), row, null, columnIndex, relativeRowIndex, writeContext.writeSheetHolder(), writeContext.writeTableHolder(), row, null, columnIndex, relativeRowIndex,
head, null, null, isHead); head, null, null, isHead, excelContentProperty);
for (WriteHandler writeHandler : handlerList) { for (WriteHandler writeHandler : handlerList) {
if (writeHandler instanceof CellWriteHandler) { if (writeHandler instanceof CellWriteHandler) {
((CellWriteHandler)writeHandler).beforeCellCreate(context); ((CellWriteHandler)writeHandler).beforeCellCreate(context);
@ -133,7 +134,7 @@ public class WriteHandlerUtils {
} }
public static void afterCellCreate(WriteContext writeContext, Cell cell, Head head, Integer relativeRowIndex, public static void afterCellCreate(WriteContext writeContext, Cell cell, Head head, Integer relativeRowIndex,
Boolean isHead) { Boolean isHead, ExcelContentProperty excelContentProperty) {
List<WriteHandler> handlerList = List<WriteHandler> handlerList =
writeContext.currentWriteHolder().writeHandlerMap().get(CellWriteHandler.class); writeContext.currentWriteHolder().writeHandlerMap().get(CellWriteHandler.class);
if (handlerList == null || handlerList.isEmpty()) { if (handlerList == null || handlerList.isEmpty()) {
@ -141,7 +142,7 @@ public class WriteHandlerUtils {
} }
CellWriteHandlerContext context = new CellWriteHandlerContext(writeContext, writeContext.writeWorkbookHolder(), CellWriteHandlerContext context = new CellWriteHandlerContext(writeContext, writeContext.writeWorkbookHolder(),
writeContext.writeSheetHolder(), writeContext.writeTableHolder(), cell.getRow(), cell, writeContext.writeSheetHolder(), writeContext.writeTableHolder(), cell.getRow(), cell,
cell.getColumnIndex(), relativeRowIndex, head, null, null, isHead); cell.getColumnIndex(), relativeRowIndex, head, null, null, isHead, excelContentProperty);
for (WriteHandler writeHandler : handlerList) { for (WriteHandler writeHandler : handlerList) {
if (writeHandler instanceof CellWriteHandler) { if (writeHandler instanceof CellWriteHandler) {
((CellWriteHandler)writeHandler).afterCellCreate(context); ((CellWriteHandler)writeHandler).afterCellCreate(context);
@ -150,8 +151,7 @@ public class WriteHandlerUtils {
} }
public static void afterCellDataConverted(WriteContext writeContext, WriteCellData<?> cellData, Cell cell, public static void afterCellDataConverted(WriteContext writeContext, WriteCellData<?> cellData, Cell cell,
Head head, Head head, Integer relativeRowIndex, Boolean isHead, ExcelContentProperty excelContentProperty) {
Integer relativeRowIndex, Boolean isHead) {
List<WriteHandler> handlerList = List<WriteHandler> handlerList =
writeContext.currentWriteHolder().writeHandlerMap().get(CellWriteHandler.class); writeContext.currentWriteHolder().writeHandlerMap().get(CellWriteHandler.class);
if (handlerList == null || handlerList.isEmpty()) { if (handlerList == null || handlerList.isEmpty()) {
@ -160,7 +160,7 @@ public class WriteHandlerUtils {
List<WriteCellData<?>> cellDataList = cellData == null ? null : ListUtils.newArrayList(cellData); List<WriteCellData<?>> cellDataList = cellData == null ? null : ListUtils.newArrayList(cellData);
CellWriteHandlerContext context = new CellWriteHandlerContext(writeContext, writeContext.writeWorkbookHolder(), CellWriteHandlerContext context = new CellWriteHandlerContext(writeContext, writeContext.writeWorkbookHolder(),
writeContext.writeSheetHolder(), writeContext.writeTableHolder(), cell.getRow(), cell, writeContext.writeSheetHolder(), writeContext.writeTableHolder(), cell.getRow(), cell,
cell.getColumnIndex(), relativeRowIndex, head, cellDataList, cellData, isHead); cell.getColumnIndex(), relativeRowIndex, head, cellDataList, cellData, isHead, excelContentProperty);
for (WriteHandler writeHandler : handlerList) { for (WriteHandler writeHandler : handlerList) {
if (writeHandler instanceof CellWriteHandler) { if (writeHandler instanceof CellWriteHandler) {
((CellWriteHandler)writeHandler).afterCellDataConverted(context); ((CellWriteHandler)writeHandler).afterCellDataConverted(context);
@ -169,14 +169,13 @@ public class WriteHandlerUtils {
} }
public static void afterCellDispose(WriteContext writeContext, WriteCellData<?> cellData, Cell cell, Head head, public static void afterCellDispose(WriteContext writeContext, WriteCellData<?> cellData, Cell cell, Head head,
Integer relativeRowIndex, Boolean isHead) { Integer relativeRowIndex, Boolean isHead, ExcelContentProperty excelContentProperty) {
List<WriteCellData<?>> cellDataList = cellData == null ? null : ListUtils.newArrayList(cellData); List<WriteCellData<?>> cellDataList = cellData == null ? null : ListUtils.newArrayList(cellData);
afterCellDispose(writeContext, cellDataList, cell, head, relativeRowIndex, isHead); afterCellDispose(writeContext, cellDataList, cell, head, relativeRowIndex, isHead, excelContentProperty);
} }
public static void afterCellDispose(WriteContext writeContext, List<WriteCellData<?>> cellDataList, Cell cell, public static void afterCellDispose(WriteContext writeContext, List<WriteCellData<?>> cellDataList, Cell cell,
Head head, Head head, Integer relativeRowIndex, Boolean isHead, ExcelContentProperty excelContentProperty) {
Integer relativeRowIndex, Boolean isHead) {
List<WriteHandler> handlerList = List<WriteHandler> handlerList =
writeContext.currentWriteHolder().writeHandlerMap().get(CellWriteHandler.class); writeContext.currentWriteHolder().writeHandlerMap().get(CellWriteHandler.class);
if (handlerList == null || handlerList.isEmpty()) { if (handlerList == null || handlerList.isEmpty()) {
@ -188,7 +187,7 @@ public class WriteHandlerUtils {
} }
CellWriteHandlerContext context = new CellWriteHandlerContext(writeContext, writeContext.writeWorkbookHolder(), CellWriteHandlerContext context = new CellWriteHandlerContext(writeContext, writeContext.writeWorkbookHolder(),
writeContext.writeSheetHolder(), writeContext.writeTableHolder(), cell.getRow(), cell, writeContext.writeSheetHolder(), writeContext.writeTableHolder(), cell.getRow(), cell,
cell.getColumnIndex(), relativeRowIndex, head, cellDataList, cellData, isHead); cell.getColumnIndex(), relativeRowIndex, head, cellDataList, cellData, isHead, excelContentProperty);
for (WriteHandler writeHandler : handlerList) { for (WriteHandler writeHandler : handlerList) {
if (writeHandler instanceof CellWriteHandler) { if (writeHandler instanceof CellWriteHandler) {
((CellWriteHandler)writeHandler).afterCellDispose(context); ((CellWriteHandler)writeHandler).afterCellDispose(context);

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

@ -23,12 +23,10 @@ import com.alibaba.excel.util.StyleUtil;
import com.alibaba.excel.util.WorkBookUtil; import com.alibaba.excel.util.WorkBookUtil;
import com.alibaba.excel.util.WriteHandlerUtils; import com.alibaba.excel.util.WriteHandlerUtils;
import com.alibaba.excel.write.metadata.holder.WriteHolder; import com.alibaba.excel.write.metadata.holder.WriteHolder;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.hssf.usermodel.HSSFClientAnchor; import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.ClientAnchor; import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.Comment; import org.apache.poi.ss.usermodel.Comment;
import org.apache.poi.ss.usermodel.CreationHelper; import org.apache.poi.ss.usermodel.CreationHelper;
@ -51,14 +49,15 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor {
protected WriteCellData<?> converterAndSet(WriteHolder currentWriteHolder, Class<?> clazz, protected WriteCellData<?> converterAndSet(WriteHolder currentWriteHolder, Class<?> clazz,
CellDataTypeEnum targetType, Cell cell, Object value, ExcelContentProperty excelContentProperty, Head head, CellDataTypeEnum targetType, Cell cell, Object value, ExcelContentProperty excelContentProperty, Head head,
Integer relativeRowIndex) { Integer relativeRowIndex, int rowIndex, int columnIndex) {
boolean needTrim = value != null && (value instanceof String && currentWriteHolder.globalConfiguration() boolean needTrim = value != null && (value instanceof String && currentWriteHolder.globalConfiguration()
.getAutoTrim()); .getAutoTrim());
if (needTrim) { if (needTrim) {
value = ((String)value).trim(); value = ((String)value).trim();
} }
WriteCellData<?> cellData = convert(currentWriteHolder, clazz, targetType, cell, value, excelContentProperty); WriteCellData<?> cellData = convert(currentWriteHolder, clazz, targetType, cell, value, excelContentProperty);
WriteHandlerUtils.afterCellDataConverted(writeContext, cellData, cell, head, relativeRowIndex, Boolean.FALSE); WriteHandlerUtils.afterCellDataConverted(writeContext, cellData, cell, head, relativeRowIndex, Boolean.FALSE,
excelContentProperty);
// Fill in picture information // Fill in picture information
fillImage(cell, cellData.getImageDataList()); fillImage(cell, cellData.getImageDataList());
@ -72,12 +71,9 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor {
// Fill in formula information // Fill in formula information
fillFormula(cell, cellData.getFormulaData()); fillFormula(cell, cellData.getFormulaData());
// Fill in style information
fillStyle(cell, cellData.getWriteCellStyle());
// Fill index // Fill index
cellData.setRowIndex(cell.getRowIndex()); cellData.setRowIndex(rowIndex);
cellData.setColumnIndex(cell.getColumnIndex()); cellData.setColumnIndex(columnIndex);
if (cellData.getType() == null) { if (cellData.getType() == null) {
cellData.setType(CellDataTypeEnum.EMPTY); cellData.setType(CellDataTypeEnum.EMPTY);
@ -109,14 +105,6 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor {
} }
private void fillStyle(Cell cell, WriteCellStyle writeCellStyle) {
if (writeCellStyle == null) {
return;
}
CellStyle cellStyle = writeContext.writeWorkbookHolder().createCellStyle(writeCellStyle);
cell.setCellStyle(cellStyle);
}
private void fillFormula(Cell cell, FormulaData formulaData) { private void fillFormula(Cell cell, FormulaData formulaData) {
if (formulaData == null) { if (formulaData == null) {
return; return;

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

@ -59,26 +59,26 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor {
} }
} }
private void addOneRowOfDataToExcel(Object oneRowData, int n, int relativeRowIndex, private void addOneRowOfDataToExcel(Object oneRowData, int rowIndex, int relativeRowIndex,
Map<Integer, Field> sortedAllFiledMap) { Map<Integer, Field> sortedAllFiledMap) {
if (oneRowData == null) { if (oneRowData == null) {
return; return;
} }
WriteHandlerUtils.beforeRowCreate(writeContext, n, relativeRowIndex, Boolean.FALSE); WriteHandlerUtils.beforeRowCreate(writeContext, rowIndex, relativeRowIndex, Boolean.FALSE);
Row row = WorkBookUtil.createRow(writeContext.writeSheetHolder().getSheet(), n); Row row = WorkBookUtil.createRow(writeContext.writeSheetHolder().getSheet(), rowIndex);
WriteHandlerUtils.afterRowCreate(writeContext, row, relativeRowIndex, Boolean.FALSE); WriteHandlerUtils.afterRowCreate(writeContext, row, relativeRowIndex, Boolean.FALSE);
if (oneRowData instanceof Collection<?>) { if (oneRowData instanceof Collection<?>) {
addBasicTypeToExcel(new CollectionRowData((Collection<?>)oneRowData), row, relativeRowIndex); addBasicTypeToExcel(new CollectionRowData((Collection<?>)oneRowData), row, rowIndex, relativeRowIndex);
} else if (oneRowData instanceof Map) { } else if (oneRowData instanceof Map) {
addBasicTypeToExcel(new MapRowData((Map<Integer, ?>)oneRowData), row, relativeRowIndex); addBasicTypeToExcel(new MapRowData((Map<Integer, ?>)oneRowData), row, rowIndex, relativeRowIndex);
} else { } else {
addJavaObjectToExcel(oneRowData, row, relativeRowIndex, sortedAllFiledMap); addJavaObjectToExcel(oneRowData, row, rowIndex, relativeRowIndex, sortedAllFiledMap);
} }
WriteHandlerUtils.afterRowDispose(writeContext, row, relativeRowIndex, Boolean.FALSE); WriteHandlerUtils.afterRowDispose(writeContext, row, relativeRowIndex, Boolean.FALSE);
} }
private void addBasicTypeToExcel(RowData oneRowData, Row row, int relativeRowIndex) { private void addBasicTypeToExcel(RowData oneRowData, Row row, int rowIndex, int relativeRowIndex) {
if (oneRowData.isEmpty()) { if (oneRowData.isEmpty()) {
return; return;
} }
@ -89,10 +89,10 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor {
if (dataIndex >= oneRowData.size()) { if (dataIndex >= oneRowData.size()) {
return; return;
} }
int cellIndex = entry.getKey(); int columnIndex = entry.getKey();
Head head = entry.getValue(); Head head = entry.getValue();
doAddBasicTypeToExcel(oneRowData, head, row, relativeRowIndex, dataIndex++, cellIndex); doAddBasicTypeToExcel(oneRowData, head, row, rowIndex, relativeRowIndex, dataIndex++, columnIndex);
maxCellIndex = Math.max(maxCellIndex, cellIndex); maxCellIndex = Math.max(maxCellIndex, columnIndex);
} }
// Finish // Finish
if (dataIndex >= oneRowData.size()) { if (dataIndex >= oneRowData.size()) {
@ -104,22 +104,29 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor {
int size = oneRowData.size() - dataIndex; int size = oneRowData.size() - dataIndex;
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
doAddBasicTypeToExcel(oneRowData, null, row, relativeRowIndex, dataIndex++, maxCellIndex++); doAddBasicTypeToExcel(oneRowData, null, row, rowIndex, relativeRowIndex, dataIndex++, maxCellIndex++);
} }
} }
private void doAddBasicTypeToExcel(RowData oneRowData, Head head, Row row, int relativeRowIndex, int dataIndex, private void doAddBasicTypeToExcel(RowData oneRowData, Head head, Row row, int rowIndex, int relativeRowIndex,
int cellIndex) { int dataIndex, int columnIndex) {
WriteHandlerUtils.beforeCellCreate(writeContext, row, head, cellIndex, relativeRowIndex, Boolean.FALSE); ExcelContentProperty excelContentProperty = ClassUtils.declaredExcelContentProperty(null,
Cell cell = WorkBookUtil.createCell(row, cellIndex); writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadClazz(),
WriteHandlerUtils.afterCellCreate(writeContext, cell, head, relativeRowIndex, Boolean.FALSE); head == null ? null : head.getFieldName());
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 = oneRowData.get(dataIndex); Object value = oneRowData.get(dataIndex);
WriteCellData<?> cellData = converterAndSet(writeContext.currentWriteHolder(), WriteCellData<?> cellData = converterAndSet(writeContext.currentWriteHolder(),
FieldUtils.getFieldClass(oneRowData, dataIndex), null, cell, value, null, head, relativeRowIndex); FieldUtils.getFieldClass(value), null, cell, value, null, head, relativeRowIndex, rowIndex, columnIndex);
WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, head, relativeRowIndex, Boolean.FALSE); WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, head, relativeRowIndex, Boolean.FALSE,
excelContentProperty);
} }
private void addJavaObjectToExcel(Object oneRowData, Row row, int relativeRowIndex, private void addJavaObjectToExcel(Object oneRowData, Row row, int rowIndex, int relativeRowIndex,
Map<Integer, Field> sortedAllFiledMap) { Map<Integer, Field> sortedAllFiledMap) {
WriteHolder currentWriteHolder = writeContext.currentWriteHolder(); WriteHolder currentWriteHolder = writeContext.currentWriteHolder();
BeanMap beanMap = BeanMapUtils.create(oneRowData); BeanMap beanMap = BeanMapUtils.create(oneRowData);
@ -128,26 +135,27 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor {
// If it's a class it needs to be cast by type // If it's a class it needs to be cast by type
if (HeadKindEnum.CLASS.equals(writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadKind())) { if (HeadKindEnum.CLASS.equals(writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadKind())) {
Map<Integer, Head> headMap = writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadMap(); Map<Integer, Head> headMap = writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadMap();
Map<Integer, ExcelContentProperty> contentPropertyMap = for (Map.Entry<Integer, Head> entry : headMap.entrySet()) {
writeContext.currentWriteHolder().excelWriteHeadProperty().getContentPropertyMap(); int columnIndex = entry.getKey();
for (Map.Entry<Integer, ExcelContentProperty> entry : contentPropertyMap.entrySet()) { Head head = entry.getValue();
int cellIndex = entry.getKey(); String name = head.getFieldName();
ExcelContentProperty excelContentProperty = entry.getValue();
String name = FieldUtils.resolveCglibFieldName(excelContentProperty.getField());
if (!beanMap.containsKey(name)) { if (!beanMap.containsKey(name)) {
continue; continue;
} }
Head head = headMap.get(cellIndex); ExcelContentProperty excelContentProperty = ClassUtils.declaredExcelContentProperty(beanMap,
WriteHandlerUtils.beforeCellCreate(writeContext, row, head, cellIndex, relativeRowIndex, Boolean.FALSE); currentWriteHolder.excelWriteHeadProperty().getHeadClazz(), name);
Cell cell = WorkBookUtil.createCell(row, cellIndex); WriteHandlerUtils.beforeCellCreate(writeContext, row, head, columnIndex, relativeRowIndex,
WriteHandlerUtils.afterCellCreate(writeContext, cell, head, relativeRowIndex, Boolean.FALSE); Boolean.FALSE, excelContentProperty);
Cell cell = WorkBookUtil.createCell(row, columnIndex);
WriteHandlerUtils.afterCellCreate(writeContext, cell, head, relativeRowIndex, Boolean.FALSE,
excelContentProperty);
Object value = beanMap.get(name); Object value = beanMap.get(name);
WriteCellData<?> cellData = converterAndSet(currentWriteHolder, WriteCellData<?> cellData = converterAndSet(currentWriteHolder, head.getField().getType(),
excelContentProperty.getField().getType(), null, cell, value, excelContentProperty, head, relativeRowIndex, rowIndex, columnIndex);
null, cell, value, excelContentProperty, head, relativeRowIndex); WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, head, relativeRowIndex, Boolean.FALSE,
WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, head, relativeRowIndex, Boolean.FALSE); excelContentProperty);
beanMapHandledSet.add(name); beanMapHandledSet.add(name);
maxCellIndex = Math.max(maxCellIndex, cellIndex); maxCellIndex = Math.max(maxCellIndex, columnIndex);
} }
} }
// Finish // Finish
@ -160,21 +168,27 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor {
initSortedAllFiledMapFieldList(oneRowData.getClass(), sortedAllFiledMap); initSortedAllFiledMapFieldList(oneRowData.getClass(), sortedAllFiledMap);
for (Map.Entry<Integer, Field> entry : sortedAllFiledMap.entrySet()) { for (Map.Entry<Integer, Field> entry : sortedAllFiledMap.entrySet()) {
Field field = entry.getValue(); Field field = entry.getValue();
String filedName = field.getName(); String filedName = FieldUtils.resolveCglibFieldName(field);
boolean uselessData = !beanMap.containsKey(filedName) || beanMapHandledSet.contains(filedName) boolean uselessData = !beanMap.containsKey(filedName) || beanMapHandledSet.contains(filedName)
|| ignoreMap.containsKey(filedName); || ignoreMap.containsKey(filedName);
if (uselessData) { if (uselessData) {
continue; continue;
} }
Object value = beanMap.get(filedName); Object value = beanMap.get(filedName);
WriteHandlerUtils.beforeCellCreate(writeContext, row, null, maxCellIndex, relativeRowIndex, Boolean.FALSE); ExcelContentProperty excelContentProperty = ClassUtils.declaredExcelContentProperty(beanMap,
currentWriteHolder.excelWriteHeadProperty().getHeadClazz(), filedName);
WriteHandlerUtils.beforeCellCreate(writeContext, row, null, maxCellIndex, relativeRowIndex, Boolean.FALSE,
excelContentProperty);
// fix https://github.com/alibaba/easyexcel/issues/1870 // fix https://github.com/alibaba/easyexcel/issues/1870
// If there is data, it is written to the next cell // If there is data, it is written to the next cell
Cell cell = WorkBookUtil.createCell(row, maxCellIndex++); Cell cell = WorkBookUtil.createCell(row, maxCellIndex++);
WriteHandlerUtils.afterCellCreate(writeContext, cell, null, relativeRowIndex, Boolean.FALSE); WriteHandlerUtils.afterCellCreate(writeContext, cell, null, relativeRowIndex, Boolean.FALSE,
excelContentProperty);
WriteCellData<?> cellData = converterAndSet(currentWriteHolder, WriteCellData<?> cellData = converterAndSet(currentWriteHolder,
FieldUtils.getFieldClass(beanMap, filedName), null, cell, value, null, null, relativeRowIndex); FieldUtils.getFieldClass(beanMap, filedName, value), null, cell, value, null, null, relativeRowIndex,
WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, null, relativeRowIndex, Boolean.FALSE); rowIndex, maxCellIndex);
WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, null, relativeRowIndex, Boolean.FALSE,
excelContentProperty);
} }
} }

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

@ -7,6 +7,7 @@ import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.Set; import java.util.Set;
import com.alibaba.excel.context.WriteContext; import com.alibaba.excel.context.WriteContext;
@ -17,6 +18,7 @@ import com.alibaba.excel.exception.ExcelGenerateException;
import com.alibaba.excel.metadata.data.WriteCellData; import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.util.BeanMapUtils; import com.alibaba.excel.util.BeanMapUtils;
import com.alibaba.excel.util.ClassUtils;
import com.alibaba.excel.util.FieldUtils; import com.alibaba.excel.util.FieldUtils;
import com.alibaba.excel.util.ListUtils; import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.util.MapUtils; import com.alibaba.excel.util.MapUtils;
@ -188,33 +190,49 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
dataMap = BeanMapUtils.create(oneRowData); dataMap = BeanMapUtils.create(oneRowData);
} }
WriteSheetHolder writeSheetHolder = writeContext.writeSheetHolder(); WriteSheetHolder writeSheetHolder = writeContext.writeSheetHolder();
Map<String, ExcelContentProperty> fieldNameContentPropertyMap =
writeContext.currentWriteHolder().excelWriteHeadProperty().getFieldNameContentPropertyMap();
for (AnalysisCell analysisCell : analysisCellList) { for (AnalysisCell analysisCell : analysisCellList) {
Cell cell = getOneCell(analysisCell, fillConfig);
if (analysisCell.getOnlyOneVariable()) { if (analysisCell.getOnlyOneVariable()) {
String variable = analysisCell.getVariableList().get(0); String variable = analysisCell.getVariableList().get(0);
if (!dataMap.containsKey(variable)) { if (!dataMap.containsKey(variable)) {
continue; continue;
} }
Object value = dataMap.get(variable); Object value = dataMap.get(variable);
ExcelContentProperty excelContentProperty = ClassUtils.declaredExcelContentProperty(dataMap,
writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadClazz(), variable);
Cell cell = getOneCell(analysisCell, fillConfig, excelContentProperty);
WriteCellData<?> cellData = converterAndSet(writeSheetHolder, WriteCellData<?> cellData = converterAndSet(writeSheetHolder,
FieldUtils.getFieldClass(dataMap, variable), FieldUtils.getFieldClass(dataMap, variable, value), null, cell, value, excelContentProperty, null,
null, cell, value, fieldNameContentPropertyMap.get(variable), null, relativeRowIndex); relativeRowIndex, analysisCell.getRowIndex(), analysisCell.getColumnIndex());
WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, null, relativeRowIndex, Boolean.FALSE); cellData.setAnalysisCell(analysisCell);
// Restyle
if (fillConfig.getAutoStyle()) {
Optional.ofNullable(collectionFieldStyleCache.get(currentUniqueDataFlag))
.map(collectionFieldStyleMap -> collectionFieldStyleMap.get(analysisCell))
.ifPresent(cellData::setOriginCellStyle);
}
WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, null, relativeRowIndex, Boolean.FALSE,
excelContentProperty);
} else { } else {
StringBuilder cellValueBuild = new StringBuilder(); StringBuilder cellValueBuild = new StringBuilder();
int index = 0; int index = 0;
List<WriteCellData<?>> cellDataList = new ArrayList<>(); List<WriteCellData<?>> cellDataList = new ArrayList<>();
Cell cell = getOneCell(analysisCell, fillConfig, ExcelContentProperty.EMPTY);
for (String variable : analysisCell.getVariableList()) { for (String variable : analysisCell.getVariableList()) {
cellValueBuild.append(analysisCell.getPrepareDataList().get(index++)); cellValueBuild.append(analysisCell.getPrepareDataList().get(index++));
if (!dataMap.containsKey(variable)) { if (!dataMap.containsKey(variable)) {
continue; continue;
} }
Object value = dataMap.get(variable); Object value = dataMap.get(variable);
WriteCellData<?> cellData = convert(writeSheetHolder, value == null ? null : value.getClass(), ExcelContentProperty excelContentProperty = ClassUtils.declaredExcelContentProperty(dataMap,
CellDataTypeEnum.STRING, cell, value, fieldNameContentPropertyMap.get(variable)); writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadClazz(), variable);
WriteCellData<?> cellData = convert(writeSheetHolder,
FieldUtils.getFieldClass(dataMap, variable, value), CellDataTypeEnum.STRING, cell, value,
excelContentProperty);
cellData.setAnalysisCell(analysisCell);
cellDataList.add(cellData); cellDataList.add(cellData);
CellDataTypeEnum type = cellData.getType(); CellDataTypeEnum type = cellData.getType();
if (type != null) { if (type != null) {
@ -235,8 +253,16 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
} }
cellValueBuild.append(analysisCell.getPrepareDataList().get(index)); cellValueBuild.append(analysisCell.getPrepareDataList().get(index));
cell.setCellValue(cellValueBuild.toString()); cell.setCellValue(cellValueBuild.toString());
// Restyle
if (fillConfig.getAutoStyle()) {
Optional.ofNullable(collectionFieldStyleCache.get(currentUniqueDataFlag))
.map(collectionFieldStyleMap -> collectionFieldStyleMap.get(analysisCell))
.ifPresent(cell::setCellStyle);
}
WriteHandlerUtils.afterCellDispose(writeContext, cellDataList, cell, null, relativeRowIndex, WriteHandlerUtils.afterCellDispose(writeContext, cellDataList, cell, null, relativeRowIndex,
Boolean.FALSE); Boolean.FALSE, ExcelContentProperty.EMPTY);
} }
} }
} }
@ -252,7 +278,8 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
return relativeRowIndex; return relativeRowIndex;
} }
private Cell getOneCell(AnalysisCell analysisCell, FillConfig fillConfig) { private Cell getOneCell(AnalysisCell analysisCell, FillConfig fillConfig,
ExcelContentProperty excelContentProperty) {
Sheet cachedSheet = writeContext.writeSheetHolder().getCachedSheet(); Sheet cachedSheet = writeContext.writeSheetHolder().getCachedSheet();
if (WriteTemplateAnalysisCellTypeEnum.COMMON.equals(analysisCell.getCellType())) { if (WriteTemplateAnalysisCellTypeEnum.COMMON.equals(analysisCell.getCellType())) {
return cachedSheet.getRow(analysisCell.getRowIndex()).getCell(analysisCell.getColumnIndex()); return cachedSheet.getRow(analysisCell.getRowIndex()).getCell(analysisCell.getColumnIndex());
@ -293,32 +320,25 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
} }
Row row = createRowIfNecessary(sheet, cachedSheet, lastRowIndex, fillConfig, analysisCell, isOriginalCell); Row row = createRowIfNecessary(sheet, cachedSheet, lastRowIndex, fillConfig, analysisCell, isOriginalCell);
Cell cell = createCellIfNecessary(row, lastColumnIndex); Cell cell = createCellIfNecessary(row, lastColumnIndex, excelContentProperty);
if (isOriginalCell) {
Map<AnalysisCell, CellStyle> collectionFieldStyleMap = collectionFieldStyleCache.computeIfAbsent( Map<AnalysisCell, CellStyle> collectionFieldStyleMap = collectionFieldStyleCache.computeIfAbsent(
currentUniqueDataFlag, key -> MapUtils.newHashMap()); currentUniqueDataFlag, key -> MapUtils.newHashMap());
if (isOriginalCell) {
collectionFieldStyleMap.put(analysisCell, cell.getCellStyle()); collectionFieldStyleMap.put(analysisCell, cell.getCellStyle());
} else {
if (fillConfig.getAutoStyle()) {
CellStyle cellStyle = collectionFieldStyleMap.get(analysisCell);
if (cellStyle != null) {
cell.setCellStyle(cellStyle);
}
}
} }
return cell; return cell;
} }
private Cell createCellIfNecessary(Row row, Integer lastColumnIndex) { private Cell createCellIfNecessary(Row row, Integer lastColumnIndex, ExcelContentProperty excelContentProperty) {
Cell cell = row.getCell(lastColumnIndex); Cell cell = row.getCell(lastColumnIndex);
if (cell != null) { if (cell != null) {
return cell; return cell;
} }
WriteHandlerUtils.beforeCellCreate(writeContext, row, null, lastColumnIndex, null, Boolean.FALSE); WriteHandlerUtils.beforeCellCreate(writeContext, row, null, lastColumnIndex, null, Boolean.FALSE,
excelContentProperty);
cell = row.createCell(lastColumnIndex); cell = row.createCell(lastColumnIndex);
WriteHandlerUtils.afterCellCreate(writeContext, cell, null, null, Boolean.FALSE); WriteHandlerUtils.afterCellCreate(writeContext, cell, null, null, Boolean.FALSE, excelContentProperty);
return cell; return cell;
} }

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

@ -5,6 +5,7 @@ import java.util.List;
import com.alibaba.excel.context.WriteContext; import com.alibaba.excel.context.WriteContext;
import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData; import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder; import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
@ -73,4 +74,8 @@ public class CellWriteHandlerContext {
* Nullable.It is null in the case of fill data. * Nullable.It is null in the case of fill data.
*/ */
private Boolean head; private Boolean head;
/**
* Field annotation configuration information.
*/
private ExcelContentProperty excelContentProperty;
} }

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

@ -11,6 +11,7 @@ import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.ss.usermodel.CellStyle;
/** /**
* fill cell style. * fill cell style.
@ -28,16 +29,20 @@ public class FillStyleCellWriteHandler implements CellWriteHandler {
@Override @Override
public void afterCellDispose(CellWriteHandlerContext context) { public void afterCellDispose(CellWriteHandlerContext context) {
List<WriteCellData<?>> cellDataList = context.getCellDataList(); List<WriteCellData<?>> cellDataList = context.getCellDataList();
if (CollectionUtils.isEmpty(cellDataList) || cellDataList.size() > 1) { if (CollectionUtils.size(cellDataList) != 1) {
return;
}
WriteCellData<?> cellData = context.getFirstCellData();
if (cellData.getAnalysisCell() != null && !cellData.getAnalysisCell().getOnlyOneVariable()) {
return; return;
} }
WriteCellData<?> cellData = cellDataList.get(0);
WriteCellStyle writeCellStyle = cellData.getWriteCellStyle(); WriteCellStyle writeCellStyle = cellData.getWriteCellStyle();
if (writeCellStyle == null) { CellStyle originCellStyle = cellData.getOriginCellStyle();
if (writeCellStyle == null && originCellStyle == null) {
return; return;
} }
WriteWorkbookHolder writeWorkbookHolder = context.getWriteWorkbookHolder(); WriteWorkbookHolder writeWorkbookHolder = context.getWriteWorkbookHolder();
context.getCell().setCellStyle(writeWorkbookHolder.createCellStyle(writeCellStyle)); context.getCell().setCellStyle(writeWorkbookHolder.createCellStyle(writeCellStyle, originCellStyle));
} }
} }

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

@ -18,6 +18,7 @@ import com.alibaba.excel.event.NotRepeatExecutor;
import com.alibaba.excel.event.Order; import com.alibaba.excel.event.Order;
import com.alibaba.excel.metadata.AbstractHolder; import com.alibaba.excel.metadata.AbstractHolder;
import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.metadata.property.LoopMergeProperty; import com.alibaba.excel.metadata.property.LoopMergeProperty;
import com.alibaba.excel.metadata.property.OnceAbsoluteMergeProperty; import com.alibaba.excel.metadata.property.OnceAbsoluteMergeProperty;
import com.alibaba.excel.metadata.property.RowHeightProperty; import com.alibaba.excel.metadata.property.RowHeightProperty;
@ -27,6 +28,7 @@ import com.alibaba.excel.write.handler.RowWriteHandler;
import com.alibaba.excel.write.handler.SheetWriteHandler; import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.handler.WorkbookWriteHandler; import com.alibaba.excel.write.handler.WorkbookWriteHandler;
import com.alibaba.excel.write.handler.WriteHandler; import com.alibaba.excel.write.handler.WriteHandler;
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
import com.alibaba.excel.write.merge.LoopMergeStrategy; import com.alibaba.excel.write.merge.LoopMergeStrategy;
import com.alibaba.excel.write.merge.OnceAbsoluteMergeStrategy; import com.alibaba.excel.write.merge.OnceAbsoluteMergeStrategy;
import com.alibaba.excel.write.metadata.WriteBasicParameter; import com.alibaba.excel.write.metadata.WriteBasicParameter;
@ -77,6 +79,7 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ
* Whether to automatically merge headers.Default is true. * Whether to automatically merge headers.Default is true.
*/ */
private Boolean automaticMergeHead; private Boolean automaticMergeHead;
/** /**
* Ignore the custom columns. * Ignore the custom columns.
*/ */
@ -194,7 +197,7 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ
} }
if (writeBasicParameter.getCustomConverterList() != null if (writeBasicParameter.getCustomConverterList() != null
&& !writeBasicParameter.getCustomConverterList().isEmpty()) { && !writeBasicParameter.getCustomConverterList().isEmpty()) {
for (Converter converter : writeBasicParameter.getCustomConverterList()) { for (Converter<?> converter : writeBasicParameter.getCustomConverterList()) {
getConverterMap().put(ConverterKeyBuild.buildKey(converter.supportJavaTypeKey()), converter); getConverterMap().put(ConverterKeyBuild.buildKey(converter.supportJavaTypeKey()), converter);
} }
} }
@ -215,8 +218,7 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ
if (head.getColumnWidthProperty() != null) { if (head.getColumnWidthProperty() != null) {
hasColumnWidth = true; hasColumnWidth = true;
} }
if (head.getHeadStyleProperty() != null || head.getHeadFontProperty() != null if (head.getHeadStyleProperty() != null || head.getHeadFontProperty() != null) {
|| head.getContentStyleProperty() != null || head.getContentFontProperty() != null) {
hasStyle = true; hasStyle = true;
} }
dealLoopMerge(handlerList, head); dealLoopMerge(handlerList, head);
@ -226,9 +228,9 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ
dealColumnWidth(handlerList); dealColumnWidth(handlerList);
} }
if (hasStyle) { //if (hasStyle) {
dealStyle(handlerList); dealStyle(handlerList);
} //}
dealRowHigh(handlerList); dealRowHigh(handlerList);
dealOnceAbsoluteMerge(handlerList); dealOnceAbsoluteMerge(handlerList);
@ -242,13 +244,17 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ
} }
@Override @Override
protected WriteCellStyle headCellStyle(Head head) { protected WriteCellStyle headCellStyle(CellWriteHandlerContext context) {
return WriteCellStyle.build(head.getHeadStyleProperty(), head.getHeadFontProperty()); ExcelContentProperty excelContentProperty = context.getExcelContentProperty();
return WriteCellStyle.build(excelContentProperty.getContentStyleProperty(),
excelContentProperty.getContentFontProperty());
} }
@Override @Override
protected WriteCellStyle contentCellStyle(Head head) { protected WriteCellStyle contentCellStyle(CellWriteHandlerContext context) {
return WriteCellStyle.build(head.getContentStyleProperty(), head.getContentFontProperty()); ExcelContentProperty excelContentProperty = context.getExcelContentProperty();
return WriteCellStyle.build(excelContentProperty.getContentStyleProperty(),
excelContentProperty.getContentFontProperty());
} }
}; };
handlerList.add(styleStrategy); handlerList.add(styleStrategy);

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

@ -24,11 +24,14 @@ import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont; import com.alibaba.excel.write.metadata.style.WriteFont;
import lombok.Data; import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook;
/** /**
@ -37,6 +40,7 @@ import org.apache.poi.xssf.usermodel.XSSFWorkbook;
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Data @Data
@Slf4j
public class WriteWorkbookHolder extends AbstractWriteHolder { public class WriteWorkbookHolder extends AbstractWriteHolder {
/*** /***
* Current poi Workbook.This is only for writing, and there may be no data in version 07 when template data needs to * Current poi Workbook.This is only for writing, and there may be no data in version 07 when template data needs to
@ -129,7 +133,7 @@ public class WriteWorkbookHolder extends AbstractWriteHolder {
/** /**
* Used to cell style. * Used to cell style.
*/ */
private Map<WriteCellStyle, CellStyle> cellStyleMap; private Map<Short, Map<WriteCellStyle, CellStyle>> cellStyleIndexMap;
/** /**
* Used to font. * Used to font.
*/ */
@ -206,7 +210,7 @@ public class WriteWorkbookHolder extends AbstractWriteHolder {
} else { } else {
this.writeExcelOnException = writeWorkbook.getWriteExcelOnException(); this.writeExcelOnException = writeWorkbook.getWriteExcelOnException();
} }
this.cellStyleMap = MapUtils.newHashMap(); this.cellStyleIndexMap = MapUtils.newHashMap();
this.fontMap = MapUtils.newHashMap(); this.fontMap = MapUtils.newHashMap();
this.dataFormatMap = MapUtils.newHashMap(); this.dataFormatMap = MapUtils.newHashMap();
} }
@ -242,17 +246,48 @@ public class WriteWorkbookHolder extends AbstractWriteHolder {
* create a cell style. * create a cell style.
* *
* @param writeCellStyle * @param writeCellStyle
* @param originCellStyle
* @return * @return
*/ */
public CellStyle createCellStyle(WriteCellStyle writeCellStyle) { public CellStyle createCellStyle(WriteCellStyle writeCellStyle, CellStyle originCellStyle) {
CellStyle cellStyle = cellStyleMap.get(writeCellStyle); if (writeCellStyle == null) {
return originCellStyle;
}
WriteCellStyle tempWriteCellStyle = new WriteCellStyle();
WriteCellStyle.merge(writeCellStyle, tempWriteCellStyle);
short styleIndex = -1;
Font originFont = null;
boolean useCache = true;
if (originCellStyle != null) {
styleIndex = originCellStyle.getIndex();
if (originCellStyle instanceof XSSFCellStyle) {
originFont = ((XSSFCellStyle)originCellStyle).getFont();
} else if (originCellStyle instanceof HSSFCellStyle) {
originFont = ((HSSFCellStyle)originCellStyle).getFont(workbook);
}
useCache = false;
}
Map<WriteCellStyle, CellStyle> cellStyleMap = cellStyleIndexMap.computeIfAbsent(styleIndex,
key -> MapUtils.newHashMap());
CellStyle cellStyle = cellStyleMap.get(tempWriteCellStyle);
if (cellStyle != null) { if (cellStyle != null) {
return cellStyle; return cellStyle;
} }
cellStyle = StyleUtil.buildCellStyle(workbook, writeCellStyle); if (log.isDebugEnabled()) {
cellStyle.setDataFormat(createDataFormat(writeCellStyle.getDataFormatData())); log.info("create new style:{},{}", tempWriteCellStyle, originCellStyle);
cellStyle.setFont(createFont(writeCellStyle.getWriteFont())); }
cellStyleMap.put(writeCellStyle, cellStyle); cellStyle = StyleUtil.buildCellStyle(workbook, originCellStyle, writeCellStyle);
Short dataFormat = createDataFormat(tempWriteCellStyle.getDataFormatData(), useCache);
if (dataFormat != null) {
cellStyle.setDataFormat(dataFormat);
}
Font font = createFont(tempWriteCellStyle.getWriteFont(), originFont, useCache);
if (font != null) {
cellStyle.setFont(font);
}
cellStyleMap.put(tempWriteCellStyle, cellStyle);
return cellStyle; return cellStyle;
} }
@ -260,15 +295,23 @@ public class WriteWorkbookHolder extends AbstractWriteHolder {
* create a font. * create a font.
* *
* @param writeFont * @param writeFont
* @param originFont
* @param useCache
* @return * @return
*/ */
public Font createFont(WriteFont writeFont) { public Font createFont(WriteFont writeFont, Font originFont, boolean useCache) {
Font font = fontMap.get(writeFont); if (!useCache) {
return StyleUtil.buildFont(workbook, originFont, writeFont);
}
WriteFont tempWriteFont = new WriteFont();
WriteFont.merge(writeFont, tempWriteFont);
Font font = fontMap.get(tempWriteFont);
if (font != null) { if (font != null) {
return font; return font;
} }
font = StyleUtil.buildFont(workbook, writeFont); font = StyleUtil.buildFont(workbook, originFont, tempWriteFont);
fontMap.put(writeFont, font); fontMap.put(tempWriteFont, font);
return font; return font;
} }
@ -276,15 +319,25 @@ public class WriteWorkbookHolder extends AbstractWriteHolder {
* create a data format. * create a data format.
* *
* @param dataFormatData * @param dataFormatData
* @param useCache
* @return * @return
*/ */
public Short createDataFormat(DataFormatData dataFormatData) { public Short createDataFormat(DataFormatData dataFormatData, boolean useCache) {
Short dataFormat = dataFormatMap.get(dataFormatData); if (dataFormatData == null) {
return null;
}
if (!useCache) {
return StyleUtil.buildDataFormat(workbook, dataFormatData);
}
DataFormatData tempDataFormatData = new DataFormatData();
DataFormatData.merge(dataFormatData, tempDataFormatData);
Short dataFormat = dataFormatMap.get(tempDataFormatData);
if (dataFormat != null) { if (dataFormat != null) {
return dataFormat; return dataFormat;
} }
dataFormat = StyleUtil.buildDataFormat(workbook, dataFormatData); dataFormat = StyleUtil.buildDataFormat(workbook, tempDataFormatData);
dataFormatMap.put(dataFormatData, dataFormat); dataFormatMap.put(tempDataFormatData, dataFormat);
return dataFormat; return dataFormat;
} }

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

@ -7,11 +7,8 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentFontStyle;
import com.alibaba.excel.annotation.write.style.ContentLoopMerge; import com.alibaba.excel.annotation.write.style.ContentLoopMerge;
import com.alibaba.excel.annotation.write.style.ContentRowHeight; import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import com.alibaba.excel.annotation.write.style.ContentStyle;
import com.alibaba.excel.annotation.write.style.HeadFontStyle; import com.alibaba.excel.annotation.write.style.HeadFontStyle;
import com.alibaba.excel.annotation.write.style.HeadRowHeight; import com.alibaba.excel.annotation.write.style.HeadRowHeight;
import com.alibaba.excel.annotation.write.style.HeadStyle; import com.alibaba.excel.annotation.write.style.HeadStyle;
@ -20,8 +17,6 @@ import com.alibaba.excel.enums.HeadKindEnum;
import com.alibaba.excel.metadata.CellRange; import com.alibaba.excel.metadata.CellRange;
import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.Holder; import com.alibaba.excel.metadata.Holder;
import com.alibaba.excel.metadata.property.ColumnWidthProperty;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.metadata.property.ExcelHeadProperty; import com.alibaba.excel.metadata.property.ExcelHeadProperty;
import com.alibaba.excel.metadata.property.FontProperty; import com.alibaba.excel.metadata.property.FontProperty;
import com.alibaba.excel.metadata.property.LoopMergeProperty; import com.alibaba.excel.metadata.property.LoopMergeProperty;
@ -29,49 +24,42 @@ import com.alibaba.excel.metadata.property.OnceAbsoluteMergeProperty;
import com.alibaba.excel.metadata.property.RowHeightProperty; import com.alibaba.excel.metadata.property.RowHeightProperty;
import com.alibaba.excel.metadata.property.StyleProperty; import com.alibaba.excel.metadata.property.StyleProperty;
import lombok.Data;
/** /**
* Define the header attribute of excel * Define the header attribute of excel
* *
* @author jipengfei * @author jipengfei
*/ */
@Data
public class ExcelWriteHeadProperty extends ExcelHeadProperty { public class ExcelWriteHeadProperty extends ExcelHeadProperty {
private RowHeightProperty headRowHeightProperty; private RowHeightProperty headRowHeightProperty;
private RowHeightProperty contentRowHeightProperty; private RowHeightProperty contentRowHeightProperty;
private OnceAbsoluteMergeProperty onceAbsoluteMergeProperty; private OnceAbsoluteMergeProperty onceAbsoluteMergeProperty;
public ExcelWriteHeadProperty(Holder holder, Class headClazz, List<List<String>> head) { public ExcelWriteHeadProperty(Holder holder, Class<?> headClazz, List<List<String>> head) {
super(holder, headClazz, head); super(holder, headClazz, head);
if (getHeadKind() != HeadKindEnum.CLASS) { if (getHeadKind() != HeadKindEnum.CLASS) {
return; return;
} }
this.headRowHeightProperty = this.headRowHeightProperty =
RowHeightProperty.build((HeadRowHeight)headClazz.getAnnotation(HeadRowHeight.class)); RowHeightProperty.build(headClazz.getAnnotation(HeadRowHeight.class));
this.contentRowHeightProperty = this.contentRowHeightProperty =
RowHeightProperty.build((ContentRowHeight)headClazz.getAnnotation(ContentRowHeight.class)); RowHeightProperty.build(headClazz.getAnnotation(ContentRowHeight.class));
this.onceAbsoluteMergeProperty = this.onceAbsoluteMergeProperty =
OnceAbsoluteMergeProperty.build((OnceAbsoluteMerge)headClazz.getAnnotation(OnceAbsoluteMerge.class)); OnceAbsoluteMergeProperty.build(headClazz.getAnnotation(OnceAbsoluteMerge.class));
ColumnWidth parentColumnWidth = (ColumnWidth)headClazz.getAnnotation(ColumnWidth.class); HeadStyle parentHeadStyle = headClazz.getAnnotation(HeadStyle.class);
HeadStyle parentHeadStyle = (HeadStyle)headClazz.getAnnotation(HeadStyle.class); HeadFontStyle parentHeadFontStyle = headClazz.getAnnotation(HeadFontStyle.class);
HeadFontStyle parentHeadFontStyle = (HeadFontStyle)headClazz.getAnnotation(HeadFontStyle.class);
ContentStyle parentContentStyle = (ContentStyle)headClazz.getAnnotation(ContentStyle.class);
ContentFontStyle parentContentFontStyle = (ContentFontStyle)headClazz.getAnnotation(ContentFontStyle.class);
for (Map.Entry<Integer, ExcelContentProperty> entry : getContentPropertyMap().entrySet()) { for (Map.Entry<Integer, Head> entry : getHeadMap().entrySet()) {
Integer index = entry.getKey(); Head headData = entry.getValue();
ExcelContentProperty excelContentPropertyData = entry.getValue(); if (headData == null) {
if (excelContentPropertyData == null) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Passing in the class and list the head, the two must be the same size."); "Passing in the class and list the head, the two must be the same size.");
} }
Field field = excelContentPropertyData.getField(); Field field = headData.getField();
Head headData = getHeadMap().get(index);
ColumnWidth columnWidth = field.getAnnotation(ColumnWidth.class);
if (columnWidth == null) {
columnWidth = parentColumnWidth;
}
headData.setColumnWidthProperty(ColumnWidthProperty.build(columnWidth));
HeadStyle headStyle = field.getAnnotation(HeadStyle.class); HeadStyle headStyle = field.getAnnotation(HeadStyle.class);
if (headStyle == null) { if (headStyle == null) {
@ -85,46 +73,10 @@ public class ExcelWriteHeadProperty extends ExcelHeadProperty {
} }
headData.setHeadFontProperty(FontProperty.build(headFontStyle)); headData.setHeadFontProperty(FontProperty.build(headFontStyle));
ContentStyle contentStyle = field.getAnnotation(ContentStyle.class);
if (contentStyle == null) {
contentStyle = parentContentStyle;
}
headData.setContentStyleProperty(StyleProperty.build(contentStyle));
ContentFontStyle contentFontStyle = field.getAnnotation(ContentFontStyle.class);
if (contentFontStyle == null) {
contentFontStyle = parentContentFontStyle;
}
headData.setContentFontProperty(FontProperty.build(contentFontStyle));
headData.setLoopMergeProperty(LoopMergeProperty.build(field.getAnnotation(ContentLoopMerge.class))); headData.setLoopMergeProperty(LoopMergeProperty.build(field.getAnnotation(ContentLoopMerge.class)));
} }
} }
public RowHeightProperty getHeadRowHeightProperty() {
return headRowHeightProperty;
}
public void setHeadRowHeightProperty(RowHeightProperty headRowHeightProperty) {
this.headRowHeightProperty = headRowHeightProperty;
}
public RowHeightProperty getContentRowHeightProperty() {
return contentRowHeightProperty;
}
public void setContentRowHeightProperty(RowHeightProperty contentRowHeightProperty) {
this.contentRowHeightProperty = contentRowHeightProperty;
}
public OnceAbsoluteMergeProperty getOnceAbsoluteMergeProperty() {
return onceAbsoluteMergeProperty;
}
public void setOnceAbsoluteMergeProperty(OnceAbsoluteMergeProperty onceAbsoluteMergeProperty) {
this.onceAbsoluteMergeProperty = onceAbsoluteMergeProperty;
}
/** /**
* Calculate all cells that need to be merged * Calculate all cells that need to be merged
* *

28
src/main/java/com/alibaba/excel/write/style/AbstractVerticalCellStyleStrategy.java

@ -18,12 +18,12 @@ public abstract class AbstractVerticalCellStyleStrategy extends AbstractCellStyl
return; return;
} }
WriteCellData<?> cellData = context.getFirstCellData(); WriteCellData<?> cellData = context.getFirstCellData();
WriteCellStyle.merge(headCellStyle(context.getHeadData()), cellData.getOrCreateStyle()); WriteCellStyle.merge(headCellStyle(context), cellData.getOrCreateStyle());
} }
@Override @Override
protected void setContentCellStyle(CellWriteHandlerContext context) { protected void setContentCellStyle(CellWriteHandlerContext context) {
if (stopProcessing(context)) { if (context.getFirstCellData() == null) {
return; return;
} }
WriteCellData<?> cellData = context.getFirstCellData(); WriteCellData<?> cellData = context.getFirstCellData();
@ -31,13 +31,13 @@ public abstract class AbstractVerticalCellStyleStrategy extends AbstractCellStyl
} }
/** /**
* Returns the column width corresponding to each column head. * Returns the column width corresponding to each column head
* *
* @param context * @param context
* @return * @return
*/ */
protected WriteCellStyle contentCellStyle(CellWriteHandlerContext context) { protected WriteCellStyle headCellStyle(CellWriteHandlerContext context) {
return contentCellStyle(context.getHeadData()); return headCellStyle(context.getHeadData());
} }
/** /**
@ -46,7 +46,19 @@ public abstract class AbstractVerticalCellStyleStrategy extends AbstractCellStyl
* @param head Nullable * @param head Nullable
* @return * @return
*/ */
protected abstract WriteCellStyle headCellStyle(Head head); protected WriteCellStyle headCellStyle(Head head) {
return null;
}
/**
* Returns the column width corresponding to each column head.
*
* @param context
* @return
*/
protected WriteCellStyle contentCellStyle(CellWriteHandlerContext context) {
return contentCellStyle(context.getHeadData());
}
/** /**
* Returns the column width corresponding to each column head * Returns the column width corresponding to each column head
@ -55,9 +67,7 @@ public abstract class AbstractVerticalCellStyleStrategy extends AbstractCellStyl
* @return * @return
*/ */
protected WriteCellStyle contentCellStyle(Head head) { protected WriteCellStyle contentCellStyle(Head head) {
throw new UnsupportedOperationException( return null;
"One of the two methods 'contentCellStyle(Cell cell, Head head, Integer relativeRowIndex)' and "
+ "'contentCellStyle(Head head)' must be implemented.");
} }
protected boolean stopProcessing(CellWriteHandlerContext context) { protected boolean stopProcessing(CellWriteHandlerContext context) {

43
src/test/java/com/alibaba/easyexcel/test/core/StyleTestUtils.java

@ -0,0 +1,43 @@
package com.alibaba.easyexcel.test.core;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFCell;
public class StyleTestUtils {
public static byte[] getFillForegroundColor(Cell cell) {
if (cell instanceof XSSFCell) {
return ((XSSFCell)cell).getCellStyle().getFillForegroundColorColor().getRGB();
} else {
return short2byte(((HSSFCell)cell).getCellStyle().getFillForegroundColorColor().getTriplet());
}
}
public static byte[] getFontColor(Cell cell, Workbook workbook) {
if (cell instanceof XSSFCell) {
return ((XSSFCell)cell).getCellStyle().getFont().getXSSFColor().getRGB();
} else {
return short2byte(((HSSFCell)cell).getCellStyle().getFont(workbook).getHSSFColor((HSSFWorkbook)workbook)
.getTriplet());
}
}
public static short getFontHeightInPoints(Cell cell, Workbook workbook) {
if (cell instanceof XSSFCell) {
return ((XSSFCell)cell).getCellStyle().getFont().getFontHeightInPoints();
} else {
return ((HSSFCell)cell).getCellStyle().getFont(workbook).getFontHeightInPoints();
}
}
private static byte[] short2byte(short[] shorts) {
byte[] bytes = new byte[shorts.length];
for (int i = 0; i < shorts.length; i++) {
bytes[i] = (byte)shorts[i];
}
return bytes;
}
}

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

@ -6,23 +6,23 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
import com.alibaba.easyexcel.test.util.TestFileUtil; import com.alibaba.easyexcel.test.util.TestFileUtil;
import com.alibaba.excel.EasyExcel; import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.enums.WriteDirectionEnum; import com.alibaba.excel.enums.WriteDirectionEnum;
import com.alibaba.excel.exception.ExcelGenerateException;
import com.alibaba.excel.write.merge.LoopMergeStrategy; import com.alibaba.excel.write.merge.LoopMergeStrategy;
import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig; import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.excel.write.metadata.fill.FillWrapper; import com.alibaba.excel.write.metadata.fill.FillWrapper;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
/** /**
*
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@FixMethodOrder(MethodSorters.NAME_ASCENDING) @FixMethodOrder(MethodSorters.NAME_ASCENDING)
@ -30,8 +30,10 @@ public class FillDataTest {
private static File file07; private static File file07;
private static File file03; private static File file03;
private static File fileCsv;
private static File simpleTemplate07; private static File simpleTemplate07;
private static File simpleTemplate03; private static File simpleTemplate03;
private static File simpleTemplateCsv;
private static File fileComplex07; private static File fileComplex07;
private static File complexFillTemplate07; private static File complexFillTemplate07;
private static File fileComplex03; private static File fileComplex03;
@ -53,8 +55,10 @@ public class FillDataTest {
public static void init() { public static void init() {
file07 = TestFileUtil.createNewFile("fill07.xlsx"); file07 = TestFileUtil.createNewFile("fill07.xlsx");
file03 = TestFileUtil.createNewFile("fill03.xls"); file03 = TestFileUtil.createNewFile("fill03.xls");
fileCsv = TestFileUtil.createNewFile("fill.csv");
simpleTemplate07 = TestFileUtil.readFile("fill" + File.separator + "simple.xlsx"); simpleTemplate07 = TestFileUtil.readFile("fill" + File.separator + "simple.xlsx");
simpleTemplate03 = TestFileUtil.readFile("fill" + File.separator + "simple.xls"); simpleTemplate03 = TestFileUtil.readFile("fill" + File.separator + "simple.xls");
simpleTemplateCsv = TestFileUtil.readFile("fill" + File.separator + "simple.csv");
fileComplex07 = TestFileUtil.createNewFile("fillComplex07.xlsx"); fileComplex07 = TestFileUtil.createNewFile("fillComplex07.xlsx");
complexFillTemplate07 = TestFileUtil.readFile("fill" + File.separator + "complex.xlsx"); complexFillTemplate07 = TestFileUtil.readFile("fill" + File.separator + "complex.xlsx");
fileComplex03 = TestFileUtil.createNewFile("fillComplex03.xls"); fileComplex03 = TestFileUtil.createNewFile("fillComplex03.xls");
@ -83,6 +87,13 @@ public class FillDataTest {
fill(file03, simpleTemplate03); fill(file03, simpleTemplate03);
} }
@Test
public void t03FillCsv() {
ExcelGenerateException excelGenerateException = Assert.assertThrows(ExcelGenerateException.class,
() -> fill(fileCsv, simpleTemplateCsv));
Assert.assertEquals("csv cannot use template.", excelGenerateException.getMessage());
}
@Test @Test
public void t03ComplexFill07() { public void t03ComplexFill07() {
complexFill(fileComplex07, complexFillTemplate07); complexFill(fileComplex07, complexFillTemplate07);
@ -147,11 +158,11 @@ public class FillDataTest {
excelWriter.finish(); excelWriter.finish();
List<Object> list = EasyExcel.read(file).ignoreEmptyRow(false).sheet().headRowNumber(0).doReadSync(); List<Object> list = EasyExcel.read(file).ignoreEmptyRow(false).sheet().headRowNumber(0).doReadSync();
Map<String, String> map0 = (Map<String, String>) list.get(0); Map<String, String> map0 = (Map<String, String>)list.get(0);
Assert.assertEquals("张三", map0.get(21)); Assert.assertEquals("张三", map0.get(21));
Map<String, String> map27 = (Map<String, String>) list.get(27); Map<String, String> map27 = (Map<String, String>)list.get(27);
Assert.assertEquals("张三", map27.get(0)); Assert.assertEquals("张三", map27.get(0));
Map<String, String> map29 = (Map<String, String>) list.get(29); Map<String, String> map29 = (Map<String, String>)list.get(29);
Assert.assertEquals("张三", map29.get(3)); Assert.assertEquals("张三", map29.get(3));
} }
@ -168,7 +179,7 @@ public class FillDataTest {
List<Object> list = EasyExcel.read(file).sheet().headRowNumber(0).doReadSync(); List<Object> list = EasyExcel.read(file).sheet().headRowNumber(0).doReadSync();
Assert.assertEquals(list.size(), 5L); Assert.assertEquals(list.size(), 5L);
Map<String, String> map0 = (Map<String, String>) list.get(0); Map<String, String> map0 = (Map<String, String>)list.get(0);
Assert.assertEquals("张三", map0.get(2)); Assert.assertEquals("张三", map0.get(2));
} }
@ -185,7 +196,7 @@ public class FillDataTest {
excelWriter.finish(); excelWriter.finish();
List<Object> list = EasyExcel.read(file).sheet().headRowNumber(3).doReadSync(); List<Object> list = EasyExcel.read(file).sheet().headRowNumber(3).doReadSync();
Assert.assertEquals(list.size(), 21L); Assert.assertEquals(list.size(), 21L);
Map<String, String> map19 = (Map<String, String>) list.get(19); Map<String, String> map19 = (Map<String, String>)list.get(19);
Assert.assertEquals("张三", map19.get(0)); Assert.assertEquals("张三", map19.get(0));
} }

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

@ -0,0 +1,29 @@
package com.alibaba.easyexcel.test.core.fill.style;
import java.util.Date;
import com.alibaba.excel.annotation.write.style.ContentFontStyle;
import com.alibaba.excel.annotation.write.style.ContentStyle;
import com.alibaba.excel.enums.BooleanEnum;
import com.alibaba.excel.enums.poi.FillPatternTypeEnum;
import lombok.Data;
/**
* @author Jiaju Zhuang
*/
@Data
public class FillStyleAnnotatedData {
@ContentStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 13)
@ContentFontStyle(bold = BooleanEnum.TRUE, color = 19)
private String name;
@ContentStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 10)
@ContentFontStyle(bold = BooleanEnum.TRUE, color = 16)
private Double number;
@ContentStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 17)
@ContentFontStyle(bold = BooleanEnum.TRUE, color = 58)
private Date date;
@ContentStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 12)
@ContentFontStyle(bold = BooleanEnum.TRUE, color = 18)
private String empty;
}

325
src/test/java/com/alibaba/easyexcel/test/core/fill/style/FillStyleAnnotatedTest.java

@ -0,0 +1,325 @@
package com.alibaba.easyexcel.test.core.fill.style;
import java.io.File;
import java.io.FileInputStream;
import java.util.List;
import com.alibaba.easyexcel.test.core.fill.FillData;
import com.alibaba.easyexcel.test.util.TestFileUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.util.DateUtils;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.AbstractVerticalCellStyleStrategy;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
/**
* @author Jiaju Zhuang
*/
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class FillStyleAnnotatedTest {
private static File FillStyleAnnotated07;
private static File FillStyleAnnotated03;
private static File fileStyleTemplate07;
private static File fileStyleTemplate03;
@BeforeClass
public static void init() {
FillStyleAnnotated07 = TestFileUtil.createNewFile("FillStyleAnnotated07.xlsx");
FillStyleAnnotated03 = TestFileUtil.createNewFile("FillStyleAnnotated03.xls");
fileStyleTemplate07 = TestFileUtil.readFile("fill" + File.separator + "style.xlsx");
fileStyleTemplate03 = TestFileUtil.readFile("fill" + File.separator + "style.xls");
}
@Test
public void t01Fill07() throws Exception {
fill(FillStyleAnnotated07, fileStyleTemplate07);
XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream(FillStyleAnnotated07));
XSSFSheet sheet = workbook.getSheetAt(0);
t01Fill07check(sheet.getRow(1));
t01Fill07check(sheet.getRow(2));
}
private void t01Fill07check(XSSFRow row) {
XSSFCell cell0 = row.getCell(0);
Assert.assertEquals("张三", cell0.getStringCellValue());
Assert.assertEquals(49, cell0.getCellStyle().getDataFormat());
Assert.assertEquals("FFFFFF00", cell0.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assert.assertEquals("FF808000", cell0.getCellStyle().getFont().getXSSFColor().getARGBHex());
Assert.assertTrue(cell0.getCellStyle().getFont().getBold());
XSSFCell cell1 = row.getCell(1);
Assert.assertEquals(5.2, cell1.getNumericCellValue(), 1);
Assert.assertEquals(0, cell1.getCellStyle().getDataFormat());
Assert.assertEquals("FFFF0000", cell1.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assert.assertEquals("FF800000", cell1.getCellStyle().getFont().getXSSFColor().getARGBHex());
Assert.assertTrue(cell1.getCellStyle().getFont().getBold());
XSSFCell cell2 = row.getCell(2);
Assert.assertEquals("2020-01-01 01:01:01", DateUtils.format(cell2.getDateCellValue(), "yyyy-MM-dd HH:mm:ss"));
Assert.assertEquals("yyyy-MM-dd HH:mm:ss", cell2.getCellStyle().getDataFormatString());
Assert.assertEquals("FF008000", cell2.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assert.assertEquals("FF003300", cell2.getCellStyle().getFont().getXSSFColor().getARGBHex());
Assert.assertTrue(cell2.getCellStyle().getFont().getBold());
XSSFCell cell3 = row.getCell(3);
Assert.assertEquals("张三今年5.2岁了", cell3.getStringCellValue());
Assert.assertEquals(0, cell3.getCellStyle().getDataFormat());
Assert.assertEquals("FFFF0000", cell3.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assert.assertEquals("FFEEECE1", cell3.getCellStyle().getFont().getXSSFColor().getARGBHex());
Assert.assertTrue(cell3.getCellStyle().getFont().getBold());
XSSFCell cell4 = row.getCell(4);
Assert.assertEquals("{.name}忽略,张三", cell4.getStringCellValue());
Assert.assertEquals(0, cell4.getCellStyle().getDataFormat());
Assert.assertEquals("FFC00000", cell4.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assert.assertEquals("FF000000", cell4.getCellStyle().getFont().getXSSFColor().getARGBHex());
Assert.assertFalse(cell4.getCellStyle().getFont().getBold());
XSSFCell cell5 = row.getCell(5);
Assert.assertEquals("空", cell5.getStringCellValue());
Assert.assertEquals(0, cell5.getCellStyle().getDataFormat());
Assert.assertEquals("FFF79646", cell5.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assert.assertEquals("FF8064A2", cell5.getCellStyle().getFont().getXSSFColor().getARGBHex());
Assert.assertFalse(cell5.getCellStyle().getFont().getBold());
}
@Test
public void t02Fill03() throws Exception {
fill(FillStyleAnnotated03, fileStyleTemplate03);
HSSFWorkbook workbook = new HSSFWorkbook(new FileInputStream(FillStyleAnnotated03));
HSSFSheet sheet = workbook.getSheetAt(0);
t02Fill03check(workbook, sheet.getRow(1));
t02Fill03check(workbook, sheet.getRow(2));
}
private void t02Fill03check(HSSFWorkbook workbook, HSSFRow row) {
HSSFCell cell0 = row.getCell(0);
Assert.assertEquals("张三", cell0.getStringCellValue());
Assert.assertEquals(49, cell0.getCellStyle().getDataFormat());
Assert.assertEquals("FFFF:FFFF:0", cell0.getCellStyle().getFillForegroundColorColor().getHexString());
Assert.assertEquals("8080:8080:0", cell0.getCellStyle().getFont(workbook).getHSSFColor(workbook)
.getHexString());
Assert.assertTrue(cell0.getCellStyle().getFont(workbook).getBold());
HSSFCell cell1 = row.getCell(1);
Assert.assertEquals(5.2, cell1.getNumericCellValue(), 1);
Assert.assertEquals(0, cell1.getCellStyle().getDataFormat());
Assert.assertEquals("FFFF:0:0", cell1.getCellStyle().getFillForegroundColorColor().getHexString());
Assert.assertEquals("8080:0:0", cell1.getCellStyle().getFont(workbook).getHSSFColor(workbook)
.getHexString());
Assert.assertTrue(cell1.getCellStyle().getFont(workbook).getBold());
HSSFCell cell2 = row.getCell(2);
Assert.assertEquals("2020-01-01 01:01:01", DateUtils.format(cell2.getDateCellValue(), "yyyy-MM-dd HH:mm:ss"));
Assert.assertEquals("yyyy-MM-dd HH:mm:ss", cell2.getCellStyle().getDataFormatString());
Assert.assertEquals("0:8080:0", cell2.getCellStyle().getFillForegroundColorColor().getHexString());
Assert.assertEquals("0:3333:0", cell2.getCellStyle().getFont(workbook).getHSSFColor(workbook).getHexString());
Assert.assertTrue(cell2.getCellStyle().getFont(workbook).getBold());
HSSFCell cell3 = row.getCell(3);
Assert.assertEquals("张三今年5.2岁了", cell3.getStringCellValue());
Assert.assertEquals(0, cell3.getCellStyle().getDataFormat());
Assert.assertEquals("FFFF:0:0", cell3.getCellStyle().getFillForegroundColorColor().getHexString());
Assert.assertEquals("FFFF:FFFF:9999", cell3.getCellStyle().getFont(workbook).getHSSFColor(workbook)
.getHexString());
Assert.assertTrue(cell3.getCellStyle().getFont(workbook).getBold());
HSSFCell cell4 = row.getCell(4);
Assert.assertEquals("{.name}忽略,张三", cell4.getStringCellValue());
Assert.assertEquals(0, cell4.getCellStyle().getDataFormat());
Assert.assertEquals("9999:3333:0", cell4.getCellStyle().getFillForegroundColorColor().getHexString());
Assert.assertEquals("3333:3333:3333", cell4.getCellStyle().getFont(workbook).getHSSFColor(workbook)
.getHexString());
Assert.assertFalse(cell4.getCellStyle().getFont(workbook).getBold());
HSSFCell cell5 = row.getCell(5);
Assert.assertEquals("空", cell5.getStringCellValue());
Assert.assertEquals(0, cell5.getCellStyle().getDataFormat());
Assert.assertEquals("9999:3333:0", cell5.getCellStyle().getFillForegroundColorColor().getHexString());
Assert.assertEquals("CCCC:9999:FFFF", cell5.getCellStyle().getFont(workbook).getHSSFColor(workbook)
.getHexString());
Assert.assertFalse(cell5.getCellStyle().getFont(workbook).getBold());
}
private void fill(File file, File template) throws Exception {
EasyExcel.write(file, FillStyleAnnotatedData.class).withTemplate(template).sheet().doFill(data());
}
private void t11FillStyleHandler07check(XSSFRow row) {
XSSFCell cell0 = row.getCell(0);
Assert.assertEquals("张三", cell0.getStringCellValue());
Assert.assertEquals(49, cell0.getCellStyle().getDataFormat());
Assert.assertEquals("FFFFFF00", cell0.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assert.assertEquals("FF808000", cell0.getCellStyle().getFont().getXSSFColor().getARGBHex());
Assert.assertTrue(cell0.getCellStyle().getFont().getBold());
XSSFCell cell1 = row.getCell(1);
Assert.assertEquals("5", cell1.getStringCellValue());
Assert.assertEquals(0, cell1.getCellStyle().getDataFormat());
Assert.assertEquals("FFFF0000", cell1.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assert.assertEquals("FF800000", cell1.getCellStyle().getFont().getXSSFColor().getARGBHex());
Assert.assertTrue(cell1.getCellStyle().getFont().getBold());
XSSFCell cell2 = row.getCell(2);
Assert.assertEquals("2020-01-01 01:01:01", DateUtils.format(cell2.getDateCellValue(), "yyyy-MM-dd HH:mm:ss"));
Assert.assertEquals("yyyy-MM-dd HH:mm:ss", cell2.getCellStyle().getDataFormatString());
Assert.assertEquals("FF008000", cell2.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assert.assertEquals("FF003300", cell2.getCellStyle().getFont().getXSSFColor().getARGBHex());
Assert.assertTrue(cell2.getCellStyle().getFont().getBold());
XSSFCell cell3 = row.getCell(3);
Assert.assertEquals("张三今年5岁了", cell3.getStringCellValue());
Assert.assertEquals(0, cell3.getCellStyle().getDataFormat());
Assert.assertEquals("FF0000FF", cell3.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assert.assertEquals("FF000080", cell3.getCellStyle().getFont().getXSSFColor().getARGBHex());
Assert.assertTrue(cell3.getCellStyle().getFont().getBold());
XSSFCell cell4 = row.getCell(4);
Assert.assertEquals("{.name}忽略,张三", cell4.getStringCellValue());
Assert.assertEquals(0, cell4.getCellStyle().getDataFormat());
Assert.assertEquals("FFFFFF00", cell4.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assert.assertEquals("FF808000", cell4.getCellStyle().getFont().getXSSFColor().getARGBHex());
Assert.assertTrue(cell4.getCellStyle().getFont().getBold());
XSSFCell cell5 = row.getCell(5);
Assert.assertEquals("空", cell5.getStringCellValue());
Assert.assertEquals(0, cell5.getCellStyle().getDataFormat());
Assert.assertEquals("FF008080", cell5.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assert.assertEquals("FF003366", cell5.getCellStyle().getFont().getXSSFColor().getARGBHex());
Assert.assertTrue(cell5.getCellStyle().getFont().getBold());
}
private void t12FillStyleHandler03check(HSSFWorkbook workbook, HSSFRow row) {
HSSFCell cell0 = row.getCell(0);
Assert.assertEquals("张三", cell0.getStringCellValue());
Assert.assertEquals(49, cell0.getCellStyle().getDataFormat());
Assert.assertEquals("FFFF:FFFF:0", cell0.getCellStyle().getFillForegroundColorColor().getHexString());
Assert.assertEquals("8080:8080:0", cell0.getCellStyle().getFont(workbook).getHSSFColor(workbook)
.getHexString());
Assert.assertTrue(cell0.getCellStyle().getFont(workbook).getBold());
HSSFCell cell1 = row.getCell(1);
Assert.assertEquals("5", cell1.getStringCellValue());
Assert.assertEquals(0, cell1.getCellStyle().getDataFormat());
Assert.assertEquals("FFFF:0:0", cell1.getCellStyle().getFillForegroundColorColor().getHexString());
Assert.assertEquals("8080:0:0", cell1.getCellStyle().getFont(workbook).getHSSFColor(workbook)
.getHexString());
Assert.assertTrue(cell1.getCellStyle().getFont(workbook).getBold());
HSSFCell cell2 = row.getCell(2);
Assert.assertEquals("2020-01-01 01:01:01", DateUtils.format(cell2.getDateCellValue(), "yyyy-MM-dd HH:mm:ss"));
Assert.assertEquals("yyyy-MM-dd HH:mm:ss", cell2.getCellStyle().getDataFormatString());
Assert.assertEquals("0:8080:0", cell2.getCellStyle().getFillForegroundColorColor().getHexString());
Assert.assertEquals("0:3333:0", cell2.getCellStyle().getFont(workbook).getHSSFColor(workbook).getHexString());
Assert.assertTrue(cell2.getCellStyle().getFont(workbook).getBold());
HSSFCell cell3 = row.getCell(3);
Assert.assertEquals("张三今年5岁了", cell3.getStringCellValue());
Assert.assertEquals(0, cell3.getCellStyle().getDataFormat());
Assert.assertEquals("0:0:FFFF", cell3.getCellStyle().getFillForegroundColorColor().getHexString());
Assert.assertEquals("0:0:8080", cell3.getCellStyle().getFont(workbook).getHSSFColor(workbook)
.getHexString());
Assert.assertTrue(cell3.getCellStyle().getFont(workbook).getBold());
HSSFCell cell4 = row.getCell(4);
Assert.assertEquals("{.name}忽略,张三", cell4.getStringCellValue());
Assert.assertEquals(0, cell4.getCellStyle().getDataFormat());
Assert.assertEquals("FFFF:FFFF:0", cell4.getCellStyle().getFillForegroundColorColor().getHexString());
Assert.assertEquals("8080:8080:0", cell4.getCellStyle().getFont(workbook).getHSSFColor(workbook)
.getHexString());
Assert.assertTrue(cell4.getCellStyle().getFont(workbook).getBold());
HSSFCell cell5 = row.getCell(5);
Assert.assertEquals("空", cell5.getStringCellValue());
Assert.assertEquals(0, cell5.getCellStyle().getDataFormat());
Assert.assertEquals("0:8080:8080", cell5.getCellStyle().getFillForegroundColorColor().getHexString());
Assert.assertEquals("0:3333:6666", cell5.getCellStyle().getFont(workbook).getHSSFColor(workbook)
.getHexString());
Assert.assertTrue(cell5.getCellStyle().getFont(workbook).getBold());
}
private void fillStyleHandler(File file, File template) throws Exception {
EasyExcel.write(file, FillData.class).withTemplate(template).sheet()
.registerWriteHandler(new AbstractVerticalCellStyleStrategy() {
@Override
protected WriteCellStyle contentCellStyle(CellWriteHandlerContext context) {
WriteCellStyle writeCellStyle = new WriteCellStyle();
WriteFont writeFont = new WriteFont();
writeCellStyle.setWriteFont(writeFont);
writeCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
writeFont.setBold(true);
if (context.getColumnIndex() == 0) {
writeCellStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
writeFont.setColor(IndexedColors.DARK_YELLOW.getIndex());
}
if (context.getColumnIndex() == 1) {
writeCellStyle.setFillForegroundColor(IndexedColors.RED.getIndex());
writeFont.setColor(IndexedColors.DARK_RED.getIndex());
}
if (context.getColumnIndex() == 2) {
writeCellStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex());
writeFont.setColor(IndexedColors.DARK_GREEN.getIndex());
}
if (context.getColumnIndex() == 3) {
writeCellStyle.setFillForegroundColor(IndexedColors.BLUE.getIndex());
writeFont.setColor(IndexedColors.DARK_BLUE.getIndex());
}
if (context.getColumnIndex() == 4) {
writeCellStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
writeFont.setColor(IndexedColors.DARK_YELLOW.getIndex());
}
if (context.getColumnIndex() == 5) {
writeCellStyle.setFillForegroundColor(IndexedColors.TEAL.getIndex());
writeFont.setColor(IndexedColors.DARK_TEAL.getIndex());
}
return writeCellStyle;
}
@Override
protected WriteCellStyle headCellStyle(Head head) {
return null;
}
})
.doFill(data());
}
private List<FillStyleAnnotatedData> data() throws Exception {
List<FillStyleAnnotatedData> list = ListUtils.newArrayList();
for (int i = 0; i < 10; i++) {
FillStyleAnnotatedData fillData = new FillStyleAnnotatedData();
list.add(fillData);
fillData.setName("张三");
fillData.setNumber(5.2);
fillData.setDate(DateUtils.parseDate("2020-01-01 01:01:01"));
if (i == 5) {
fillData.setName(null);
}
}
return list;
}
}

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

@ -0,0 +1,16 @@
package com.alibaba.easyexcel.test.core.fill.style;
import java.util.Date;
import lombok.Data;
/**
* @author Jiaju Zhuang
*/
@Data
public class FillStyleData {
private String name;
private Double number;
private Date date;
private String empty;
}

344
src/test/java/com/alibaba/easyexcel/test/core/fill/style/FillStyleDataTest.java

@ -0,0 +1,344 @@
package com.alibaba.easyexcel.test.core.fill.style;
import java.io.File;
import java.io.FileInputStream;
import java.util.List;
import com.alibaba.easyexcel.test.util.TestFileUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.util.DateUtils;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.AbstractVerticalCellStyleStrategy;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
/**
* @author Jiaju Zhuang
*/
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class FillStyleDataTest {
private static File fileStyle07;
private static File fileStyle03;
private static File fileStyleHandler07;
private static File fileStyleHandler03;
private static File fileStyleTemplate07;
private static File fileStyleTemplate03;
@BeforeClass
public static void init() {
fileStyle07 = TestFileUtil.createNewFile("fileStyle07.xlsx");
fileStyle03 = TestFileUtil.createNewFile("fileStyle03.xls");
fileStyleHandler07 = TestFileUtil.createNewFile("fileStyleHandler07.xlsx");
fileStyleHandler03 = TestFileUtil.createNewFile("fileStyleHandler03.xls");
fileStyleTemplate07 = TestFileUtil.readFile("fill" + File.separator + "style.xlsx");
fileStyleTemplate03 = TestFileUtil.readFile("fill" + File.separator + "style.xls");
}
@Test
public void t01Fill07() throws Exception {
fill(fileStyle07, fileStyleTemplate07);
XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream(fileStyle07));
XSSFSheet sheet = workbook.getSheetAt(0);
t01Fill07check(sheet.getRow(1));
t01Fill07check(sheet.getRow(2));
}
private void t01Fill07check(XSSFRow row) {
XSSFCell cell0 = row.getCell(0);
Assert.assertEquals("张三", cell0.getStringCellValue());
Assert.assertEquals(49, cell0.getCellStyle().getDataFormat());
Assert.assertEquals("FF00B050", cell0.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assert.assertEquals("FF7030A0", cell0.getCellStyle().getFont().getXSSFColor().getARGBHex());
Assert.assertTrue(cell0.getCellStyle().getFont().getBold());
XSSFCell cell1 = row.getCell(1);
Assert.assertEquals(5.2, cell1.getNumericCellValue(), 1);
Assert.assertEquals(0, cell1.getCellStyle().getDataFormat());
Assert.assertEquals("FF92D050", cell1.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assert.assertEquals("FF4BACC6", cell1.getCellStyle().getFont().getXSSFColor().getARGBHex());
Assert.assertFalse(cell1.getCellStyle().getFont().getBold());
XSSFCell cell2 = row.getCell(2);
Assert.assertEquals("2020-01-01 01:01:01", DateUtils.format(cell2.getDateCellValue(), "yyyy-MM-dd HH:mm:ss"));
Assert.assertEquals("yyyy-MM-dd HH:mm:ss", cell2.getCellStyle().getDataFormatString());
Assert.assertEquals("FFFFC000", cell2.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assert.assertEquals("FFC0504D", cell2.getCellStyle().getFont().getXSSFColor().getARGBHex());
Assert.assertTrue(cell2.getCellStyle().getFont().getBold());
XSSFCell cell3 = row.getCell(3);
Assert.assertEquals("张三今年5.2岁了", cell3.getStringCellValue());
Assert.assertEquals(0, cell3.getCellStyle().getDataFormat());
Assert.assertEquals("FFFF0000", cell3.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assert.assertEquals("FFEEECE1", cell3.getCellStyle().getFont().getXSSFColor().getARGBHex());
Assert.assertTrue(cell3.getCellStyle().getFont().getBold());
XSSFCell cell4 = row.getCell(4);
Assert.assertEquals("{.name}忽略,张三", cell4.getStringCellValue());
Assert.assertEquals(0, cell4.getCellStyle().getDataFormat());
Assert.assertEquals("FFC00000", cell4.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assert.assertEquals("FF000000", cell4.getCellStyle().getFont().getXSSFColor().getARGBHex());
Assert.assertFalse(cell4.getCellStyle().getFont().getBold());
XSSFCell cell5 = row.getCell(5);
Assert.assertEquals("空", cell5.getStringCellValue());
Assert.assertEquals(0, cell5.getCellStyle().getDataFormat());
Assert.assertEquals("FFF79646", cell5.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assert.assertEquals("FF8064A2", cell5.getCellStyle().getFont().getXSSFColor().getARGBHex());
Assert.assertFalse(cell5.getCellStyle().getFont().getBold());
}
@Test
public void t02Fill03() throws Exception {
fill(fileStyle03, fileStyleTemplate03);
HSSFWorkbook workbook = new HSSFWorkbook(new FileInputStream(fileStyle03));
HSSFSheet sheet = workbook.getSheetAt(0);
t02Fill03check(workbook, sheet.getRow(1));
t02Fill03check(workbook, sheet.getRow(2));
}
private void t02Fill03check(HSSFWorkbook workbook, HSSFRow row) {
HSSFCell cell0 = row.getCell(0);
Assert.assertEquals("张三", cell0.getStringCellValue());
Assert.assertEquals(49, cell0.getCellStyle().getDataFormat());
Assert.assertEquals("0:8080:0", cell0.getCellStyle().getFillForegroundColorColor().getHexString());
Assert.assertEquals("8080:0:8080", cell0.getCellStyle().getFont(workbook).getHSSFColor(workbook)
.getHexString());
Assert.assertTrue(cell0.getCellStyle().getFont(workbook).getBold());
HSSFCell cell1 = row.getCell(1);
Assert.assertEquals(5.2, cell1.getNumericCellValue(), 1);
Assert.assertEquals(0, cell1.getCellStyle().getDataFormat());
Assert.assertEquals("9999:CCCC:0", cell1.getCellStyle().getFillForegroundColorColor().getHexString());
Assert.assertEquals("0:8080:8080", cell1.getCellStyle().getFont(workbook).getHSSFColor(workbook)
.getHexString());
Assert.assertFalse(cell1.getCellStyle().getFont(workbook).getBold());
HSSFCell cell2 = row.getCell(2);
Assert.assertEquals("2020-01-01 01:01:01", DateUtils.format(cell2.getDateCellValue(), "yyyy-MM-dd HH:mm:ss"));
Assert.assertEquals("yyyy-MM-dd HH:mm:ss", cell2.getCellStyle().getDataFormatString());
Assert.assertEquals("FFFF:CCCC:0", cell2.getCellStyle().getFillForegroundColorColor().getHexString());
Assert.assertEquals("8080:0:0", cell2.getCellStyle().getFont(workbook).getHSSFColor(workbook).getHexString());
Assert.assertTrue(cell2.getCellStyle().getFont(workbook).getBold());
HSSFCell cell3 = row.getCell(3);
Assert.assertEquals("张三今年5.2岁了", cell3.getStringCellValue());
Assert.assertEquals(0, cell3.getCellStyle().getDataFormat());
Assert.assertEquals("FFFF:0:0", cell3.getCellStyle().getFillForegroundColorColor().getHexString());
Assert.assertEquals("FFFF:FFFF:9999", cell3.getCellStyle().getFont(workbook).getHSSFColor(workbook)
.getHexString());
Assert.assertTrue(cell3.getCellStyle().getFont(workbook).getBold());
HSSFCell cell4 = row.getCell(4);
Assert.assertEquals("{.name}忽略,张三", cell4.getStringCellValue());
Assert.assertEquals(0, cell4.getCellStyle().getDataFormat());
Assert.assertEquals("9999:3333:0", cell4.getCellStyle().getFillForegroundColorColor().getHexString());
Assert.assertEquals("3333:3333:3333", cell4.getCellStyle().getFont(workbook).getHSSFColor(workbook)
.getHexString());
Assert.assertFalse(cell4.getCellStyle().getFont(workbook).getBold());
HSSFCell cell5 = row.getCell(5);
Assert.assertEquals("空", cell5.getStringCellValue());
Assert.assertEquals(0, cell5.getCellStyle().getDataFormat());
Assert.assertEquals("9999:3333:0", cell5.getCellStyle().getFillForegroundColorColor().getHexString());
Assert.assertEquals("CCCC:9999:FFFF", cell5.getCellStyle().getFont(workbook).getHSSFColor(workbook)
.getHexString());
Assert.assertFalse(cell5.getCellStyle().getFont(workbook).getBold());
}
private void fill(File file, File template) throws Exception {
EasyExcel.write(file, FillStyleData.class).withTemplate(template).sheet().doFill(data());
}
@Test
public void t11FillStyleHandler07() throws Exception {
fillStyleHandler(fileStyleHandler07, fileStyleTemplate07);
XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream(fileStyleHandler07));
XSSFSheet sheet = workbook.getSheetAt(0);
t11FillStyleHandler07check(sheet.getRow(1));
t11FillStyleHandler07check(sheet.getRow(2));
}
private void t11FillStyleHandler07check(XSSFRow row) {
XSSFCell cell0 = row.getCell(0);
Assert.assertEquals("张三", cell0.getStringCellValue());
Assert.assertEquals(49, cell0.getCellStyle().getDataFormat());
Assert.assertEquals("FFFFFF00", cell0.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assert.assertEquals("FF808000", cell0.getCellStyle().getFont().getXSSFColor().getARGBHex());
Assert.assertTrue(cell0.getCellStyle().getFont().getBold());
XSSFCell cell1 = row.getCell(1);
Assert.assertEquals(5.2, cell1.getNumericCellValue(), 1);
Assert.assertEquals(0, cell1.getCellStyle().getDataFormat());
Assert.assertEquals("FFFF0000", cell1.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assert.assertEquals("FF800000", cell1.getCellStyle().getFont().getXSSFColor().getARGBHex());
Assert.assertTrue(cell1.getCellStyle().getFont().getBold());
XSSFCell cell2 = row.getCell(2);
Assert.assertEquals("2020-01-01 01:01:01", DateUtils.format(cell2.getDateCellValue(), "yyyy-MM-dd HH:mm:ss"));
Assert.assertEquals("yyyy-MM-dd HH:mm:ss", cell2.getCellStyle().getDataFormatString());
Assert.assertEquals("FF008000", cell2.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assert.assertEquals("FF003300", cell2.getCellStyle().getFont().getXSSFColor().getARGBHex());
Assert.assertTrue(cell2.getCellStyle().getFont().getBold());
XSSFCell cell3 = row.getCell(3);
Assert.assertEquals("张三今年5.2岁了", cell3.getStringCellValue());
Assert.assertEquals(0, cell3.getCellStyle().getDataFormat());
Assert.assertEquals("FFFF0000", cell3.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assert.assertEquals("FFEEECE1", cell3.getCellStyle().getFont().getXSSFColor().getARGBHex());
Assert.assertTrue(cell3.getCellStyle().getFont().getBold());
XSSFCell cell4 = row.getCell(4);
Assert.assertEquals("{.name}忽略,张三", cell4.getStringCellValue());
Assert.assertEquals(0, cell4.getCellStyle().getDataFormat());
Assert.assertEquals("FFC00000", cell4.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assert.assertEquals("FF000000", cell4.getCellStyle().getFont().getXSSFColor().getARGBHex());
Assert.assertFalse(cell4.getCellStyle().getFont().getBold());
XSSFCell cell5 = row.getCell(5);
Assert.assertEquals("空", cell5.getStringCellValue());
Assert.assertEquals(0, cell5.getCellStyle().getDataFormat());
Assert.assertEquals("FFF79646", cell5.getCellStyle().getFillForegroundColorColor().getARGBHex());
Assert.assertEquals("FF8064A2", cell5.getCellStyle().getFont().getXSSFColor().getARGBHex());
Assert.assertFalse(cell5.getCellStyle().getFont().getBold());
}
@Test
public void t12FillStyleHandler03() throws Exception {
fillStyleHandler(fileStyleHandler03, fileStyleTemplate03);
HSSFWorkbook workbook = new HSSFWorkbook(new FileInputStream(fileStyleHandler03));
HSSFSheet sheet = workbook.getSheetAt(0);
t12FillStyleHandler03check(workbook, sheet.getRow(1));
t12FillStyleHandler03check(workbook, sheet.getRow(2));
}
private void t12FillStyleHandler03check(HSSFWorkbook workbook, HSSFRow row) {
HSSFCell cell0 = row.getCell(0);
Assert.assertEquals("张三", cell0.getStringCellValue());
Assert.assertEquals(49, cell0.getCellStyle().getDataFormat());
Assert.assertEquals("FFFF:FFFF:0", cell0.getCellStyle().getFillForegroundColorColor().getHexString());
Assert.assertEquals("8080:8080:0", cell0.getCellStyle().getFont(workbook).getHSSFColor(workbook)
.getHexString());
Assert.assertTrue(cell0.getCellStyle().getFont(workbook).getBold());
HSSFCell cell1 = row.getCell(1);
Assert.assertEquals(5.2, cell1.getNumericCellValue(), 1);
Assert.assertEquals(0, cell1.getCellStyle().getDataFormat());
Assert.assertEquals("FFFF:0:0", cell1.getCellStyle().getFillForegroundColorColor().getHexString());
Assert.assertEquals("8080:0:0", cell1.getCellStyle().getFont(workbook).getHSSFColor(workbook)
.getHexString());
Assert.assertTrue(cell1.getCellStyle().getFont(workbook).getBold());
HSSFCell cell2 = row.getCell(2);
Assert.assertEquals("2020-01-01 01:01:01", DateUtils.format(cell2.getDateCellValue(), "yyyy-MM-dd HH:mm:ss"));
Assert.assertEquals("yyyy-MM-dd HH:mm:ss", cell2.getCellStyle().getDataFormatString());
Assert.assertEquals("0:8080:0", cell2.getCellStyle().getFillForegroundColorColor().getHexString());
Assert.assertEquals("0:3333:0", cell2.getCellStyle().getFont(workbook).getHSSFColor(workbook).getHexString());
Assert.assertTrue(cell2.getCellStyle().getFont(workbook).getBold());
HSSFCell cell3 = row.getCell(3);
Assert.assertEquals("张三今年5.2岁了", cell3.getStringCellValue());
Assert.assertEquals(0, cell3.getCellStyle().getDataFormat());
Assert.assertEquals("FFFF:0:0", cell3.getCellStyle().getFillForegroundColorColor().getHexString());
Assert.assertEquals("FFFF:FFFF:9999", cell3.getCellStyle().getFont(workbook).getHSSFColor(workbook)
.getHexString());
Assert.assertTrue(cell3.getCellStyle().getFont(workbook).getBold());
HSSFCell cell4 = row.getCell(4);
Assert.assertEquals("{.name}忽略,张三", cell4.getStringCellValue());
Assert.assertEquals(0, cell4.getCellStyle().getDataFormat());
Assert.assertEquals("9999:3333:0", cell4.getCellStyle().getFillForegroundColorColor().getHexString());
Assert.assertEquals("3333:3333:3333", cell4.getCellStyle().getFont(workbook).getHSSFColor(workbook)
.getHexString());
Assert.assertFalse(cell4.getCellStyle().getFont(workbook).getBold());
HSSFCell cell5 = row.getCell(5);
Assert.assertEquals("空", cell5.getStringCellValue());
Assert.assertEquals(0, cell5.getCellStyle().getDataFormat());
Assert.assertEquals("9999:3333:0", cell5.getCellStyle().getFillForegroundColorColor().getHexString());
Assert.assertEquals("CCCC:9999:FFFF", cell5.getCellStyle().getFont(workbook).getHSSFColor(workbook)
.getHexString());
Assert.assertFalse(cell5.getCellStyle().getFont(workbook).getBold());
}
private void fillStyleHandler(File file, File template) throws Exception {
EasyExcel.write(file, FillStyleData.class).withTemplate(template).sheet()
.registerWriteHandler(new AbstractVerticalCellStyleStrategy() {
@Override
protected WriteCellStyle contentCellStyle(CellWriteHandlerContext context) {
WriteCellStyle writeCellStyle = new WriteCellStyle();
WriteFont writeFont = new WriteFont();
writeCellStyle.setWriteFont(writeFont);
writeCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
writeFont.setBold(true);
if (context.getColumnIndex() == 0) {
writeCellStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
writeFont.setColor(IndexedColors.DARK_YELLOW.getIndex());
}
if (context.getColumnIndex() == 1) {
writeCellStyle.setFillForegroundColor(IndexedColors.RED.getIndex());
writeFont.setColor(IndexedColors.DARK_RED.getIndex());
}
if (context.getColumnIndex() == 2) {
writeCellStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex());
writeFont.setColor(IndexedColors.DARK_GREEN.getIndex());
}
if (context.getColumnIndex() == 3) {
writeCellStyle.setFillForegroundColor(IndexedColors.BLUE.getIndex());
writeFont.setColor(IndexedColors.DARK_BLUE.getIndex());
}
if (context.getColumnIndex() == 4) {
writeCellStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
writeFont.setColor(IndexedColors.DARK_YELLOW.getIndex());
}
if (context.getColumnIndex() == 5) {
writeCellStyle.setFillForegroundColor(IndexedColors.TEAL.getIndex());
writeFont.setColor(IndexedColors.DARK_TEAL.getIndex());
}
return writeCellStyle;
}
@Override
protected WriteCellStyle headCellStyle(Head head) {
return null;
}
})
.doFill(data());
}
private List<FillStyleData> data() throws Exception {
List<FillStyleData> list = ListUtils.newArrayList();
for (int i = 0; i < 10; i++) {
FillStyleData fillData = new FillStyleData();
list.add(fillData);
fillData.setName("张三");
fillData.setNumber(5.2);
fillData.setDate(DateUtils.parseDate("2020-01-01 01:01:01"));
if (i == 5) {
fillData.setName(null);
}
}
return list;
}
}

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

@ -1,6 +1,7 @@
package com.alibaba.easyexcel.test.core.large; package com.alibaba.easyexcel.test.core.large;
import java.io.File; import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -9,6 +10,11 @@ import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.excel.write.metadata.WriteSheet;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.junit.Assert;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.FixMethodOrder; import org.junit.FixMethodOrder;
import org.junit.Test; import org.junit.Test;
@ -25,11 +31,16 @@ public class LargeDataTest {
private static File fileFill07; private static File fileFill07;
private static File template07; private static File template07;
private static File fileCsv; private static File fileCsv;
private static File fileWrite07;
private static File fileWritePoi07;
private int i = 0; private int i = 0;
@BeforeClass @BeforeClass
public static void init() { public static void init() {
fileFill07 = TestFileUtil.createNewFile("largefill07.xlsx"); fileFill07 = TestFileUtil.createNewFile("largefill07.xlsx");
fileWrite07 = TestFileUtil.createNewFile("large" + File.separator + "fileWrite07.xlsx");
fileWritePoi07 = TestFileUtil.createNewFile("large" + File.separator + "fileWritePoi07.xlsx");
template07 = TestFileUtil.readFile("large" + File.separator + "fill.xlsx"); template07 = TestFileUtil.readFile("large" + File.separator + "fill.xlsx");
fileCsv = TestFileUtil.createNewFile("largefileCsv.csv"); fileCsv = TestFileUtil.createNewFile("largefileCsv.csv");
} }
@ -72,6 +83,41 @@ public class LargeDataTest {
LOGGER.info("CSV large data total time spent:{}", System.currentTimeMillis() - start); LOGGER.info("CSV large data total time spent:{}", System.currentTimeMillis() - start);
} }
@Test
public void t04Write() throws Exception {
long start = System.currentTimeMillis();
ExcelWriter excelWriter = EasyExcel.write(fileWrite07, LargeData.class).build();
WriteSheet writeSheet = EasyExcel.writerSheet().build();
for (int j = 0; j < 100; j++) {
excelWriter.write(data(), writeSheet);
LOGGER.info("{} write success.", j);
}
excelWriter.finish();
long cost = System.currentTimeMillis() - start;
LOGGER.info("write cost:{}", cost);
start = System.currentTimeMillis();
try (FileOutputStream fileOutputStream = new FileOutputStream(fileWritePoi07)) {
SXSSFWorkbook workbook = new SXSSFWorkbook();
SXSSFSheet sheet = workbook.createSheet("sheet1");
for (int i = 0; i < 100 * 5000; i++) {
SXSSFRow row = sheet.createRow(i);
for (int j = 0; j < 25; j++) {
SXSSFCell cell = row.createCell(j);
cell.setCellValue("str-" + j + "-" + i);
}
if (i % 5000 == 0) {
LOGGER.info("{} write success.", i);
}
}
workbook.write(fileOutputStream);
workbook.dispose();
workbook.close();
}
long costPoi = System.currentTimeMillis() - start;
LOGGER.info("poi write cost:{}", System.currentTimeMillis() - start);
Assert.assertTrue(costPoi * 3 > cost);
}
private List<LargeData> data() { private List<LargeData> data() {
List<LargeData> list = new ArrayList<>(); List<LargeData> list = new ArrayList<>();
int size = i + 5000; int size = i + 5000;

5
src/test/java/com/alibaba/easyexcel/test/core/noncamel/UnCamelDataListener.java

@ -22,11 +22,12 @@ public class UnCamelDataListener extends AnalysisEventListener<UnCamelData> {
public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) { public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
log.debug("Head is:{}", JSON.toJSONString(headMap)); log.debug("Head is:{}", JSON.toJSONString(headMap));
Assert.assertEquals(headMap.get(0), "string1"); Assert.assertEquals(headMap.get(0), "string1");
Assert.assertEquals(headMap.get(1), "String2"); Assert.assertEquals(headMap.get(1), "string2");
Assert.assertEquals(headMap.get(2), "sTring3"); Assert.assertEquals(headMap.get(2), "STring3");
Assert.assertEquals(headMap.get(3), "STring4"); Assert.assertEquals(headMap.get(3), "STring4");
Assert.assertEquals(headMap.get(4), "STRING5"); Assert.assertEquals(headMap.get(4), "STRING5");
Assert.assertEquals(headMap.get(5), "STRing6"); Assert.assertEquals(headMap.get(5), "STRing6");
} }
@Override @Override

65
src/test/java/com/alibaba/easyexcel/test/core/style/StyleDataTest.java

@ -4,14 +4,15 @@ import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.alibaba.easyexcel.test.core.StyleTestUtils;
import com.alibaba.easyexcel.test.util.TestFileUtil; import com.alibaba.easyexcel.test.util.TestFileUtil;
import com.alibaba.excel.EasyExcel; import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.annotation.write.style.HeadFontStyle; import com.alibaba.excel.annotation.write.style.HeadFontStyle;
import com.alibaba.excel.annotation.write.style.HeadStyle; import com.alibaba.excel.annotation.write.style.HeadStyle;
import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.DataFormatData;
import com.alibaba.excel.metadata.property.FontProperty; import com.alibaba.excel.metadata.property.FontProperty;
import com.alibaba.excel.metadata.property.StyleProperty; import com.alibaba.excel.metadata.property.StyleProperty;
import com.alibaba.excel.metadata.data.DataFormatData;
import com.alibaba.excel.write.merge.LoopMergeStrategy; import com.alibaba.excel.write.merge.LoopMergeStrategy;
import com.alibaba.excel.write.merge.OnceAbsoluteMergeStrategy; import com.alibaba.excel.write.merge.OnceAbsoluteMergeStrategy;
import com.alibaba.excel.write.metadata.style.WriteCellStyle; import com.alibaba.excel.write.metadata.style.WriteCellStyle;
@ -22,11 +23,17 @@ import com.alibaba.excel.write.style.column.SimpleColumnWidthStyleStrategy;
import com.alibaba.excel.write.style.row.SimpleRowHeightStyleStrategy; import com.alibaba.excel.write.style.row.SimpleRowHeightStyleStrategy;
import org.apache.poi.ss.usermodel.BorderStyle; import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.FillPatternType; import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment; import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors; import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.VerticalAlignment; import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.junit.Assert;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.FixMethodOrder; import org.junit.FixMethodOrder;
import org.junit.Test; import org.junit.Test;
@ -40,20 +47,26 @@ public class StyleDataTest {
private static File file07; private static File file07;
private static File file03; private static File file03;
private static File fileVerticalCellStyleStrategy07;
private static File fileVerticalCellStyleStrategy207;
private static File fileLoopMergeStrategy;
@BeforeClass @BeforeClass
public static void init() { public static void init() {
file07 = TestFileUtil.createNewFile("style07.xlsx"); file07 = TestFileUtil.createNewFile("style07.xlsx");
file03 = TestFileUtil.createNewFile("style03.xls"); file03 = TestFileUtil.createNewFile("style03.xls");
fileVerticalCellStyleStrategy07 = TestFileUtil.createNewFile("verticalCellStyle.xlsx");
fileVerticalCellStyleStrategy207 = TestFileUtil.createNewFile("verticalCellStyle2.xlsx");
fileLoopMergeStrategy = TestFileUtil.createNewFile("loopMergeStrategy.xlsx");
} }
@Test @Test
public void t01ReadAndWrite07() { public void t01ReadAndWrite07() throws Exception {
readAndWrite(file07); readAndWrite(file07);
} }
@Test @Test
public void t02ReadAndWrite03() { public void t02ReadAndWrite03() throws Exception {
readAndWrite(file03); readAndWrite(file03);
} }
@ -113,9 +126,12 @@ public class StyleDataTest {
return writeCellStyle; return writeCellStyle;
} }
}; };
EasyExcel.write(file07, StyleData.class).registerWriteHandler(verticalCellStyleStrategy).sheet() EasyExcel.write(fileVerticalCellStyleStrategy07, StyleData.class).registerWriteHandler(
verticalCellStyleStrategy).sheet()
.doWrite(data()); .doWrite(data());
} }
@Test @Test
public void t04AbstractVerticalCellStyleStrategy02() { public void t04AbstractVerticalCellStyleStrategy02() {
final StyleProperty styleProperty = StyleProperty.build(StyleData.class.getAnnotation(HeadStyle.class)); final StyleProperty styleProperty = StyleProperty.build(StyleData.class.getAnnotation(HeadStyle.class));
@ -152,32 +168,36 @@ public class StyleDataTest {
return writeCellStyle; return writeCellStyle;
} }
}; };
EasyExcel.write(file07, StyleData.class).registerWriteHandler(verticalCellStyleStrategy).sheet() EasyExcel.write(fileVerticalCellStyleStrategy207, StyleData.class).registerWriteHandler(
verticalCellStyleStrategy).sheet()
.doWrite(data()); .doWrite(data());
} }
@Test @Test
public void t05LoopMergeStrategy() { public void t05LoopMergeStrategy() {
EasyExcel.write(file07, StyleData.class).sheet().registerWriteHandler(new LoopMergeStrategy(2, 1)) EasyExcel.write(fileLoopMergeStrategy, StyleData.class).sheet().registerWriteHandler(
new LoopMergeStrategy(2, 1))
.doWrite(data10()); .doWrite(data10());
} }
private void readAndWrite(File file) { private void readAndWrite(File file) throws Exception {
SimpleColumnWidthStyleStrategy simpleColumnWidthStyleStrategy = new SimpleColumnWidthStyleStrategy(50); SimpleColumnWidthStyleStrategy simpleColumnWidthStyleStrategy = new SimpleColumnWidthStyleStrategy(50);
SimpleRowHeightStyleStrategy simpleRowHeightStyleStrategy = SimpleRowHeightStyleStrategy simpleRowHeightStyleStrategy =
new SimpleRowHeightStyleStrategy((short)40, (short)50); new SimpleRowHeightStyleStrategy((short)40, (short)50);
WriteCellStyle headWriteCellStyle = new WriteCellStyle(); WriteCellStyle headWriteCellStyle = new WriteCellStyle();
headWriteCellStyle.setFillForegroundColor(IndexedColors.RED.getIndex()); headWriteCellStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
WriteFont headWriteFont = new WriteFont(); WriteFont headWriteFont = new WriteFont();
headWriteFont.setFontHeightInPoints((short)20); headWriteFont.setFontHeightInPoints((short)20);
headWriteFont.setColor(IndexedColors.DARK_YELLOW.getIndex());
headWriteCellStyle.setWriteFont(headWriteFont); headWriteCellStyle.setWriteFont(headWriteFont);
WriteCellStyle contentWriteCellStyle = new WriteCellStyle(); WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND); contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
contentWriteCellStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex()); contentWriteCellStyle.setFillForegroundColor(IndexedColors.TEAL.getIndex());
WriteFont contentWriteFont = new WriteFont(); WriteFont contentWriteFont = new WriteFont();
contentWriteFont.setFontHeightInPoints((short)20); contentWriteFont.setFontHeightInPoints((short)30);
headWriteCellStyle.setWriteFont(contentWriteFont); contentWriteFont.setColor(IndexedColors.DARK_TEAL.getIndex());
contentWriteCellStyle.setWriteFont(contentWriteFont);
HorizontalCellStyleStrategy horizontalCellStyleStrategy = HorizontalCellStyleStrategy horizontalCellStyleStrategy =
new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle); new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
@ -186,6 +206,29 @@ public class StyleDataTest {
.registerWriteHandler(simpleRowHeightStyleStrategy).registerWriteHandler(horizontalCellStyleStrategy) .registerWriteHandler(simpleRowHeightStyleStrategy).registerWriteHandler(horizontalCellStyleStrategy)
.registerWriteHandler(onceAbsoluteMergeStrategy).sheet().doWrite(data()); .registerWriteHandler(onceAbsoluteMergeStrategy).sheet().doWrite(data());
EasyExcel.read(file, StyleData.class, new StyleDataListener()).sheet().doRead(); EasyExcel.read(file, StyleData.class, new StyleDataListener()).sheet().doRead();
Workbook workbook = WorkbookFactory.create(file);
Sheet sheet = workbook.getSheetAt(0);
Row row0 = sheet.getRow(0);
Cell cell00 = row0.getCell(0);
Assert.assertArrayEquals(new byte[] {-1, -1, 0}, StyleTestUtils.getFillForegroundColor(cell00));
Assert.assertArrayEquals(new byte[] {-128, -128, 0}, StyleTestUtils.getFontColor(cell00, workbook));
Assert.assertEquals(20, StyleTestUtils.getFontHeightInPoints(cell00, workbook));
Cell cell01 = row0.getCell(1);
Assert.assertArrayEquals(new byte[] {-1, -1, 0}, StyleTestUtils.getFillForegroundColor(cell01));
Assert.assertArrayEquals(new byte[] {-128, -128, 0}, StyleTestUtils.getFontColor(cell01, workbook));
Assert.assertEquals(20, StyleTestUtils.getFontHeightInPoints(cell01, workbook));
Row row1 = sheet.getRow(1);
Cell cell10 = row1.getCell(0);
Assert.assertArrayEquals(new byte[] {0, -128, -128}, StyleTestUtils.getFillForegroundColor(cell10));
Assert.assertArrayEquals(new byte[] {0, 51, 102}, StyleTestUtils.getFontColor(cell10, workbook));
Assert.assertEquals(30, StyleTestUtils.getFontHeightInPoints(cell10, workbook));
Cell cell11 = row1.getCell(1);
Assert.assertArrayEquals(new byte[] {0, -128, -128}, StyleTestUtils.getFillForegroundColor(cell11));
Assert.assertArrayEquals(new byte[] {0, 51, 102}, StyleTestUtils.getFontColor(cell11, workbook));
Assert.assertEquals(30, StyleTestUtils.getFontHeightInPoints(cell11, workbook));
} }
private List<StyleData> data() { private List<StyleData> data() {

4
src/test/java/com/alibaba/easyexcel/test/demo/fill/FillData.java

@ -1,5 +1,7 @@
package com.alibaba.easyexcel.test.demo.fill; package com.alibaba.easyexcel.test.demo.fill;
import java.util.Date;
import lombok.Data; import lombok.Data;
/** /**
@ -9,4 +11,6 @@ import lombok.Data;
public class FillData { public class FillData {
private String name; private String name;
private double number; private double number;
private Date date;
} }

1
src/test/java/com/alibaba/easyexcel/test/demo/fill/FillTest.java

@ -233,6 +233,7 @@ public class FillTest {
list.add(fillData); list.add(fillData);
fillData.setName("张三"); fillData.setName("张三");
fillData.setNumber(5.2); fillData.setNumber(5.2);
fillData.setDate(new Date());
} }
return list; return list;
} }

132
src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiTest.java

@ -1,6 +1,7 @@
package com.alibaba.easyexcel.test.temp.poi; package com.alibaba.easyexcel.test.temp.poi;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.Date; import java.util.Date;
@ -8,13 +9,22 @@ import java.util.Date;
import com.alibaba.easyexcel.test.util.TestFileUtil; import com.alibaba.easyexcel.test.util.TestFileUtil;
import com.alibaba.excel.util.FileUtils; import com.alibaba.excel.util.FileUtils;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFRow; import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet; import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFColor;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook;
@ -39,25 +49,129 @@ public class PoiTest {
SXSSFSheet xssfSheet = xssfWorkbook.getSheetAt(0); SXSSFSheet xssfSheet = xssfWorkbook.getSheetAt(0);
LOGGER.info("一共行数:{}", xssfSheet.getLastRowNum()); LOGGER.info("一共行数:{}", xssfSheet.getLastRowNum());
SXSSFRow row = xssfSheet.getRow(0); SXSSFRow row = xssfSheet.getRow(0);
LOGGER.info("dd{}",row.getCell(0).getColumnIndex()); LOGGER.info("dd{}", row.getCell(0).getColumnIndex());
Date date = row.getCell(1).getDateCellValue(); Date date = row.getCell(1).getDateCellValue();
} }
@Test @Test
public void lastRowNumXSSF() throws IOException { public void lastRowNumXSSF() throws IOException {
String file = "/Users/zhuangjiaju/test/test3.xlsx";
XSSFWorkbook xssfWorkbook = new XSSFWorkbook(file); String file = "/Users/zhuangjiaju/test/test3 copy 10.xlsx";
XSSFWorkbook xssfWorkbook = new XSSFWorkbook(new FileInputStream(file));
LOGGER.info("一共:{}个sheet", xssfWorkbook.getNumberOfSheets()); LOGGER.info("一共:{}个sheet", xssfWorkbook.getNumberOfSheets());
XSSFSheet xssfSheet = xssfWorkbook.getSheetAt(0); XSSFSheet xssfSheet = xssfWorkbook.getSheetAt(0);
LOGGER.info("一共行数:{}", xssfSheet.getLastRowNum()); LOGGER.info("一共行数:{}", xssfSheet.getLastRowNum());
XSSFRow row = xssfSheet.getRow(0); XSSFRow row = xssfSheet.getRow(1);
LOGGER.info("dd{}",row.getCell(0).getRow().getRowNum()); LOGGER.info("dd{}", row.getCell(0).getRow().getRowNum());
LOGGER.info("dd{}",xssfSheet.getLastRowNum()); LOGGER.info("dd{}", xssfSheet.getLastRowNum());
Date date = row.getCell(1).getDateCellValue(); XSSFCellStyle cellStyle = row.getCell(0).getCellStyle();
LOGGER.info("date{}",date); LOGGER.info("size1:{}", cellStyle.getFontIndexAsInt());
XSSFCellStyle cellStyle1 = xssfWorkbook.createCellStyle();
LOGGER.info("size2:{}", cellStyle1.getFontIndexAsInt());
cellStyle1.cloneStyleFrom(cellStyle);
LOGGER.info("size3:{}", cellStyle1.getFontIndexAsInt());
LOGGER.info("bbb:{}", cellStyle1.getFont().getXSSFColor().getIndex());
LOGGER.info("bbb:{}", cellStyle1.getFont().getXSSFColor().getIndexed());
XSSFColor myColor = new XSSFColor(cellStyle1.getFont().getXSSFColor().getRGB(), null);
LOGGER.info("bbb:{}", cellStyle1.getFont().getXSSFColor().getRGB());
LOGGER.info("bbb:{}", cellStyle1.getFont().getXSSFColor().getARGBHex());
LOGGER.info("bbb:{}", cellStyle1.getFont().getBold());
LOGGER.info("bbb:{}", cellStyle1.getFont().getFontName());
XSSFFont xssfFont = xssfWorkbook.createFont();
xssfFont.setColor(myColor);
xssfFont.setFontHeightInPoints((short)50);
xssfFont.setBold(Boolean.TRUE);
cellStyle1.setFont(xssfFont);
cellStyle1.setFillForegroundColor(IndexedColors.PINK.getIndex());
LOGGER.info("aaa:{}", cellStyle1.getFont().getColor());
row.getCell(1).setCellStyle(cellStyle1);
row.getCell(1).setCellValue(3334l);
XSSFCellStyle cellStyle2 = xssfWorkbook.createCellStyle();
cellStyle2.cloneStyleFrom(cellStyle);
cellStyle2.setFillForegroundColor(IndexedColors.BLUE.getIndex());
//cellStyle2.setFont(cellStyle1.getFont());
row.getCell(2).setCellStyle(cellStyle2);
row.getCell(2).setCellValue(3334l);
//LOGGER.info("date1:{}", row.getCell(0).getStringCellValue());
//LOGGER.info("date2:{}", ((XSSFColor) cellStyle.getFillForegroundColorColor()).getIndex());
//LOGGER.info("date2:{}", ((XSSFColor) cellStyle.getFillForegroundColorColor()).isRGB());
//LOGGER.info("date4:{}", ((XSSFColor) cellStyle.getFillForegroundColorColor()).isIndexed());
//LOGGER.info("date3:{}", cellStyle.getFont().getXSSFColor().getRGB());
//LOGGER.info("date4:{}", cellStyle.getFont().getCTFont().getColorArray(0).getRgb());
FileOutputStream fileOutputStream = new FileOutputStream(file);
xssfWorkbook.write(fileOutputStream);
fileOutputStream.flush();
xssfWorkbook.close();
}
@Test
public void lastRowNumXSSFv22() throws IOException {
String file = "/Users/zhuangjiaju/test/test3 copy 2.xls";
HSSFWorkbook xssfWorkbook = new HSSFWorkbook(new FileInputStream(file));
LOGGER.info("一共:{}个sheet", xssfWorkbook.getNumberOfSheets());
HSSFSheet xssfSheet = xssfWorkbook.getSheetAt(0);
LOGGER.info("一共行数:{}", xssfSheet.getLastRowNum());
HSSFRow row = xssfSheet.getRow(1);
LOGGER.info("dd{}", row.getCell(0).getRow().getRowNum());
LOGGER.info("dd{}", xssfSheet.getLastRowNum());
HSSFCellStyle cellStyle = row.getCell(0).getCellStyle();
LOGGER.info("单元格1的字体:{}", cellStyle.getFontIndexAsInt());
HSSFCellStyle cellStyle1 = xssfWorkbook.createCellStyle();
LOGGER.info("size2:{}", cellStyle1.getFontIndexAsInt());
cellStyle1.cloneStyleFrom(cellStyle);
LOGGER.info("单元格2的字体:{}", cellStyle1.getFontIndexAsInt());
LOGGER.info("bbb:{}", cellStyle1.getFont(xssfWorkbook).getColor());
HSSFFont xssfFont = xssfWorkbook.createFont();
xssfFont.setColor(cellStyle1.getFont(xssfWorkbook).getColor());
xssfFont.setFontHeightInPoints((short)50);
xssfFont.setBold(Boolean.TRUE);
cellStyle1.setFont(xssfFont);
cellStyle1.setFillForegroundColor(IndexedColors.PINK.getIndex());
LOGGER.info("aaa:{}", cellStyle1.getFont(xssfWorkbook).getColor());
row.getCell(1).setCellStyle(cellStyle1);
row.getCell(1).setCellValue(3334l);
HSSFCellStyle cellStyle2 = xssfWorkbook.createCellStyle();
cellStyle2.cloneStyleFrom(cellStyle);
cellStyle2.setFillForegroundColor(IndexedColors.BLUE.getIndex());
//cellStyle2.setFont(cellStyle1.getFont());
row.getCell(2).setCellStyle(cellStyle2);
row.getCell(2).setCellValue(3334l);
//LOGGER.info("date1:{}", row.getCell(0).getStringCellValue());
//LOGGER.info("date2:{}", ((XSSFColor) cellStyle.getFillForegroundColorColor()).getIndex());
//LOGGER.info("date2:{}", ((XSSFColor) cellStyle.getFillForegroundColorColor()).isRGB());
//LOGGER.info("date4:{}", ((XSSFColor) cellStyle.getFillForegroundColorColor()).isIndexed());
//LOGGER.info("date3:{}", cellStyle.getFont().getXSSFColor().getRGB());
//LOGGER.info("date4:{}", cellStyle.getFont().getCTFont().getColorArray(0).getRgb());
FileOutputStream fileOutputStream = new FileOutputStream(file);
xssfWorkbook.write(fileOutputStream);
fileOutputStream.flush();
xssfWorkbook.close();
} }
@Test @Test

17
src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiWriteTest.java

@ -1,10 +1,15 @@
package com.alibaba.easyexcel.test.temp.poi; package com.alibaba.easyexcel.test.temp.poi;
import java.io.BufferedInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.net.URL;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import com.alibaba.fastjson.JSON;
import org.apache.poi.xssf.streaming.SXSSFCell; import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow; import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet; import org.apache.poi.xssf.streaming.SXSSFSheet;
@ -14,8 +19,6 @@ import org.junit.Test;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSON;
/** /**
* 测试poi * 测试poi
* *
@ -104,4 +107,14 @@ public class PoiWriteTest {
} }
@Test
public void part4() throws IOException {
//URL url=new URL("http://120.55.161.4/group1/M00/00/00/i8QJ8WFfwMiAXKYrAAACqC1MFiY641.png");
URL url=new URL("https://img-blog.csdn.net/20160729002743309?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center");
InputStream in = new BufferedInputStream(url.openStream());
}
} }

BIN
src/test/resources/demo/fill/list.xlsx

Binary file not shown.

2
src/test/resources/fill/simple.csv

@ -0,0 +1,2 @@
姓名,数字,复杂,忽略,空
{name},{number},{name}今年{number}岁了,\{name\}忽略,{name},空{.empty}
1 姓名 数字 复杂 忽略
2 {name} {number} {name}今年{number}岁了 \{name\}忽略,{name} 空{.empty}

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

Binary file not shown.

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

Binary file not shown.

9
update.md

@ -1,3 +1,12 @@
# 3.0.1
* 升级到正式版
* 修复填充样式可能丢失的问题 [Issue #2124](https://github.com/alibaba/easyexcel/issues/2124)
* 修复填充数据为空 可能NPE的bug
* 修复填充样式可能不生效bug
* 修复样式可能超过最大限制的bug
* 修复写入过慢的bug
# 3.0.0-beta3 # 3.0.0-beta3
* 修复导出浮点型数据可能精度异常的bug * 修复导出浮点型数据可能精度异常的bug

Loading…
Cancel
Save