diff --git a/README.md b/README.md index 325984c1..bc234820 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,15 @@ Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都 * 大版本升级后建议相关内容重新测试下 * 要升级涉及到 +### 最新版本 +```xml + + com.alibaba + easyexcel + 3.0.1 + +``` + ## 广告位 ### 支付宝扫一扫红包 本项目都是个人业余时间写的,所以比较贫穷。推广下支付宝,赚个建群的费用。有空的同学帮忙扫一扫 diff --git a/pom.xml b/pom.xml index 01134342..66331d1b 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.alibaba easyexcel - 3.0.0-beta3 + 3.0.1 jar easyexcel diff --git a/src/main/java/com/alibaba/excel/annotation/ExcelProperty.java b/src/main/java/com/alibaba/excel/annotation/ExcelProperty.java index e763ab37..db539266 100644 --- a/src/main/java/com/alibaba/excel/annotation/ExcelProperty.java +++ b/src/main/java/com/alibaba/excel/annotation/ExcelProperty.java @@ -54,7 +54,7 @@ public @interface ExcelProperty { * * @return Converter */ - Class converter() default AutoConverter.class; + Class> converter() default AutoConverter.class; /** * diff --git a/src/main/java/com/alibaba/excel/context/WriteContextImpl.java b/src/main/java/com/alibaba/excel/context/WriteContextImpl.java index 2c66b535..f31705f7 100644 --- a/src/main/java/com/alibaba/excel/context/WriteContextImpl.java +++ b/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.metadata.Head; import com.alibaba.excel.metadata.data.WriteCellData; +import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.support.ExcelTypeEnum; +import com.alibaba.excel.util.ClassUtils; import com.alibaba.excel.util.DateUtils; import com.alibaba.excel.util.FileUtils; import com.alibaba.excel.util.NumberDataFormatterUtils; @@ -244,17 +246,21 @@ public class WriteContextImpl implements WriteContext { for (Map.Entry entry : headMap.entrySet()) { Head head = entry.getValue(); 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); - WriteHandlerUtils.afterCellCreate(this, cell, head, relativeRowIndex, Boolean.TRUE); + WriteHandlerUtils.afterCellCreate(this, cell, head, relativeRowIndex, Boolean.TRUE, excelContentProperty); WriteCellData writeCellData = new WriteCellData<>(head.getHeadNameList().get(relativeRowIndex)); cell.setCellValue(writeCellData.getStringValue()); - WriteHandlerUtils.afterCellDispose(this, writeCellData, cell, head, relativeRowIndex, - Boolean.TRUE); + WriteHandlerUtils.afterCellDispose(this, writeCellData, cell, head, relativeRowIndex, Boolean.TRUE, + excelContentProperty); } } diff --git a/src/main/java/com/alibaba/excel/metadata/Head.java b/src/main/java/com/alibaba/excel/metadata/Head.java index c150fe02..7e1fd47b 100644 --- a/src/main/java/com/alibaba/excel/metadata/Head.java +++ b/src/main/java/com/alibaba/excel/metadata/Head.java @@ -1,5 +1,6 @@ package com.alibaba.excel.metadata; +import java.lang.reflect.Field; import java.util.ArrayList; 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.StyleProperty; +import lombok.Data; + /** * excel head * * @author Jiaju Zhuang **/ +@Data public class Head { /** * Column index of head */ 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)} */ @@ -35,10 +43,12 @@ public class Head { * Whether to specify a name */ private Boolean forceName; + /** * column with */ private ColumnWidthProperty columnWidthProperty; + /** * Loop merge */ @@ -47,22 +57,15 @@ public class Head { * Head style */ private StyleProperty headStyleProperty; - /** - * Content style - */ - private StyleProperty contentStyleProperty; /** * Head font */ private FontProperty headFontProperty; - /** - * Content font - */ - private FontProperty contentFontProperty; - public Head(Integer columnIndex, String fieldName, List headNameList, Boolean forceIndex, + public Head(Integer columnIndex, Field field, String fieldName, List headNameList, Boolean forceIndex, Boolean forceName) { this.columnIndex = columnIndex; + this.field = field; this.fieldName = fieldName; if (headNameList == null) { this.headNameList = new ArrayList<>(); @@ -77,92 +80,4 @@ public class Head { this.forceIndex = forceIndex; 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 getHeadNameList() { - return headNameList; - } - - public void setHeadNameList(List 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; - } } diff --git a/src/main/java/com/alibaba/excel/metadata/data/WriteCellData.java b/src/main/java/com/alibaba/excel/metadata/data/WriteCellData.java index 60413385..5a3487bf 100644 --- a/src/main/java/com/alibaba/excel/metadata/data/WriteCellData.java +++ b/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.util.ListUtils; +import com.alibaba.excel.write.metadata.fill.AnalysisCell; import com.alibaba.excel.write.metadata.style.WriteCellStyle; import lombok.Data; import lombok.NoArgsConstructor; +import org.apache.poi.ss.usermodel.CellStyle; /** * wirte cell data @@ -42,11 +44,23 @@ public class WriteCellData extends CellData { * hyper link */ private HyperlinkData hyperlinkData; + /** * style */ 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) { this(CellDataTypeEnum.STRING, stringValue); } diff --git a/src/main/java/com/alibaba/excel/metadata/property/ExcelContentProperty.java b/src/main/java/com/alibaba/excel/metadata/property/ExcelContentProperty.java index f6f92532..1c0bb232 100644 --- a/src/main/java/com/alibaba/excel/metadata/property/ExcelContentProperty.java +++ b/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 com.alibaba.excel.converters.Converter; -import com.alibaba.excel.metadata.Head; import lombok.Data; @@ -12,18 +11,30 @@ import lombok.Data; */ @Data public class ExcelContentProperty { + public static final ExcelContentProperty EMPTY = new ExcelContentProperty(); + /** * Java filed */ private Field field; - /** - * Excel head - */ - private Head head; /** * Custom defined converters */ private Converter converter; + /** + * date time format + */ private DateTimeFormatProperty dateTimeFormatProperty; + /** + * number format + */ private NumberFormatProperty numberFormatProperty; + /** + * Content style + */ + private StyleProperty contentStyleProperty; + /** + * Content font + */ + private FontProperty contentFontProperty; } diff --git a/src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java b/src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java index 3562501d..a0359fb3 100644 --- a/src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java +++ b/src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java @@ -8,15 +8,11 @@ import java.util.Map; import java.util.TreeMap; 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.exception.ExcelCommonException; import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.Holder; import com.alibaba.excel.util.ClassUtils; +import com.alibaba.excel.util.FieldUtils; import com.alibaba.excel.util.MapUtils; import com.alibaba.excel.util.StringUtils; import com.alibaba.excel.write.metadata.holder.AbstractWriteHolder; @@ -38,7 +34,7 @@ public class ExcelHeadProperty { /** * Custom class */ - private Class headClazz; + private Class headClazz; /** * The types of head */ @@ -51,24 +47,14 @@ public class ExcelHeadProperty { * Configuration header information */ private Map headMap; - /** - * Configuration column information - */ - private Map contentPropertyMap; - /** - * Configuration column information - */ - private Map fieldNameContentPropertyMap; /** * Fields ignored */ private Map ignoreMap; - public ExcelHeadProperty(Holder holder, Class headClazz, List> head) { + public ExcelHeadProperty(Holder holder, Class headClazz, List> head) { this.headClazz = headClazz; headMap = new TreeMap<>(); - contentPropertyMap = new TreeMap<>(); - fieldNameContentPropertyMap = MapUtils.newHashMap(); ignoreMap = MapUtils.newHashMap(); headKind = HeadKindEnum.NONE; headRowNumber = 0; @@ -80,8 +66,7 @@ public class ExcelHeadProperty { continue; } } - headMap.put(headIndex, new Head(headIndex, null, head.get(i), Boolean.FALSE, Boolean.TRUE)); - contentPropertyMap.put(headIndex, null); + headMap.put(headIndex, new Head(headIndex, null, null, head.get(i), Boolean.FALSE, Boolean.TRUE)); headIndex++; } headKind = HeadKindEnum.STRING; @@ -148,39 +133,20 @@ public class ExcelHeadProperty { private void initOneColumnProperty(int index, Field field, Boolean forceIndex) { ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class); List tmpHeadList = new ArrayList(); + String fieldName = FieldUtils.resolveCglibFieldName(field); boolean notForceName = excelProperty == null || excelProperty.value().length <= 0 || (excelProperty.value().length == 1 && StringUtils.isEmpty((excelProperty.value())[0])); if (headMap.containsKey(index)) { tmpHeadList.addAll(headMap.get(index).getHeadNameList()); } else { if (notForceName) { - tmpHeadList.add(field.getName()); + tmpHeadList.add(fieldName); } else { Collections.addAll(tmpHeadList, excelProperty.value()); } } - Head head = new Head(index, field.getName(), tmpHeadList, forceIndex, !notForceName); - ExcelContentProperty excelContentProperty = new ExcelContentProperty(); - if (excelProperty != null) { - Class 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))); + Head head = new Head(index, field, fieldName, tmpHeadList, forceIndex, !notForceName); headMap.put(index, head); - contentPropertyMap.put(index, excelContentProperty); - fieldNameContentPropertyMap.put(field.getName(), excelContentProperty); } public boolean hasHead() { diff --git a/src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java b/src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java index 6a814f4d..7ba8b88f 100644 --- a/src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java +++ b/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.metadata.Head; 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.property.ExcelReadHeadProperty; import com.alibaba.excel.util.BeanMapUtils; +import com.alibaba.excel.util.ClassUtils; import com.alibaba.excel.util.ConverterUtils; -import com.alibaba.excel.util.FieldUtils; import com.alibaba.excel.util.MapUtils; +import net.sf.cglib.beans.BeanMap; import org.apache.commons.collections4.CollectionUtils; /** @@ -92,22 +92,23 @@ public class ModelBuildEventListener implements ReadListener headMap = excelReadHeadProperty.getHeadMap(); Map map = MapUtils.newHashMapWithExpectedSize(headMap.size()); - Map contentPropertyMap = excelReadHeadProperty.getContentPropertyMap(); + BeanMap dataMap = BeanMapUtils.create(resultModel); for (Map.Entry entry : headMap.entrySet()) { Integer index = entry.getKey(); + Head head = entry.getValue(); + String fieldName = head.getFieldName(); if (!cellDataMap.containsKey(index)) { continue; } ReadCellData cellData = cellDataMap.get(index); - ExcelContentProperty excelContentProperty = contentPropertyMap.get(index); - Object value = ConverterUtils.convertToJavaObject(cellData, excelContentProperty.getField(), - excelContentProperty, readSheetHolder.converterMap(), context, - context.readRowHolder().getRowIndex(), index); + Object value = ConverterUtils.convertToJavaObject(cellData, head.getField(), + ClassUtils.declaredExcelContentProperty(dataMap, readSheetHolder.excelReadHeadProperty().getHeadClazz(), + fieldName), readSheetHolder.converterMap(), context, context.readRowHolder().getRowIndex(), index); if (value != null) { - map.put(FieldUtils.resolveCglibFieldName(excelContentProperty.getField()), value); + map.put(fieldName, value); } } - BeanMapUtils.create(resultModel).putAll(map); + dataMap.putAll(map); return resultModel; } diff --git a/src/main/java/com/alibaba/excel/read/processor/DefaultAnalysisEventProcessor.java b/src/main/java/com/alibaba/excel/read/processor/DefaultAnalysisEventProcessor.java index c3c50234..914a9654 100644 --- a/src/main/java/com/alibaba/excel/read/processor/DefaultAnalysisEventProcessor.java +++ b/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.metadata.Head; 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.metadata.holder.ReadRowHolder; import com.alibaba.excel.read.metadata.property.ExcelReadHeadProperty; @@ -118,15 +117,11 @@ public class DefaultAnalysisEventProcessor implements AnalysisEventProcessor { Map dataMap = ConverterUtils.convertToStringMap(cellDataMap, analysisContext); ExcelReadHeadProperty excelHeadPropertyData = analysisContext.readSheetHolder().excelReadHeadProperty(); Map headMapData = excelHeadPropertyData.getHeadMap(); - Map contentPropertyMapData = excelHeadPropertyData.getContentPropertyMap(); Map tmpHeadMap = new HashMap(headMapData.size() * 4 / 3 + 1); - Map tmpContentPropertyMap = - new HashMap(contentPropertyMapData.size() * 4 / 3 + 1); for (Map.Entry entry : headMapData.entrySet()) { Head headData = entry.getValue(); if (headData.getForceIndex() || !headData.getForceName()) { tmpHeadMap.put(entry.getKey(), headData); - tmpContentPropertyMap.put(entry.getKey(), contentPropertyMapData.get(entry.getKey())); continue; } List headNameList = headData.getHeadNameList(); @@ -146,12 +141,10 @@ public class DefaultAnalysisEventProcessor implements AnalysisEventProcessor { if (headName.equals(headString)) { headData.setColumnIndex(stringKey); tmpHeadMap.put(stringKey, headData); - tmpContentPropertyMap.put(stringKey, contentPropertyMapData.get(entry.getKey())); break; } } } excelHeadPropertyData.setHeadMap(tmpHeadMap); - excelHeadPropertyData.setContentPropertyMap(tmpContentPropertyMap); } } diff --git a/src/main/java/com/alibaba/excel/util/ClassUtils.java b/src/main/java/com/alibaba/excel/util/ClassUtils.java index 50e9351a..9020d56c 100644 --- a/src/main/java/com/alibaba/excel/util/ClassUtils.java +++ b/src/main/java/com/alibaba/excel/util/ClassUtils.java @@ -1,6 +1,5 @@ package com.alibaba.excel.util; -import java.lang.ref.SoftReference; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.ArrayList; @@ -10,16 +9,30 @@ import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.TreeMap; import java.util.concurrent.ConcurrentHashMap; import com.alibaba.excel.annotation.ExcelIgnore; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; 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.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 net.sf.cglib.beans.BeanMap; + /** * Class utils * @@ -27,7 +40,156 @@ import com.alibaba.excel.write.metadata.holder.WriteHolder; **/ public class ClassUtils { - public static final Map, SoftReference> FIELD_CACHE = new ConcurrentHashMap<>(); + public static final Map, FieldCache> FIELD_CACHE = new ConcurrentHashMap<>(); + + /** + * The cache configuration information for each of the class + */ + public static final Map, Map> CLASS_CONTENT_CACHE + = new ConcurrentHashMap<>(); + + /** + * The cache configuration information for each of the class + */ + public static final Map 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 declaredFieldContentMap(Class clazz) { + if (clazz == null) { + return null; + } + return CLASS_CONTENT_CACHE.computeIfAbsent(clazz, key -> { + List 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 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> 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 @@ -41,7 +203,7 @@ public class ClassUtils { */ public static void declaredFields(Class clazz, Map sortedAllFiledMap, Map indexFiledMap, Map ignoreMap, Boolean needIgnore, Holder holder) { - FieldCache fieldCache = getFieldCache(clazz); + FieldCache fieldCache = declaredFields(clazz); if (fieldCache == null) { return; } @@ -92,45 +254,31 @@ public class ClassUtils { declaredFields(clazz, sortedAllFiledMap, null, null, needIgnore, writeHolder); } - private static FieldCache getFieldCache(Class clazz) { + private static FieldCache declaredFields(Class clazz) { if (clazz == null) { return null; } - SoftReference fieldCacheSoftReference = FIELD_CACHE.get(clazz); - 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(); + return FIELD_CACHE.computeIfAbsent(clazz, key -> { + List tempFieldList = new ArrayList<>(); + Class tempClass = clazz; + // When the parent class is null, it indicates that the parent class (Object class) has reached the top + // level. + while (tempClass != null) { + Collections.addAll(tempFieldList, tempClass.getDeclaredFields()); + // Get the parent class and give it to yourself + tempClass = tempClass.getSuperclass(); } - declaredFields(clazz); - } - return FIELD_CACHE.get(clazz).get(); - } + // Screening of field + Map> orderFiledMap = new TreeMap>(); + Map indexFiledMap = new TreeMap(); + Map ignoreMap = new HashMap(16); - private static void declaredFields(Class clazz) { - List tempFieldList = new ArrayList<>(); - Class tempClass = clazz; - // When the parent class is null, it indicates that the parent class (Object class) has reached the top - // level. - while (tempClass != null) { - Collections.addAll(tempFieldList, tempClass.getDeclaredFields()); - // Get the parent class and give it to yourself - tempClass = tempClass.getSuperclass(); - } - // Screening of field - Map> orderFiledMap = new TreeMap>(); - Map indexFiledMap = new TreeMap(); - Map ignoreMap = new HashMap(16); - - ExcelIgnoreUnannotated excelIgnoreUnannotated = clazz.getAnnotation(ExcelIgnoreUnannotated.class); - for (Field field : tempFieldList) { - declaredOneField(field, orderFiledMap, indexFiledMap, ignoreMap, excelIgnoreUnannotated); - } - FIELD_CACHE.put(clazz, new SoftReference( - new FieldCache(buildSortedAllFiledMap(orderFiledMap, indexFiledMap), indexFiledMap, ignoreMap))); + ExcelIgnoreUnannotated excelIgnoreUnannotated = clazz.getAnnotation(ExcelIgnoreUnannotated.class); + for (Field field : tempFieldList) { + declaredOneField(field, orderFiledMap, indexFiledMap, ignoreMap, excelIgnoreUnannotated); + } + return new FieldCache(buildSortedAllFiledMap(orderFiledMap, indexFiledMap), indexFiledMap, ignoreMap); + }); } private static Map buildSortedAllFiledMap(Map> orderFiledMap, diff --git a/src/main/java/com/alibaba/excel/util/FieldUtils.java b/src/main/java/com/alibaba/excel/util/FieldUtils.java index a5c75731..367c6e55 100644 --- a/src/main/java/com/alibaba/excel/util/FieldUtils.java +++ b/src/main/java/com/alibaba/excel/util/FieldUtils.java @@ -5,7 +5,6 @@ import java.lang.reflect.Modifier; import java.util.Map; import com.alibaba.excel.metadata.NullObject; -import com.alibaba.excel.write.metadata.RowData; import net.sf.cglib.beans.BeanMap; @@ -20,19 +19,17 @@ public class FieldUtils { 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) { - return ((BeanMap)dataMap).getPropertyType(filedName); - } - Object value = dataMap.get(filedName); - if (value != null) { - return value.getClass(); + Class fieldClass = ((BeanMap)dataMap).getPropertyType(filedName); + if (fieldClass != null) { + return fieldClass; + } } - return nullObjectClass; + return getFieldClass(value); } - public static Class getFieldClass(RowData rowData, int dataIndex) { - Object value = rowData.get(dataIndex); + public static Class getFieldClass(Object value) { if (value != null) { return value.getClass(); } diff --git a/src/main/java/com/alibaba/excel/util/ListUtils.java b/src/main/java/com/alibaba/excel/util/ListUtils.java index e64acb36..1a3451d8 100644 --- a/src/main/java/com/alibaba/excel/util/ListUtils.java +++ b/src/main/java/com/alibaba/excel/util/ListUtils.java @@ -10,10 +10,21 @@ import lombok.NonNull; 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 { private ListUtils() {} diff --git a/src/main/java/com/alibaba/excel/util/MapUtils.java b/src/main/java/com/alibaba/excel/util/MapUtils.java index 7d049e9d..6039fbde 100644 --- a/src/main/java/com/alibaba/excel/util/MapUtils.java +++ b/src/main/java/com/alibaba/excel/util/MapUtils.java @@ -5,10 +5,21 @@ import java.util.LinkedHashMap; 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 { private MapUtils() {} diff --git a/src/main/java/com/alibaba/excel/util/NumberUtils.java b/src/main/java/com/alibaba/excel/util/NumberUtils.java index 4226e967..c467762c 100644 --- a/src/main/java/com/alibaba/excel/util/NumberUtils.java +++ b/src/main/java/com/alibaba/excel/util/NumberUtils.java @@ -186,4 +186,5 @@ public class NumberUtils { decimalFormat.setParseBigDecimal(true); return decimalFormat.parse(string); } + } diff --git a/src/main/java/com/alibaba/excel/util/StringUtils.java b/src/main/java/com/alibaba/excel/util/StringUtils.java index 40b77d52..b076370c 100644 --- a/src/main/java/com/alibaba/excel/util/StringUtils.java +++ b/src/main/java/com/alibaba/excel/util/StringUtils.java @@ -1,5 +1,6 @@ package com.alibaba.excel.util; -/* + +/** * 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. @@ -12,8 +13,9 @@ package com.alibaba.excel.util; * 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 StringUtils { private StringUtils() {} @@ -194,7 +196,6 @@ public class StringUtils { return true; } - /** *

Checks if the CharSequence contains only Unicode digits. * A decimal point is not a Unicode digit and returns false.

@@ -221,7 +222,7 @@ public class StringUtils { * StringUtils.isNumeric("+123") = false * * - * @param cs the CharSequence to check, may be null + * @param cs the CharSequence to check, may be null * @return {@code true} if only contains digits, and is non-null * @since 3.0 Changed signature from isNumeric(String) to isNumeric(CharSequence) * @since 3.0 Changed "" to return false and not true diff --git a/src/main/java/com/alibaba/excel/util/StyleUtil.java b/src/main/java/com/alibaba/excel/util/StyleUtil.java index 70c7ac7a..1bafcdc8 100644 --- a/src/main/java/com/alibaba/excel/util/StyleUtil.java +++ b/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.WriteFont; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; 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.ss.usermodel.CellStyle; 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.Workbook; 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; /** * @author jipengfei */ +@Slf4j public class StyleUtil { private StyleUtil() {} @@ -32,11 +37,16 @@ public class StyleUtil { * Build cell style * * @param workbook + * @param originCellStyle * @param writeCellStyle * @return */ - public static CellStyle buildCellStyle(Workbook workbook, WriteCellStyle writeCellStyle) { + public static CellStyle buildCellStyle(Workbook workbook, CellStyle originCellStyle, + WriteCellStyle writeCellStyle) { CellStyle cellStyle = workbook.createCellStyle(); + if (originCellStyle != null) { + cellStyle.cloneStyleFrom(originCellStyle); + } if (writeCellStyle == null) { return cellStyle; } @@ -115,14 +125,23 @@ public class StyleUtil { return dataFormatData.getIndex(); } if (StringUtils.isNotBlank(dataFormatData.getFormat())) { + if (log.isDebugEnabled()) { + log.info("create new data fromat:{}", dataFormatData); + } DataFormat dataFormatCreate = workbook.createDataFormat(); return dataFormatCreate.getFormat(dataFormatData.getFormat()); } return BuiltinFormats.GENERAL; } - public static Font buildFont(Workbook workbook, WriteFont writeFont) { - Font font = workbook.createFont(); + public static Font buildFont(Workbook workbook, Font originFont, WriteFont writeFont) { + 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) { return font; } @@ -156,6 +175,44 @@ public class StyleUtil { 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, RichTextStringData richTextStringData) { if (richTextStringData == null) { @@ -168,12 +225,12 @@ public class StyleUtil { richTextString = new HSSFRichTextString(richTextStringData.getTextString()); } if (richTextStringData.getWriteFont() != null) { - richTextString.applyFont(writeWorkbookHolder.createFont(richTextStringData.getWriteFont())); + richTextString.applyFont(writeWorkbookHolder.createFont(richTextStringData.getWriteFont(), null, true)); } if (CollectionUtils.isNotEmpty(richTextStringData.getIntervalFontList())) { for (IntervalFont intervalFont : richTextStringData.getIntervalFontList()) { richTextString.applyFont(intervalFont.getStartIndex(), intervalFont.getEndIndex(), - writeWorkbookHolder.createFont(intervalFont.getWriteFont())); + writeWorkbookHolder.createFont(intervalFont.getWriteFont(), null, true)); } } return richTextString; diff --git a/src/main/java/com/alibaba/excel/util/WriteHandlerUtils.java b/src/main/java/com/alibaba/excel/util/WriteHandlerUtils.java index 4279baf4..78ce8d8e 100644 --- a/src/main/java/com/alibaba/excel/util/WriteHandlerUtils.java +++ b/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.metadata.Head; import com.alibaba.excel.metadata.data.WriteCellData; +import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.write.handler.CellWriteHandler; import com.alibaba.excel.write.handler.RowWriteHandler; import com.alibaba.excel.write.handler.SheetWriteHandler; @@ -116,7 +117,7 @@ public class WriteHandlerUtils { } public static void beforeCellCreate(WriteContext writeContext, Row row, Head head, Integer columnIndex, - Integer relativeRowIndex, Boolean isHead) { + Integer relativeRowIndex, Boolean isHead, ExcelContentProperty excelContentProperty) { List handlerList = writeContext.currentWriteHolder().writeHandlerMap().get(CellWriteHandler.class); if (handlerList == null || handlerList.isEmpty()) { @@ -124,7 +125,7 @@ public class WriteHandlerUtils { } CellWriteHandlerContext context = new CellWriteHandlerContext(writeContext, writeContext.writeWorkbookHolder(), writeContext.writeSheetHolder(), writeContext.writeTableHolder(), row, null, columnIndex, relativeRowIndex, - head, null, null, isHead); + head, null, null, isHead, excelContentProperty); for (WriteHandler writeHandler : handlerList) { if (writeHandler instanceof CellWriteHandler) { ((CellWriteHandler)writeHandler).beforeCellCreate(context); @@ -133,7 +134,7 @@ public class WriteHandlerUtils { } public static void afterCellCreate(WriteContext writeContext, Cell cell, Head head, Integer relativeRowIndex, - Boolean isHead) { + Boolean isHead, ExcelContentProperty excelContentProperty) { List handlerList = writeContext.currentWriteHolder().writeHandlerMap().get(CellWriteHandler.class); if (handlerList == null || handlerList.isEmpty()) { @@ -141,7 +142,7 @@ public class WriteHandlerUtils { } CellWriteHandlerContext context = new CellWriteHandlerContext(writeContext, writeContext.writeWorkbookHolder(), 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) { if (writeHandler instanceof CellWriteHandler) { ((CellWriteHandler)writeHandler).afterCellCreate(context); @@ -150,8 +151,7 @@ public class WriteHandlerUtils { } public static void afterCellDataConverted(WriteContext writeContext, WriteCellData cellData, Cell cell, - Head head, - Integer relativeRowIndex, Boolean isHead) { + Head head, Integer relativeRowIndex, Boolean isHead, ExcelContentProperty excelContentProperty) { List handlerList = writeContext.currentWriteHolder().writeHandlerMap().get(CellWriteHandler.class); if (handlerList == null || handlerList.isEmpty()) { @@ -160,7 +160,7 @@ public class WriteHandlerUtils { List> cellDataList = cellData == null ? null : ListUtils.newArrayList(cellData); CellWriteHandlerContext context = new CellWriteHandlerContext(writeContext, writeContext.writeWorkbookHolder(), writeContext.writeSheetHolder(), writeContext.writeTableHolder(), cell.getRow(), cell, - cell.getColumnIndex(), relativeRowIndex, head, cellDataList, cellData, isHead); + cell.getColumnIndex(), relativeRowIndex, head, cellDataList, cellData, isHead, excelContentProperty); for (WriteHandler writeHandler : handlerList) { if (writeHandler instanceof CellWriteHandler) { ((CellWriteHandler)writeHandler).afterCellDataConverted(context); @@ -169,14 +169,13 @@ public class WriteHandlerUtils { } public static void afterCellDispose(WriteContext writeContext, WriteCellData cellData, Cell cell, Head head, - Integer relativeRowIndex, Boolean isHead) { + Integer relativeRowIndex, Boolean isHead, ExcelContentProperty excelContentProperty) { List> 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> cellDataList, Cell cell, - Head head, - Integer relativeRowIndex, Boolean isHead) { + Head head, Integer relativeRowIndex, Boolean isHead, ExcelContentProperty excelContentProperty) { List handlerList = writeContext.currentWriteHolder().writeHandlerMap().get(CellWriteHandler.class); if (handlerList == null || handlerList.isEmpty()) { @@ -188,7 +187,7 @@ public class WriteHandlerUtils { } CellWriteHandlerContext context = new CellWriteHandlerContext(writeContext, writeContext.writeWorkbookHolder(), 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) { if (writeHandler instanceof CellWriteHandler) { ((CellWriteHandler)writeHandler).afterCellDispose(context); diff --git a/src/main/java/com/alibaba/excel/write/executor/AbstractExcelWriteExecutor.java b/src/main/java/com/alibaba/excel/write/executor/AbstractExcelWriteExecutor.java index 5cd0cda2..597d94de 100644 --- a/src/main/java/com/alibaba/excel/write/executor/AbstractExcelWriteExecutor.java +++ b/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.WriteHandlerUtils; 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.poi.hssf.usermodel.HSSFClientAnchor; 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.Comment; import org.apache.poi.ss.usermodel.CreationHelper; @@ -51,14 +49,15 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor { protected WriteCellData converterAndSet(WriteHolder currentWriteHolder, Class clazz, 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() .getAutoTrim()); if (needTrim) { value = ((String)value).trim(); } WriteCellData cellData = convert(currentWriteHolder, clazz, targetType, cell, value, excelContentProperty); - WriteHandlerUtils.afterCellDataConverted(writeContext, cellData, cell, head, relativeRowIndex, Boolean.FALSE); + WriteHandlerUtils.afterCellDataConverted(writeContext, cellData, cell, head, relativeRowIndex, Boolean.FALSE, + excelContentProperty); // Fill in picture information fillImage(cell, cellData.getImageDataList()); @@ -72,12 +71,9 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor { // Fill in formula information fillFormula(cell, cellData.getFormulaData()); - // Fill in style information - fillStyle(cell, cellData.getWriteCellStyle()); - // Fill index - cellData.setRowIndex(cell.getRowIndex()); - cellData.setColumnIndex(cell.getColumnIndex()); + cellData.setRowIndex(rowIndex); + cellData.setColumnIndex(columnIndex); if (cellData.getType() == null) { 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) { if (formulaData == null) { return; diff --git a/src/main/java/com/alibaba/excel/write/executor/ExcelWriteAddExecutor.java b/src/main/java/com/alibaba/excel/write/executor/ExcelWriteAddExecutor.java index e053d81f..bdfea49e 100644 --- a/src/main/java/com/alibaba/excel/write/executor/ExcelWriteAddExecutor.java +++ b/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 sortedAllFiledMap) { if (oneRowData == null) { return; } - WriteHandlerUtils.beforeRowCreate(writeContext, n, relativeRowIndex, Boolean.FALSE); - Row row = WorkBookUtil.createRow(writeContext.writeSheetHolder().getSheet(), n); + WriteHandlerUtils.beforeRowCreate(writeContext, rowIndex, relativeRowIndex, Boolean.FALSE); + Row row = WorkBookUtil.createRow(writeContext.writeSheetHolder().getSheet(), rowIndex); WriteHandlerUtils.afterRowCreate(writeContext, row, relativeRowIndex, Boolean.FALSE); if (oneRowData instanceof Collection) { - addBasicTypeToExcel(new CollectionRowData((Collection)oneRowData), row, relativeRowIndex); + addBasicTypeToExcel(new CollectionRowData((Collection)oneRowData), row, rowIndex, relativeRowIndex); } else if (oneRowData instanceof Map) { - addBasicTypeToExcel(new MapRowData((Map)oneRowData), row, relativeRowIndex); + addBasicTypeToExcel(new MapRowData((Map)oneRowData), row, rowIndex, relativeRowIndex); } else { - addJavaObjectToExcel(oneRowData, row, relativeRowIndex, sortedAllFiledMap); + addJavaObjectToExcel(oneRowData, row, rowIndex, relativeRowIndex, sortedAllFiledMap); } 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()) { return; } @@ -89,10 +89,10 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor { if (dataIndex >= oneRowData.size()) { return; } - int cellIndex = entry.getKey(); + int columnIndex = entry.getKey(); Head head = entry.getValue(); - doAddBasicTypeToExcel(oneRowData, head, row, relativeRowIndex, dataIndex++, cellIndex); - maxCellIndex = Math.max(maxCellIndex, cellIndex); + doAddBasicTypeToExcel(oneRowData, head, row, rowIndex, relativeRowIndex, dataIndex++, columnIndex); + maxCellIndex = Math.max(maxCellIndex, columnIndex); } // Finish if (dataIndex >= oneRowData.size()) { @@ -104,22 +104,29 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor { int size = oneRowData.size() - dataIndex; 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, - int cellIndex) { - WriteHandlerUtils.beforeCellCreate(writeContext, row, head, cellIndex, relativeRowIndex, Boolean.FALSE); - Cell cell = WorkBookUtil.createCell(row, cellIndex); - WriteHandlerUtils.afterCellCreate(writeContext, cell, head, relativeRowIndex, Boolean.FALSE); + private void doAddBasicTypeToExcel(RowData oneRowData, Head head, Row row, int rowIndex, int relativeRowIndex, + int dataIndex, int columnIndex) { + ExcelContentProperty excelContentProperty = ClassUtils.declaredExcelContentProperty(null, + writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadClazz(), + 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); WriteCellData cellData = converterAndSet(writeContext.currentWriteHolder(), - FieldUtils.getFieldClass(oneRowData, dataIndex), null, cell, value, null, head, relativeRowIndex); - WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, head, relativeRowIndex, Boolean.FALSE); + FieldUtils.getFieldClass(value), null, cell, value, null, head, relativeRowIndex, rowIndex, columnIndex); + 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 sortedAllFiledMap) { WriteHolder currentWriteHolder = writeContext.currentWriteHolder(); 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 (HeadKindEnum.CLASS.equals(writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadKind())) { Map headMap = writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadMap(); - Map contentPropertyMap = - writeContext.currentWriteHolder().excelWriteHeadProperty().getContentPropertyMap(); - for (Map.Entry entry : contentPropertyMap.entrySet()) { - int cellIndex = entry.getKey(); - ExcelContentProperty excelContentProperty = entry.getValue(); - String name = FieldUtils.resolveCglibFieldName(excelContentProperty.getField()); + for (Map.Entry entry : headMap.entrySet()) { + int columnIndex = entry.getKey(); + Head head = entry.getValue(); + String name = head.getFieldName(); if (!beanMap.containsKey(name)) { continue; } - Head head = headMap.get(cellIndex); - WriteHandlerUtils.beforeCellCreate(writeContext, row, head, cellIndex, relativeRowIndex, Boolean.FALSE); - Cell cell = WorkBookUtil.createCell(row, cellIndex); - WriteHandlerUtils.afterCellCreate(writeContext, cell, head, relativeRowIndex, Boolean.FALSE); + ExcelContentProperty excelContentProperty = ClassUtils.declaredExcelContentProperty(beanMap, + currentWriteHolder.excelWriteHeadProperty().getHeadClazz(), name); + WriteHandlerUtils.beforeCellCreate(writeContext, row, head, columnIndex, relativeRowIndex, + Boolean.FALSE, excelContentProperty); + Cell cell = WorkBookUtil.createCell(row, columnIndex); + WriteHandlerUtils.afterCellCreate(writeContext, cell, head, relativeRowIndex, Boolean.FALSE, + excelContentProperty); Object value = beanMap.get(name); - WriteCellData cellData = converterAndSet(currentWriteHolder, - excelContentProperty.getField().getType(), - null, cell, value, excelContentProperty, head, relativeRowIndex); - WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, head, relativeRowIndex, Boolean.FALSE); + WriteCellData cellData = converterAndSet(currentWriteHolder, head.getField().getType(), + null, cell, value, excelContentProperty, head, relativeRowIndex, rowIndex, columnIndex); + WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, head, relativeRowIndex, Boolean.FALSE, + excelContentProperty); beanMapHandledSet.add(name); - maxCellIndex = Math.max(maxCellIndex, cellIndex); + maxCellIndex = Math.max(maxCellIndex, columnIndex); } } // Finish @@ -160,21 +168,27 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor { initSortedAllFiledMapFieldList(oneRowData.getClass(), sortedAllFiledMap); for (Map.Entry entry : sortedAllFiledMap.entrySet()) { Field field = entry.getValue(); - String filedName = field.getName(); + String filedName = FieldUtils.resolveCglibFieldName(field); boolean uselessData = !beanMap.containsKey(filedName) || beanMapHandledSet.contains(filedName) || ignoreMap.containsKey(filedName); if (uselessData) { continue; } 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 // If there is data, it is written to the next cell Cell cell = WorkBookUtil.createCell(row, maxCellIndex++); - WriteHandlerUtils.afterCellCreate(writeContext, cell, null, relativeRowIndex, Boolean.FALSE); + WriteHandlerUtils.afterCellCreate(writeContext, cell, null, relativeRowIndex, Boolean.FALSE, + excelContentProperty); WriteCellData cellData = converterAndSet(currentWriteHolder, - FieldUtils.getFieldClass(beanMap, filedName), null, cell, value, null, null, relativeRowIndex); - WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, null, relativeRowIndex, Boolean.FALSE); + FieldUtils.getFieldClass(beanMap, filedName, value), null, cell, value, null, null, relativeRowIndex, + rowIndex, maxCellIndex); + WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, null, relativeRowIndex, Boolean.FALSE, + excelContentProperty); } } diff --git a/src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java b/src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java index e91e2834..2fb755a7 100644 --- a/src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java +++ b/src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java @@ -7,6 +7,7 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; 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.property.ExcelContentProperty; import com.alibaba.excel.util.BeanMapUtils; +import com.alibaba.excel.util.ClassUtils; import com.alibaba.excel.util.FieldUtils; import com.alibaba.excel.util.ListUtils; import com.alibaba.excel.util.MapUtils; @@ -188,33 +190,49 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { dataMap = BeanMapUtils.create(oneRowData); } WriteSheetHolder writeSheetHolder = writeContext.writeSheetHolder(); - Map fieldNameContentPropertyMap = - writeContext.currentWriteHolder().excelWriteHeadProperty().getFieldNameContentPropertyMap(); - for (AnalysisCell analysisCell : analysisCellList) { - Cell cell = getOneCell(analysisCell, fillConfig); if (analysisCell.getOnlyOneVariable()) { String variable = analysisCell.getVariableList().get(0); if (!dataMap.containsKey(variable)) { continue; } 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, - FieldUtils.getFieldClass(dataMap, variable), - null, cell, value, fieldNameContentPropertyMap.get(variable), null, relativeRowIndex); - WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, null, relativeRowIndex, Boolean.FALSE); + FieldUtils.getFieldClass(dataMap, variable, value), null, cell, value, excelContentProperty, null, + relativeRowIndex, analysisCell.getRowIndex(), analysisCell.getColumnIndex()); + 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 { StringBuilder cellValueBuild = new StringBuilder(); int index = 0; List> cellDataList = new ArrayList<>(); + Cell cell = getOneCell(analysisCell, fillConfig, ExcelContentProperty.EMPTY); + for (String variable : analysisCell.getVariableList()) { cellValueBuild.append(analysisCell.getPrepareDataList().get(index++)); if (!dataMap.containsKey(variable)) { continue; } Object value = dataMap.get(variable); - WriteCellData cellData = convert(writeSheetHolder, value == null ? null : value.getClass(), - CellDataTypeEnum.STRING, cell, value, fieldNameContentPropertyMap.get(variable)); + ExcelContentProperty excelContentProperty = ClassUtils.declaredExcelContentProperty(dataMap, + writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadClazz(), variable); + WriteCellData cellData = convert(writeSheetHolder, + FieldUtils.getFieldClass(dataMap, variable, value), CellDataTypeEnum.STRING, cell, value, + excelContentProperty); + cellData.setAnalysisCell(analysisCell); cellDataList.add(cellData); CellDataTypeEnum type = cellData.getType(); if (type != null) { @@ -235,8 +253,16 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { } cellValueBuild.append(analysisCell.getPrepareDataList().get(index)); 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, - Boolean.FALSE); + Boolean.FALSE, ExcelContentProperty.EMPTY); } } } @@ -252,7 +278,8 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { return relativeRowIndex; } - private Cell getOneCell(AnalysisCell analysisCell, FillConfig fillConfig) { + private Cell getOneCell(AnalysisCell analysisCell, FillConfig fillConfig, + ExcelContentProperty excelContentProperty) { Sheet cachedSheet = writeContext.writeSheetHolder().getCachedSheet(); if (WriteTemplateAnalysisCellTypeEnum.COMMON.equals(analysisCell.getCellType())) { 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); - Cell cell = createCellIfNecessary(row, lastColumnIndex); - - Map collectionFieldStyleMap = collectionFieldStyleCache.computeIfAbsent( - currentUniqueDataFlag, key -> MapUtils.newHashMap()); + Cell cell = createCellIfNecessary(row, lastColumnIndex, excelContentProperty); if (isOriginalCell) { + Map collectionFieldStyleMap = collectionFieldStyleCache.computeIfAbsent( + currentUniqueDataFlag, key -> MapUtils.newHashMap()); collectionFieldStyleMap.put(analysisCell, cell.getCellStyle()); - } else { - if (fillConfig.getAutoStyle()) { - CellStyle cellStyle = collectionFieldStyleMap.get(analysisCell); - if (cellStyle != null) { - cell.setCellStyle(cellStyle); - } - } } return cell; } - private Cell createCellIfNecessary(Row row, Integer lastColumnIndex) { + private Cell createCellIfNecessary(Row row, Integer lastColumnIndex, ExcelContentProperty excelContentProperty) { Cell cell = row.getCell(lastColumnIndex); if (cell != null) { 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); - WriteHandlerUtils.afterCellCreate(writeContext, cell, null, null, Boolean.FALSE); + WriteHandlerUtils.afterCellCreate(writeContext, cell, null, null, Boolean.FALSE, excelContentProperty); return cell; } diff --git a/src/main/java/com/alibaba/excel/write/handler/context/CellWriteHandlerContext.java b/src/main/java/com/alibaba/excel/write/handler/context/CellWriteHandlerContext.java index 92c1500f..27530f6f 100644 --- a/src/main/java/com/alibaba/excel/write/handler/context/CellWriteHandlerContext.java +++ b/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.metadata.Head; 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.WriteTableHolder; 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. */ private Boolean head; + /** + * Field annotation configuration information. + */ + private ExcelContentProperty excelContentProperty; } diff --git a/src/main/java/com/alibaba/excel/write/handler/impl/FillStyleCellWriteHandler.java b/src/main/java/com/alibaba/excel/write/handler/impl/FillStyleCellWriteHandler.java index 9956ea19..c8116b4d 100644 --- a/src/main/java/com/alibaba/excel/write/handler/impl/FillStyleCellWriteHandler.java +++ b/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 org.apache.commons.collections4.CollectionUtils; +import org.apache.poi.ss.usermodel.CellStyle; /** * fill cell style. @@ -28,16 +29,20 @@ public class FillStyleCellWriteHandler implements CellWriteHandler { @Override public void afterCellDispose(CellWriteHandlerContext context) { List> 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; } - WriteCellData cellData = cellDataList.get(0); WriteCellStyle writeCellStyle = cellData.getWriteCellStyle(); - if (writeCellStyle == null) { + CellStyle originCellStyle = cellData.getOriginCellStyle(); + if (writeCellStyle == null && originCellStyle == null) { return; } WriteWorkbookHolder writeWorkbookHolder = context.getWriteWorkbookHolder(); - context.getCell().setCellStyle(writeWorkbookHolder.createCellStyle(writeCellStyle)); + context.getCell().setCellStyle(writeWorkbookHolder.createCellStyle(writeCellStyle, originCellStyle)); } } diff --git a/src/main/java/com/alibaba/excel/write/metadata/holder/AbstractWriteHolder.java b/src/main/java/com/alibaba/excel/write/metadata/holder/AbstractWriteHolder.java index d6921681..5059894a 100644 --- a/src/main/java/com/alibaba/excel/write/metadata/holder/AbstractWriteHolder.java +++ b/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.metadata.AbstractHolder; 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.OnceAbsoluteMergeProperty; 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.WorkbookWriteHandler; 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.OnceAbsoluteMergeStrategy; 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. */ private Boolean automaticMergeHead; + /** * Ignore the custom columns. */ @@ -194,7 +197,7 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ } if (writeBasicParameter.getCustomConverterList() != null && !writeBasicParameter.getCustomConverterList().isEmpty()) { - for (Converter converter : writeBasicParameter.getCustomConverterList()) { + for (Converter converter : writeBasicParameter.getCustomConverterList()) { getConverterMap().put(ConverterKeyBuild.buildKey(converter.supportJavaTypeKey()), converter); } } @@ -215,8 +218,7 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ if (head.getColumnWidthProperty() != null) { hasColumnWidth = true; } - if (head.getHeadStyleProperty() != null || head.getHeadFontProperty() != null - || head.getContentStyleProperty() != null || head.getContentFontProperty() != null) { + if (head.getHeadStyleProperty() != null || head.getHeadFontProperty() != null) { hasStyle = true; } dealLoopMerge(handlerList, head); @@ -226,9 +228,9 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ dealColumnWidth(handlerList); } - if (hasStyle) { + //if (hasStyle) { dealStyle(handlerList); - } + //} dealRowHigh(handlerList); dealOnceAbsoluteMerge(handlerList); @@ -242,13 +244,17 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ } @Override - protected WriteCellStyle headCellStyle(Head head) { - return WriteCellStyle.build(head.getHeadStyleProperty(), head.getHeadFontProperty()); + protected WriteCellStyle headCellStyle(CellWriteHandlerContext context) { + ExcelContentProperty excelContentProperty = context.getExcelContentProperty(); + return WriteCellStyle.build(excelContentProperty.getContentStyleProperty(), + excelContentProperty.getContentFontProperty()); } @Override - protected WriteCellStyle contentCellStyle(Head head) { - return WriteCellStyle.build(head.getContentStyleProperty(), head.getContentFontProperty()); + protected WriteCellStyle contentCellStyle(CellWriteHandlerContext context) { + ExcelContentProperty excelContentProperty = context.getExcelContentProperty(); + return WriteCellStyle.build(excelContentProperty.getContentStyleProperty(), + excelContentProperty.getContentFontProperty()); } }; handlerList.add(styleStrategy); diff --git a/src/main/java/com/alibaba/excel/write/metadata/holder/WriteWorkbookHolder.java b/src/main/java/com/alibaba/excel/write/metadata/holder/WriteWorkbookHolder.java index 85e15275..374b5b7a 100644 --- a/src/main/java/com/alibaba/excel/write/metadata/holder/WriteWorkbookHolder.java +++ b/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 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.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.streaming.SXSSFWorkbook; +import org.apache.poi.xssf.usermodel.XSSFCellStyle; import org.apache.poi.xssf.usermodel.XSSFWorkbook; /** @@ -37,6 +40,7 @@ import org.apache.poi.xssf.usermodel.XSSFWorkbook; * @author Jiaju Zhuang */ @Data +@Slf4j 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 @@ -129,7 +133,7 @@ public class WriteWorkbookHolder extends AbstractWriteHolder { /** * Used to cell style. */ - private Map cellStyleMap; + private Map> cellStyleIndexMap; /** * Used to font. */ @@ -206,7 +210,7 @@ public class WriteWorkbookHolder extends AbstractWriteHolder { } else { this.writeExcelOnException = writeWorkbook.getWriteExcelOnException(); } - this.cellStyleMap = MapUtils.newHashMap(); + this.cellStyleIndexMap = MapUtils.newHashMap(); this.fontMap = MapUtils.newHashMap(); this.dataFormatMap = MapUtils.newHashMap(); } @@ -242,17 +246,48 @@ public class WriteWorkbookHolder extends AbstractWriteHolder { * create a cell style. * * @param writeCellStyle + * @param originCellStyle * @return */ - public CellStyle createCellStyle(WriteCellStyle writeCellStyle) { - CellStyle cellStyle = cellStyleMap.get(writeCellStyle); + public CellStyle createCellStyle(WriteCellStyle writeCellStyle, CellStyle originCellStyle) { + 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 cellStyleMap = cellStyleIndexMap.computeIfAbsent(styleIndex, + key -> MapUtils.newHashMap()); + CellStyle cellStyle = cellStyleMap.get(tempWriteCellStyle); if (cellStyle != null) { return cellStyle; } - cellStyle = StyleUtil.buildCellStyle(workbook, writeCellStyle); - cellStyle.setDataFormat(createDataFormat(writeCellStyle.getDataFormatData())); - cellStyle.setFont(createFont(writeCellStyle.getWriteFont())); - cellStyleMap.put(writeCellStyle, cellStyle); + if (log.isDebugEnabled()) { + log.info("create new style:{},{}", tempWriteCellStyle, originCellStyle); + } + 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; } @@ -260,15 +295,23 @@ public class WriteWorkbookHolder extends AbstractWriteHolder { * create a font. * * @param writeFont + * @param originFont + * @param useCache * @return */ - public Font createFont(WriteFont writeFont) { - Font font = fontMap.get(writeFont); + public Font createFont(WriteFont writeFont, Font originFont, boolean useCache) { + if (!useCache) { + return StyleUtil.buildFont(workbook, originFont, writeFont); + } + WriteFont tempWriteFont = new WriteFont(); + WriteFont.merge(writeFont, tempWriteFont); + + Font font = fontMap.get(tempWriteFont); if (font != null) { return font; } - font = StyleUtil.buildFont(workbook, writeFont); - fontMap.put(writeFont, font); + font = StyleUtil.buildFont(workbook, originFont, tempWriteFont); + fontMap.put(tempWriteFont, font); return font; } @@ -276,15 +319,25 @@ public class WriteWorkbookHolder extends AbstractWriteHolder { * create a data format. * * @param dataFormatData + * @param useCache * @return */ - public Short createDataFormat(DataFormatData dataFormatData) { - Short dataFormat = dataFormatMap.get(dataFormatData); + public Short createDataFormat(DataFormatData dataFormatData, boolean useCache) { + 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) { return dataFormat; } - dataFormat = StyleUtil.buildDataFormat(workbook, dataFormatData); - dataFormatMap.put(dataFormatData, dataFormat); + dataFormat = StyleUtil.buildDataFormat(workbook, tempDataFormatData); + dataFormatMap.put(tempDataFormatData, dataFormat); return dataFormat; } diff --git a/src/main/java/com/alibaba/excel/write/property/ExcelWriteHeadProperty.java b/src/main/java/com/alibaba/excel/write/property/ExcelWriteHeadProperty.java index c2779136..7f52cd1d 100644 --- a/src/main/java/com/alibaba/excel/write/property/ExcelWriteHeadProperty.java +++ b/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.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.ContentRowHeight; -import com.alibaba.excel.annotation.write.style.ContentStyle; import com.alibaba.excel.annotation.write.style.HeadFontStyle; import com.alibaba.excel.annotation.write.style.HeadRowHeight; 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.Head; 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.FontProperty; 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.StyleProperty; +import lombok.Data; + /** * Define the header attribute of excel * * @author jipengfei */ +@Data public class ExcelWriteHeadProperty extends ExcelHeadProperty { private RowHeightProperty headRowHeightProperty; private RowHeightProperty contentRowHeightProperty; private OnceAbsoluteMergeProperty onceAbsoluteMergeProperty; - public ExcelWriteHeadProperty(Holder holder, Class headClazz, List> head) { + public ExcelWriteHeadProperty(Holder holder, Class headClazz, List> head) { super(holder, headClazz, head); if (getHeadKind() != HeadKindEnum.CLASS) { return; } this.headRowHeightProperty = - RowHeightProperty.build((HeadRowHeight)headClazz.getAnnotation(HeadRowHeight.class)); + RowHeightProperty.build(headClazz.getAnnotation(HeadRowHeight.class)); this.contentRowHeightProperty = - RowHeightProperty.build((ContentRowHeight)headClazz.getAnnotation(ContentRowHeight.class)); + RowHeightProperty.build(headClazz.getAnnotation(ContentRowHeight.class)); this.onceAbsoluteMergeProperty = - OnceAbsoluteMergeProperty.build((OnceAbsoluteMerge)headClazz.getAnnotation(OnceAbsoluteMerge.class)); + OnceAbsoluteMergeProperty.build(headClazz.getAnnotation(OnceAbsoluteMerge.class)); - ColumnWidth parentColumnWidth = (ColumnWidth)headClazz.getAnnotation(ColumnWidth.class); - HeadStyle parentHeadStyle = (HeadStyle)headClazz.getAnnotation(HeadStyle.class); - HeadFontStyle parentHeadFontStyle = (HeadFontStyle)headClazz.getAnnotation(HeadFontStyle.class); - ContentStyle parentContentStyle = (ContentStyle)headClazz.getAnnotation(ContentStyle.class); - ContentFontStyle parentContentFontStyle = (ContentFontStyle)headClazz.getAnnotation(ContentFontStyle.class); + HeadStyle parentHeadStyle = headClazz.getAnnotation(HeadStyle.class); + HeadFontStyle parentHeadFontStyle = headClazz.getAnnotation(HeadFontStyle.class); - for (Map.Entry entry : getContentPropertyMap().entrySet()) { - Integer index = entry.getKey(); - ExcelContentProperty excelContentPropertyData = entry.getValue(); - if (excelContentPropertyData == null) { + for (Map.Entry entry : getHeadMap().entrySet()) { + Head headData = entry.getValue(); + if (headData == null) { throw new IllegalArgumentException( "Passing in the class and list the head, the two must be the same size."); } - Field field = excelContentPropertyData.getField(); - Head headData = getHeadMap().get(index); - ColumnWidth columnWidth = field.getAnnotation(ColumnWidth.class); - if (columnWidth == null) { - columnWidth = parentColumnWidth; - } - headData.setColumnWidthProperty(ColumnWidthProperty.build(columnWidth)); + Field field = headData.getField(); HeadStyle headStyle = field.getAnnotation(HeadStyle.class); if (headStyle == null) { @@ -85,46 +73,10 @@ public class ExcelWriteHeadProperty extends ExcelHeadProperty { } 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))); } } - 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 * diff --git a/src/main/java/com/alibaba/excel/write/style/AbstractVerticalCellStyleStrategy.java b/src/main/java/com/alibaba/excel/write/style/AbstractVerticalCellStyleStrategy.java index e37987bb..f9d76f7f 100644 --- a/src/main/java/com/alibaba/excel/write/style/AbstractVerticalCellStyleStrategy.java +++ b/src/main/java/com/alibaba/excel/write/style/AbstractVerticalCellStyleStrategy.java @@ -18,12 +18,12 @@ public abstract class AbstractVerticalCellStyleStrategy extends AbstractCellStyl return; } WriteCellData cellData = context.getFirstCellData(); - WriteCellStyle.merge(headCellStyle(context.getHeadData()), cellData.getOrCreateStyle()); + WriteCellStyle.merge(headCellStyle(context), cellData.getOrCreateStyle()); } @Override protected void setContentCellStyle(CellWriteHandlerContext context) { - if (stopProcessing(context)) { + if (context.getFirstCellData() == null) { return; } 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 * @return */ - protected WriteCellStyle contentCellStyle(CellWriteHandlerContext context) { - return contentCellStyle(context.getHeadData()); + protected WriteCellStyle headCellStyle(CellWriteHandlerContext context) { + return headCellStyle(context.getHeadData()); } /** @@ -46,7 +46,19 @@ public abstract class AbstractVerticalCellStyleStrategy extends AbstractCellStyl * @param head Nullable * @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 @@ -55,9 +67,7 @@ public abstract class AbstractVerticalCellStyleStrategy extends AbstractCellStyl * @return */ protected WriteCellStyle contentCellStyle(Head head) { - throw new UnsupportedOperationException( - "One of the two methods 'contentCellStyle(Cell cell, Head head, Integer relativeRowIndex)' and " - + "'contentCellStyle(Head head)' must be implemented."); + return null; } protected boolean stopProcessing(CellWriteHandlerContext context) { diff --git a/src/test/java/com/alibaba/easyexcel/test/core/StyleTestUtils.java b/src/test/java/com/alibaba/easyexcel/test/core/StyleTestUtils.java new file mode 100644 index 00000000..266f724a --- /dev/null +++ b/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; + } +} diff --git a/src/test/java/com/alibaba/easyexcel/test/core/fill/FillDataTest.java b/src/test/java/com/alibaba/easyexcel/test/core/fill/FillDataTest.java index 3df12b1c..e85d63a6 100644 --- a/src/test/java/com/alibaba/easyexcel/test/core/fill/FillDataTest.java +++ b/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.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.excel.EasyExcel; import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.enums.WriteDirectionEnum; +import com.alibaba.excel.exception.ExcelGenerateException; import com.alibaba.excel.write.merge.LoopMergeStrategy; import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.excel.write.metadata.fill.FillConfig; 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 */ @FixMethodOrder(MethodSorters.NAME_ASCENDING) @@ -30,8 +30,10 @@ public class FillDataTest { private static File file07; private static File file03; + private static File fileCsv; private static File simpleTemplate07; private static File simpleTemplate03; + private static File simpleTemplateCsv; private static File fileComplex07; private static File complexFillTemplate07; private static File fileComplex03; @@ -53,8 +55,10 @@ public class FillDataTest { public static void init() { file07 = TestFileUtil.createNewFile("fill07.xlsx"); file03 = TestFileUtil.createNewFile("fill03.xls"); + fileCsv = TestFileUtil.createNewFile("fill.csv"); simpleTemplate07 = TestFileUtil.readFile("fill" + File.separator + "simple.xlsx"); simpleTemplate03 = TestFileUtil.readFile("fill" + File.separator + "simple.xls"); + simpleTemplateCsv = TestFileUtil.readFile("fill" + File.separator + "simple.csv"); fileComplex07 = TestFileUtil.createNewFile("fillComplex07.xlsx"); complexFillTemplate07 = TestFileUtil.readFile("fill" + File.separator + "complex.xlsx"); fileComplex03 = TestFileUtil.createNewFile("fillComplex03.xls"); @@ -83,6 +87,13 @@ public class FillDataTest { 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 public void t03ComplexFill07() { complexFill(fileComplex07, complexFillTemplate07); @@ -147,11 +158,11 @@ public class FillDataTest { excelWriter.finish(); List list = EasyExcel.read(file).ignoreEmptyRow(false).sheet().headRowNumber(0).doReadSync(); - Map map0 = (Map) list.get(0); + Map map0 = (Map)list.get(0); Assert.assertEquals("张三", map0.get(21)); - Map map27 = (Map) list.get(27); + Map map27 = (Map)list.get(27); Assert.assertEquals("张三", map27.get(0)); - Map map29 = (Map) list.get(29); + Map map29 = (Map)list.get(29); Assert.assertEquals("张三", map29.get(3)); } @@ -168,7 +179,7 @@ public class FillDataTest { List list = EasyExcel.read(file).sheet().headRowNumber(0).doReadSync(); Assert.assertEquals(list.size(), 5L); - Map map0 = (Map) list.get(0); + Map map0 = (Map)list.get(0); Assert.assertEquals("张三", map0.get(2)); } @@ -185,7 +196,7 @@ public class FillDataTest { excelWriter.finish(); List list = EasyExcel.read(file).sheet().headRowNumber(3).doReadSync(); Assert.assertEquals(list.size(), 21L); - Map map19 = (Map) list.get(19); + Map map19 = (Map)list.get(19); Assert.assertEquals("张三", map19.get(0)); } diff --git a/src/test/java/com/alibaba/easyexcel/test/core/fill/style/FillStyleAnnotatedData.java b/src/test/java/com/alibaba/easyexcel/test/core/fill/style/FillStyleAnnotatedData.java new file mode 100644 index 00000000..52b1cc04 --- /dev/null +++ b/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; +} diff --git a/src/test/java/com/alibaba/easyexcel/test/core/fill/style/FillStyleAnnotatedTest.java b/src/test/java/com/alibaba/easyexcel/test/core/fill/style/FillStyleAnnotatedTest.java new file mode 100644 index 00000000..13367904 --- /dev/null +++ b/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 data() throws Exception { + List 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; + } + +} diff --git a/src/test/java/com/alibaba/easyexcel/test/core/fill/style/FillStyleData.java b/src/test/java/com/alibaba/easyexcel/test/core/fill/style/FillStyleData.java new file mode 100644 index 00000000..98c29fb2 --- /dev/null +++ b/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; +} diff --git a/src/test/java/com/alibaba/easyexcel/test/core/fill/style/FillStyleDataTest.java b/src/test/java/com/alibaba/easyexcel/test/core/fill/style/FillStyleDataTest.java new file mode 100644 index 00000000..210a5b9f --- /dev/null +++ b/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 data() throws Exception { + List 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; + } + +} diff --git a/src/test/java/com/alibaba/easyexcel/test/core/large/LargeDataTest.java b/src/test/java/com/alibaba/easyexcel/test/core/large/LargeDataTest.java index 957894e2..3da8500d 100644 --- a/src/test/java/com/alibaba/easyexcel/test/core/large/LargeDataTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/core/large/LargeDataTest.java @@ -1,6 +1,7 @@ package com.alibaba.easyexcel.test.core.large; import java.io.File; +import java.io.FileOutputStream; import java.util.ArrayList; import java.util.List; @@ -9,6 +10,11 @@ import com.alibaba.excel.EasyExcel; import com.alibaba.excel.ExcelWriter; 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.FixMethodOrder; import org.junit.Test; @@ -25,11 +31,16 @@ public class LargeDataTest { private static File fileFill07; private static File template07; private static File fileCsv; + private static File fileWrite07; + private static File fileWritePoi07; + private int i = 0; @BeforeClass public static void init() { 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"); fileCsv = TestFileUtil.createNewFile("largefileCsv.csv"); } @@ -72,6 +83,41 @@ public class LargeDataTest { 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 data() { List list = new ArrayList<>(); int size = i + 5000; diff --git a/src/test/java/com/alibaba/easyexcel/test/core/noncamel/UnCamelDataListener.java b/src/test/java/com/alibaba/easyexcel/test/core/noncamel/UnCamelDataListener.java index 2f36d665..b307ddb4 100644 --- a/src/test/java/com/alibaba/easyexcel/test/core/noncamel/UnCamelDataListener.java +++ b/src/test/java/com/alibaba/easyexcel/test/core/noncamel/UnCamelDataListener.java @@ -22,11 +22,12 @@ public class UnCamelDataListener extends AnalysisEventListener { public void invokeHeadMap(Map headMap, AnalysisContext context) { log.debug("Head is:{}", JSON.toJSONString(headMap)); Assert.assertEquals(headMap.get(0), "string1"); - Assert.assertEquals(headMap.get(1), "String2"); - Assert.assertEquals(headMap.get(2), "sTring3"); + Assert.assertEquals(headMap.get(1), "string2"); + Assert.assertEquals(headMap.get(2), "STring3"); Assert.assertEquals(headMap.get(3), "STring4"); Assert.assertEquals(headMap.get(4), "STRING5"); Assert.assertEquals(headMap.get(5), "STRing6"); + } @Override diff --git a/src/test/java/com/alibaba/easyexcel/test/core/style/StyleDataTest.java b/src/test/java/com/alibaba/easyexcel/test/core/style/StyleDataTest.java index ceb571db..a48c3238 100644 --- a/src/test/java/com/alibaba/easyexcel/test/core/style/StyleDataTest.java +++ b/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.List; +import com.alibaba.easyexcel.test.core.StyleTestUtils; import com.alibaba.easyexcel.test.util.TestFileUtil; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.annotation.write.style.HeadFontStyle; import com.alibaba.excel.annotation.write.style.HeadStyle; 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.StyleProperty; -import com.alibaba.excel.metadata.data.DataFormatData; import com.alibaba.excel.write.merge.LoopMergeStrategy; import com.alibaba.excel.write.merge.OnceAbsoluteMergeStrategy; 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 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.Font; import org.apache.poi.ss.usermodel.HorizontalAlignment; 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.Workbook; +import org.apache.poi.ss.usermodel.WorkbookFactory; +import org.junit.Assert; import org.junit.BeforeClass; import org.junit.FixMethodOrder; import org.junit.Test; @@ -40,20 +47,26 @@ public class StyleDataTest { private static File file07; private static File file03; + private static File fileVerticalCellStyleStrategy07; + private static File fileVerticalCellStyleStrategy207; + private static File fileLoopMergeStrategy; @BeforeClass public static void init() { file07 = TestFileUtil.createNewFile("style07.xlsx"); file03 = TestFileUtil.createNewFile("style03.xls"); + fileVerticalCellStyleStrategy07 = TestFileUtil.createNewFile("verticalCellStyle.xlsx"); + fileVerticalCellStyleStrategy207 = TestFileUtil.createNewFile("verticalCellStyle2.xlsx"); + fileLoopMergeStrategy = TestFileUtil.createNewFile("loopMergeStrategy.xlsx"); } @Test - public void t01ReadAndWrite07() { + public void t01ReadAndWrite07() throws Exception { readAndWrite(file07); } @Test - public void t02ReadAndWrite03() { + public void t02ReadAndWrite03() throws Exception { readAndWrite(file03); } @@ -113,9 +126,12 @@ public class StyleDataTest { return writeCellStyle; } }; - EasyExcel.write(file07, StyleData.class).registerWriteHandler(verticalCellStyleStrategy).sheet() + EasyExcel.write(fileVerticalCellStyleStrategy07, StyleData.class).registerWriteHandler( + verticalCellStyleStrategy).sheet() .doWrite(data()); + } + @Test public void t04AbstractVerticalCellStyleStrategy02() { final StyleProperty styleProperty = StyleProperty.build(StyleData.class.getAnnotation(HeadStyle.class)); @@ -152,32 +168,36 @@ public class StyleDataTest { return writeCellStyle; } }; - EasyExcel.write(file07, StyleData.class).registerWriteHandler(verticalCellStyleStrategy).sheet() + EasyExcel.write(fileVerticalCellStyleStrategy207, StyleData.class).registerWriteHandler( + verticalCellStyleStrategy).sheet() .doWrite(data()); } @Test 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()); } - private void readAndWrite(File file) { + private void readAndWrite(File file) throws Exception { SimpleColumnWidthStyleStrategy simpleColumnWidthStyleStrategy = new SimpleColumnWidthStyleStrategy(50); SimpleRowHeightStyleStrategy simpleRowHeightStyleStrategy = new SimpleRowHeightStyleStrategy((short)40, (short)50); WriteCellStyle headWriteCellStyle = new WriteCellStyle(); - headWriteCellStyle.setFillForegroundColor(IndexedColors.RED.getIndex()); + headWriteCellStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex()); WriteFont headWriteFont = new WriteFont(); headWriteFont.setFontHeightInPoints((short)20); + headWriteFont.setColor(IndexedColors.DARK_YELLOW.getIndex()); headWriteCellStyle.setWriteFont(headWriteFont); WriteCellStyle contentWriteCellStyle = new WriteCellStyle(); contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND); - contentWriteCellStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex()); + contentWriteCellStyle.setFillForegroundColor(IndexedColors.TEAL.getIndex()); WriteFont contentWriteFont = new WriteFont(); - contentWriteFont.setFontHeightInPoints((short)20); - headWriteCellStyle.setWriteFont(contentWriteFont); + contentWriteFont.setFontHeightInPoints((short)30); + contentWriteFont.setColor(IndexedColors.DARK_TEAL.getIndex()); + contentWriteCellStyle.setWriteFont(contentWriteFont); HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle); @@ -186,6 +206,29 @@ public class StyleDataTest { .registerWriteHandler(simpleRowHeightStyleStrategy).registerWriteHandler(horizontalCellStyleStrategy) .registerWriteHandler(onceAbsoluteMergeStrategy).sheet().doWrite(data()); 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 data() { diff --git a/src/test/java/com/alibaba/easyexcel/test/demo/fill/FillData.java b/src/test/java/com/alibaba/easyexcel/test/demo/fill/FillData.java index 8890b82f..589f838c 100644 --- a/src/test/java/com/alibaba/easyexcel/test/demo/fill/FillData.java +++ b/src/test/java/com/alibaba/easyexcel/test/demo/fill/FillData.java @@ -1,5 +1,7 @@ package com.alibaba.easyexcel.test.demo.fill; +import java.util.Date; + import lombok.Data; /** @@ -9,4 +11,6 @@ import lombok.Data; public class FillData { private String name; private double number; + private Date date; + } diff --git a/src/test/java/com/alibaba/easyexcel/test/demo/fill/FillTest.java b/src/test/java/com/alibaba/easyexcel/test/demo/fill/FillTest.java index 309e410f..baca2232 100644 --- a/src/test/java/com/alibaba/easyexcel/test/demo/fill/FillTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/demo/fill/FillTest.java @@ -233,6 +233,7 @@ public class FillTest { list.add(fillData); fillData.setName("张三"); fillData.setNumber(5.2); + fillData.setDate(new Date()); } return list; } diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiTest.java b/src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiTest.java index d56bd7b8..e27136d4 100644 --- a/src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiTest.java @@ -1,6 +1,7 @@ package com.alibaba.easyexcel.test.temp.poi; import java.io.File; +import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.Date; @@ -8,13 +9,22 @@ import java.util.Date; import com.alibaba.easyexcel.test.util.TestFileUtil; 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.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.IndexedColors; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.streaming.SXSSFRow; import org.apache.poi.xssf.streaming.SXSSFSheet; 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.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; @@ -39,25 +49,129 @@ public class PoiTest { SXSSFSheet xssfSheet = xssfWorkbook.getSheetAt(0); LOGGER.info("一共行数:{}", xssfSheet.getLastRowNum()); 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(); - } @Test 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()); XSSFSheet xssfSheet = xssfWorkbook.getSheetAt(0); LOGGER.info("一共行数:{}", xssfSheet.getLastRowNum()); - XSSFRow row = xssfSheet.getRow(0); - LOGGER.info("dd{}",row.getCell(0).getRow().getRowNum()); - LOGGER.info("dd{}",xssfSheet.getLastRowNum()); + XSSFRow row = xssfSheet.getRow(1); + LOGGER.info("dd{}", row.getCell(0).getRow().getRowNum()); + LOGGER.info("dd{}", xssfSheet.getLastRowNum()); - Date date = row.getCell(1).getDateCellValue(); - LOGGER.info("date{}",date); + XSSFCellStyle cellStyle = row.getCell(0).getCellStyle(); + 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 diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiWriteTest.java b/src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiWriteTest.java index fa417049..59330bbd 100644 --- a/src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiWriteTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiWriteTest.java @@ -1,10 +1,15 @@ package com.alibaba.easyexcel.test.temp.poi; +import java.io.BufferedInputStream; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; import java.math.BigDecimal; +import java.net.URL; import java.util.regex.Pattern; +import com.alibaba.fastjson.JSON; + import org.apache.poi.xssf.streaming.SXSSFCell; import org.apache.poi.xssf.streaming.SXSSFRow; import org.apache.poi.xssf.streaming.SXSSFSheet; @@ -14,8 +19,6 @@ import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.alibaba.fastjson.JSON; - /** * 测试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()); + + + } + } diff --git a/src/test/resources/demo/fill/list.xlsx b/src/test/resources/demo/fill/list.xlsx index 717cb498..d29e05e7 100644 Binary files a/src/test/resources/demo/fill/list.xlsx and b/src/test/resources/demo/fill/list.xlsx differ diff --git a/src/test/resources/fill/simple.csv b/src/test/resources/fill/simple.csv new file mode 100644 index 00000000..a5153481 --- /dev/null +++ b/src/test/resources/fill/simple.csv @@ -0,0 +1,2 @@ +姓名,数字,复杂,忽略,空 +{name},{number},{name}今年{number}岁了,\{name\}忽略,{name},空{.empty} \ No newline at end of file diff --git a/src/test/resources/fill/style.xls b/src/test/resources/fill/style.xls new file mode 100644 index 00000000..3127743c Binary files /dev/null and b/src/test/resources/fill/style.xls differ diff --git a/src/test/resources/fill/style.xlsx b/src/test/resources/fill/style.xlsx new file mode 100644 index 00000000..062540d0 Binary files /dev/null and b/src/test/resources/fill/style.xlsx differ diff --git a/update.md b/update.md index 7a2cb568..fdec0ee3 100644 --- a/update.md +++ b/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 * 修复导出浮点型数据可能精度异常的bug