Browse Source

修改完成支持导出日期格式

pull/2074/head
Jiaju Zhuang 4 years ago
parent
commit
fdd5d85f22
  1. 22
      src/main/java/com/alibaba/excel/analysis/v03/handlers/FormulaRecordHandler.java
  2. 9
      src/main/java/com/alibaba/excel/analysis/v03/handlers/NumberRecordHandler.java
  3. 2
      src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java
  4. 6
      src/main/java/com/alibaba/excel/constant/BuiltinFormats.java
  5. 13
      src/main/java/com/alibaba/excel/constant/OrderConstant.java
  6. 78
      src/main/java/com/alibaba/excel/converters/Converter.java
  7. 23
      src/main/java/com/alibaba/excel/converters/DefaultConverterLoader.java
  8. 8
      src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalNumberConverter.java
  9. 2
      src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalStringConverter.java
  10. 8
      src/main/java/com/alibaba/excel/converters/byteconverter/ByteNumberConverter.java
  11. 2
      src/main/java/com/alibaba/excel/converters/byteconverter/ByteStringConverter.java
  12. 34
      src/main/java/com/alibaba/excel/converters/date/DateDateConverter.java
  13. 9
      src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleNumberConverter.java
  14. 2
      src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleStringConverter.java
  15. 11
      src/main/java/com/alibaba/excel/converters/floatconverter/FloatNumberConverter.java
  16. 2
      src/main/java/com/alibaba/excel/converters/floatconverter/FloatStringConverter.java
  17. 10
      src/main/java/com/alibaba/excel/converters/integer/IntegerNumberConverter.java
  18. 2
      src/main/java/com/alibaba/excel/converters/integer/IntegerStringConverter.java
  19. 10
      src/main/java/com/alibaba/excel/converters/longconverter/LongBooleanConverter.java
  20. 14
      src/main/java/com/alibaba/excel/converters/longconverter/LongNumberConverter.java
  21. 8
      src/main/java/com/alibaba/excel/converters/longconverter/LongStringConverter.java
  22. 10
      src/main/java/com/alibaba/excel/converters/shortconverter/ShortBooleanConverter.java
  23. 13
      src/main/java/com/alibaba/excel/converters/shortconverter/ShortNumberConverter.java
  24. 2
      src/main/java/com/alibaba/excel/converters/shortconverter/ShortStringConverter.java
  25. 8
      src/main/java/com/alibaba/excel/enums/CellDataTypeEnum.java
  26. 2
      src/main/java/com/alibaba/excel/event/AnalysisEventListener.java
  27. 8
      src/main/java/com/alibaba/excel/metadata/AbstractHolder.java
  28. 110
      src/main/java/com/alibaba/excel/metadata/CellData.java
  29. 2
      src/main/java/com/alibaba/excel/metadata/ConfigurationHolder.java
  30. 10
      src/main/java/com/alibaba/excel/metadata/format/DataFormatter.java
  31. 48
      src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java
  32. 2
      src/main/java/com/alibaba/excel/read/listener/ReadListener.java
  33. 18
      src/main/java/com/alibaba/excel/read/metadata/holder/AbstractReadHolder.java
  34. 4
      src/main/java/com/alibaba/excel/read/processor/DefaultAnalysisEventProcessor.java
  35. 75
      src/main/java/com/alibaba/excel/util/BooleanUtils.java
  36. 49
      src/main/java/com/alibaba/excel/util/ConverterUtils.java
  37. 24
      src/main/java/com/alibaba/excel/util/DateUtils.java
  38. 9
      src/main/java/com/alibaba/excel/util/IntUtils.java
  39. 58
      src/main/java/com/alibaba/excel/util/ListUtils.java
  40. 63
      src/main/java/com/alibaba/excel/util/MapUtils.java
  41. 2
      src/main/java/com/alibaba/excel/util/NumberDataFormatterUtils.java
  42. 24
      src/main/java/com/alibaba/excel/util/NumberUtils.java
  43. 25
      src/main/java/com/alibaba/excel/util/WorkBookUtil.java
  44. 4
      src/main/java/com/alibaba/excel/util/WriteHandlerUtils.java
  45. 19
      src/main/java/com/alibaba/excel/write/executor/AbstractExcelWriteExecutor.java
  46. 2
      src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java
  47. 2
      src/main/java/com/alibaba/excel/write/handler/AbstractCellWriteHandler.java
  48. 4
      src/main/java/com/alibaba/excel/write/handler/CellWriteHandler.java
  49. 2
      src/main/java/com/alibaba/excel/write/handler/DefaultWriteHandlerLoader.java
  50. 75
      src/main/java/com/alibaba/excel/write/handler/impl/FillDataFormatCellWriteHandler.java
  51. 25
      src/main/java/com/alibaba/excel/write/merge/AbstractMergeStrategy.java
  52. 2
      src/main/java/com/alibaba/excel/write/metadata/holder/AbstractWriteHolder.java
  53. 168
      src/main/java/com/alibaba/excel/write/metadata/holder/WriteWorkbookHolder.java
  54. 38
      src/main/java/com/alibaba/excel/write/style/AbstractCellStyleStrategy.java
  55. 28
      src/main/java/com/alibaba/excel/write/style/AbstractVerticalCellStyleStrategy.java
  56. 50
      src/main/java/com/alibaba/excel/write/style/HorizontalCellStyleStrategy.java
  57. 4
      src/main/java/com/alibaba/excel/write/style/column/AbstractColumnWidthStyleStrategy.java
  58. 2
      src/main/java/com/alibaba/excel/write/style/column/AbstractHeadColumnWidthStyleStrategy.java
  59. 4
      src/main/java/com/alibaba/excel/write/style/column/LongestMatchColumnWidthStyleStrategy.java
  60. 2
      src/test/java/com/alibaba/easyexcel/test/core/handler/WriteHandler.java
  61. 2
      src/test/java/com/alibaba/easyexcel/test/demo/write/CustomCellWriteHandler.java
  62. 4
      src/test/java/com/alibaba/easyexcel/test/temp/dataformat/DataFormatTest.java

22
src/main/java/com/alibaba/excel/analysis/v03/handlers/FormulaRecordHandler.java

@ -3,14 +3,6 @@ package com.alibaba.excel.analysis.v03.handlers;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Map; import java.util.Map;
import com.alibaba.excel.enums.RowTypeEnum;
import org.apache.poi.hssf.model.HSSFFormulaParser;
import org.apache.poi.hssf.record.FormulaRecord;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.ss.usermodel.CellType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.excel.analysis.v03.IgnorableXlsRecordHandler; import com.alibaba.excel.analysis.v03.IgnorableXlsRecordHandler;
import com.alibaba.excel.constant.BuiltinFormats; import com.alibaba.excel.constant.BuiltinFormats;
import com.alibaba.excel.context.xls.XlsReadContext; import com.alibaba.excel.context.xls.XlsReadContext;
@ -19,6 +11,13 @@ import com.alibaba.excel.enums.RowTypeEnum;
import com.alibaba.excel.metadata.Cell; import com.alibaba.excel.metadata.Cell;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
import org.apache.poi.hssf.model.HSSFFormulaParser;
import org.apache.poi.hssf.record.FormulaRecord;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.ss.usermodel.CellType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* Record handler * Record handler
* *
@ -32,7 +31,7 @@ public class FormulaRecordHandler extends AbstractXlsRecordHandler implements Ig
public void processRecord(XlsReadContext xlsReadContext, Record record) { public void processRecord(XlsReadContext xlsReadContext, Record record) {
FormulaRecord frec = (FormulaRecord)record; FormulaRecord frec = (FormulaRecord)record;
Map<Integer, Cell> cellMap = xlsReadContext.xlsReadSheetHolder().getCellMap(); Map<Integer, Cell> cellMap = xlsReadContext.xlsReadSheetHolder().getCellMap();
CellData tempCellData = new CellData(); CellData<?> tempCellData = new CellData<>();
tempCellData.setRowIndex(frec.getRow()); tempCellData.setRowIndex(frec.getRow());
tempCellData.setColumnIndex((int)frec.getColumn()); tempCellData.setColumnIndex((int)frec.getColumn());
CellType cellType = CellType.forInt(frec.getCachedResultType()); CellType cellType = CellType.forInt(frec.getCachedResultType());
@ -58,8 +57,9 @@ public class FormulaRecordHandler extends AbstractXlsRecordHandler implements Ig
tempCellData.setNumberValue(BigDecimal.valueOf(frec.getValue())); tempCellData.setNumberValue(BigDecimal.valueOf(frec.getValue()));
Integer dataFormat = Integer dataFormat =
xlsReadContext.xlsReadWorkbookHolder().getFormatTrackingHSSFListener().getFormatIndex(frec); xlsReadContext.xlsReadWorkbookHolder().getFormatTrackingHSSFListener().getFormatIndex(frec);
tempCellData.setDataFormat(dataFormat); Short dataFormatShort = dataFormat.shortValue();
tempCellData.setDataFormatString(BuiltinFormats.getBuiltinFormat(dataFormat, tempCellData.setDataFormat(dataFormatShort);
tempCellData.setDataFormatString(BuiltinFormats.getBuiltinFormat(dataFormatShort,
xlsReadContext.xlsReadWorkbookHolder().getFormatTrackingHSSFListener().getFormatString(frec), xlsReadContext.xlsReadWorkbookHolder().getFormatTrackingHSSFListener().getFormatString(frec),
xlsReadContext.readSheetHolder().getGlobalConfiguration().getLocale())); xlsReadContext.readSheetHolder().getGlobalConfiguration().getLocale()));
cellMap.put((int)frec.getColumn(), tempCellData); cellMap.put((int)frec.getColumn(), tempCellData);

9
src/main/java/com/alibaba/excel/analysis/v03/handlers/NumberRecordHandler.java

@ -2,15 +2,15 @@ package com.alibaba.excel.analysis.v03.handlers;
import java.math.BigDecimal; import java.math.BigDecimal;
import org.apache.poi.hssf.record.NumberRecord;
import org.apache.poi.hssf.record.Record;
import com.alibaba.excel.analysis.v03.IgnorableXlsRecordHandler; import com.alibaba.excel.analysis.v03.IgnorableXlsRecordHandler;
import com.alibaba.excel.constant.BuiltinFormats; import com.alibaba.excel.constant.BuiltinFormats;
import com.alibaba.excel.context.xls.XlsReadContext; import com.alibaba.excel.context.xls.XlsReadContext;
import com.alibaba.excel.enums.RowTypeEnum; import com.alibaba.excel.enums.RowTypeEnum;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
import org.apache.poi.hssf.record.NumberRecord;
import org.apache.poi.hssf.record.Record;
/** /**
* Record handler * Record handler
* *
@ -22,7 +22,8 @@ public class NumberRecordHandler extends AbstractXlsRecordHandler implements Ign
public void processRecord(XlsReadContext xlsReadContext, Record record) { public void processRecord(XlsReadContext xlsReadContext, Record record) {
NumberRecord nr = (NumberRecord)record; NumberRecord nr = (NumberRecord)record;
CellData cellData = CellData.newInstance(BigDecimal.valueOf(nr.getValue()), nr.getRow(), (int)nr.getColumn()); CellData cellData = CellData.newInstance(BigDecimal.valueOf(nr.getValue()), nr.getRow(), (int)nr.getColumn());
Integer dataFormat = xlsReadContext.xlsReadWorkbookHolder().getFormatTrackingHSSFListener().getFormatIndex(nr); short dataFormat = (short)xlsReadContext.xlsReadWorkbookHolder().getFormatTrackingHSSFListener().getFormatIndex(
nr);
cellData.setDataFormat(dataFormat); cellData.setDataFormat(dataFormat);
cellData.setDataFormatString(BuiltinFormats.getBuiltinFormat(dataFormat, cellData.setDataFormatString(BuiltinFormats.getBuiltinFormat(dataFormat,
xlsReadContext.xlsReadWorkbookHolder().getFormatTrackingHSSFListener().getFormatString(nr), xlsReadContext.xlsReadWorkbookHolder().getFormatTrackingHSSFListener().getFormatString(nr),

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

@ -52,7 +52,7 @@ public class CellTagHandler extends AbstractXlsxTagHandler {
return; return;
} }
XSSFCellStyle xssfCellStyle = stylesTable.getStyleAt(dateFormatIndexInteger); XSSFCellStyle xssfCellStyle = stylesTable.getStyleAt(dateFormatIndexInteger);
int dataFormat = xssfCellStyle.getDataFormat(); short dataFormat = xssfCellStyle.getDataFormat();
xlsxReadSheetHolder.getTempCellData().setDataFormat(dataFormat); xlsxReadSheetHolder.getTempCellData().setDataFormat(dataFormat);
xlsxReadSheetHolder.getTempCellData().setDataFormatString(BuiltinFormats.getBuiltinFormat(dataFormat, xlsxReadSheetHolder.getTempCellData().setDataFormatString(BuiltinFormats.getBuiltinFormat(dataFormat,
xssfCellStyle.getDataFormatString(), xlsxReadSheetHolder.getGlobalConfiguration().getLocale())); xssfCellStyle.getDataFormatString(), xlsxReadSheetHolder.getGlobalConfiguration().getLocale()));

6
src/main/java/com/alibaba/excel/constant/BuiltinFormats.java

@ -17,7 +17,7 @@ import java.util.Locale;
**/ **/
public class BuiltinFormats { public class BuiltinFormats {
private static final String[] BUILTIN_FORMATS_CN = { public static final String[] BUILTIN_FORMATS_CN = {
// 0 // 0
"General", "General",
// 1 // 1
@ -189,7 +189,7 @@ public class BuiltinFormats {
// end // end
}; };
private static final String[] BUILTIN_FORMATS_US = { public static final String[] BUILTIN_FORMATS_US = {
// 0 // 0
"General", "General",
// 1 // 1
@ -361,7 +361,7 @@ public class BuiltinFormats {
// end // end
}; };
public static String getBuiltinFormat(Integer index, String defaultFormat, Locale locale) { public static String getBuiltinFormat(Short index, String defaultFormat, Locale locale) {
String[] builtinFormat = switchBuiltinFormats(locale); String[] builtinFormat = switchBuiltinFormats(locale);
if (index == null || index < 0 || index >= builtinFormat.length) { if (index == null || index < 0 || index >= builtinFormat.length) {
return defaultFormat; return defaultFormat;

13
src/main/java/com/alibaba/excel/constant/OrderConstant.java

@ -0,0 +1,13 @@
package com.alibaba.excel.constant;
/**
* Order constant.
*
* @author Jiaju Zhuang
*/
public class OrderConstant {
/**
* Sorting of styles written to cells.
*/
public static final int FILL_DATA_FORMAT = 10000;
}

78
src/main/java/com/alibaba/excel/converters/Converter.java

@ -4,12 +4,16 @@ import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.GlobalConfiguration; import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.read.metadata.holder.ReadSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteHolder;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
/** /**
* Convert between Java objects and excel objects * Convert between Java objects and excel objects
* *
* @author Dan Zheng
* @param <T> * @param <T>
* @author Dan Zheng
*/ */
public interface Converter<T> { public interface Converter<T> {
@ -18,44 +22,72 @@ public interface Converter<T> {
* *
* @return Support for Java class * @return Support for Java class
*/ */
Class supportJavaTypeKey(); default Class<T> supportJavaTypeKey() {
throw new UnsupportedOperationException("The current operation is not supported by the current converter.");
}
/** /**
* Back to object enum in excel * Back to object enum in excel
* *
* @return Support for {@link CellDataTypeEnum} * @return Support for {@link CellDataTypeEnum}
*/ */
CellDataTypeEnum supportExcelTypeKey(); default CellDataTypeEnum supportExcelTypeKey() {
throw new UnsupportedOperationException("The current operation is not supported by the current converter.");
}
/**
* Convert excel objects to Java objects
*
* @param cellData Excel cell data.NotNull.
* @param contentProperty Content property.Nullable.
* @param globalConfiguration Global configuration.NotNull.
* @return Data to put into a Java object
* @throws Exception Exception.
*/
default T convertToJavaData(CellData<?> cellData, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) throws Exception {
throw new UnsupportedOperationException("The current operation is not supported by the current converter.");
}
/** /**
* Convert excel objects to Java objects * Convert excel objects to Java objects
* *
* @param cellData * @param cellData Excel cell data.NotNull.
* Excel cell data.NotNull. * @param contentProperty Content property.Nullable.
* @param contentProperty * @param readSheetHolder .NotNull.
* Content property.Nullable.
* @param globalConfiguration
* Global configuration.NotNull.
* @return Data to put into a Java object * @return Data to put into a Java object
* @throws Exception * @throws Exception Exception.
* Exception. */
default T convertToJavaData(CellData<?> cellData,
ExcelContentProperty contentProperty, ReadSheetHolder readSheetHolder) throws Exception {
return convertToJavaData(cellData, contentProperty, readSheetHolder.globalConfiguration());
}
/**
* Convert Java objects to excel objects
*
* @param value Java Data.NotNull.
* @param contentProperty Content property.Nullable.
* @param globalConfiguration Global configuration.NotNull.
* @return Data to put into a Excel
* @throws Exception Exception.
*/ */
T convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, default CellData<?> convertToExcelData(T value, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) throws Exception; GlobalConfiguration globalConfiguration) throws Exception {
throw new UnsupportedOperationException("The current operation is not supported by the current converter.");
}
/** /**
* Convert Java objects to excel objects * Convert Java objects to excel objects
* *
* @param value * @param value Java Data.NotNull.
* Java Data.NotNull. * @param contentProperty Content property.Nullable.
* @param contentProperty * @param currentWriteHolder He would be {@link WriteSheetHolder} or {@link WriteTableHolder}.NotNull.
* Content property.Nullable.
* @param globalConfiguration
* Global configuration.NotNull.
* @return Data to put into a Excel * @return Data to put into a Excel
* @throws Exception * @throws Exception Exception.
* Exception.
*/ */
CellData convertToExcelData(T value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) default CellData<?> convertToExcelData(T value, ExcelContentProperty contentProperty,
throws Exception; WriteHolder currentWriteHolder) throws Exception {
return convertToExcelData(value, contentProperty, currentWriteHolder.globalConfiguration());
}
} }

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

@ -1,6 +1,5 @@
package com.alibaba.excel.converters; package com.alibaba.excel.converters;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import com.alibaba.excel.converters.bigdecimal.BigDecimalBooleanConverter; import com.alibaba.excel.converters.bigdecimal.BigDecimalBooleanConverter;
@ -14,6 +13,7 @@ import com.alibaba.excel.converters.bytearray.ByteArrayImageConverter;
import com.alibaba.excel.converters.byteconverter.ByteBooleanConverter; import com.alibaba.excel.converters.byteconverter.ByteBooleanConverter;
import com.alibaba.excel.converters.byteconverter.ByteNumberConverter; import com.alibaba.excel.converters.byteconverter.ByteNumberConverter;
import com.alibaba.excel.converters.byteconverter.ByteStringConverter; import com.alibaba.excel.converters.byteconverter.ByteStringConverter;
import com.alibaba.excel.converters.date.DateDateConverter;
import com.alibaba.excel.converters.date.DateNumberConverter; import com.alibaba.excel.converters.date.DateNumberConverter;
import com.alibaba.excel.converters.date.DateStringConverter; import com.alibaba.excel.converters.date.DateStringConverter;
import com.alibaba.excel.converters.doubleconverter.DoubleBooleanConverter; import com.alibaba.excel.converters.doubleconverter.DoubleBooleanConverter;
@ -38,6 +38,7 @@ import com.alibaba.excel.converters.string.StringErrorConverter;
import com.alibaba.excel.converters.string.StringNumberConverter; import com.alibaba.excel.converters.string.StringNumberConverter;
import com.alibaba.excel.converters.string.StringStringConverter; import com.alibaba.excel.converters.string.StringStringConverter;
import com.alibaba.excel.converters.url.UrlImageConverter; import com.alibaba.excel.converters.url.UrlImageConverter;
import com.alibaba.excel.util.MapUtils;
/** /**
* Load default handler * Load default handler
@ -45,8 +46,8 @@ import com.alibaba.excel.converters.url.UrlImageConverter;
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
public class DefaultConverterLoader { public class DefaultConverterLoader {
private static Map<String, Converter> defaultWriteConverter; private static Map<String, Converter<?>> defaultWriteConverter;
private static Map<String, Converter> allConverter; private static Map<String, Converter<?>> allConverter;
static { static {
initDefaultWriteConverter(); initDefaultWriteConverter();
@ -54,7 +55,7 @@ public class DefaultConverterLoader {
} }
private static void initAllConverter() { private static void initAllConverter() {
allConverter = new HashMap<String, Converter>(64); allConverter = MapUtils.newHashMapWithExpectedSize(40);
putAllConverter(new BigDecimalBooleanConverter()); putAllConverter(new BigDecimalBooleanConverter());
putAllConverter(new BigDecimalNumberConverter()); putAllConverter(new BigDecimalNumberConverter());
putAllConverter(new BigDecimalStringConverter()); putAllConverter(new BigDecimalStringConverter());
@ -97,11 +98,11 @@ public class DefaultConverterLoader {
} }
private static void initDefaultWriteConverter() { private static void initDefaultWriteConverter() {
defaultWriteConverter = new HashMap<String, Converter>(32); defaultWriteConverter = MapUtils.newHashMapWithExpectedSize(20);
putWriteConverter(new BigDecimalNumberConverter()); putWriteConverter(new BigDecimalNumberConverter());
putWriteConverter(new BooleanBooleanConverter()); putWriteConverter(new BooleanBooleanConverter());
putWriteConverter(new ByteNumberConverter()); putWriteConverter(new ByteNumberConverter());
putWriteConverter(new DateStringConverter()); putWriteConverter(new DateDateConverter());
putWriteConverter(new DoubleNumberConverter()); putWriteConverter(new DoubleNumberConverter());
putWriteConverter(new FloatNumberConverter()); putWriteConverter(new FloatNumberConverter());
putWriteConverter(new IntegerNumberConverter()); putWriteConverter(new IntegerNumberConverter());
@ -120,11 +121,11 @@ public class DefaultConverterLoader {
* *
* @return * @return
*/ */
public static Map<String, Converter> loadDefaultWriteConverter() { public static Map<String, Converter<?>> loadDefaultWriteConverter() {
return defaultWriteConverter; return defaultWriteConverter;
} }
private static void putWriteConverter(Converter converter) { private static void putWriteConverter(Converter<?> converter) {
defaultWriteConverter.put(ConverterKeyBuild.buildKey(converter.supportJavaTypeKey()), converter); defaultWriteConverter.put(ConverterKeyBuild.buildKey(converter.supportJavaTypeKey()), converter);
} }
@ -133,7 +134,7 @@ public class DefaultConverterLoader {
* *
* @return * @return
*/ */
public static Map<String, Converter> loadDefaultReadConverter() { public static Map<String, Converter<?>> loadDefaultReadConverter() {
return loadAllConverter(); return loadAllConverter();
} }
@ -142,11 +143,11 @@ public class DefaultConverterLoader {
* *
* @return * @return
*/ */
public static Map<String, Converter> loadAllConverter() { public static Map<String, Converter<?>> loadAllConverter() {
return allConverter; return allConverter;
} }
private static void putAllConverter(Converter converter) { private static void putAllConverter(Converter<?> converter) {
allConverter.put(ConverterKeyBuild.buildKey(converter.supportJavaTypeKey(), converter.supportExcelTypeKey()), allConverter.put(ConverterKeyBuild.buildKey(converter.supportJavaTypeKey(), converter.supportExcelTypeKey()),
converter); converter);
} }

8
src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalNumberConverter.java

@ -7,6 +7,8 @@ import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.GlobalConfiguration; import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.util.NumberUtils;
import com.alibaba.excel.write.metadata.holder.WriteHolder;
/** /**
* BigDecimal and number converter * BigDecimal and number converter
@ -32,8 +34,8 @@ public class BigDecimalNumberConverter implements Converter<BigDecimal> {
} }
@Override @Override
public CellData convertToExcelData(BigDecimal value, ExcelContentProperty contentProperty, public CellData<?> convertToExcelData(BigDecimal value, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) { WriteHolder currentWriteHolder) {
return new CellData(value); return NumberUtils.formatToCellData(value, contentProperty, currentWriteHolder);
} }
} }

2
src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalStringConverter.java

@ -36,6 +36,6 @@ public class BigDecimalStringConverter implements Converter<BigDecimal> {
@Override @Override
public CellData convertToExcelData(BigDecimal value, ExcelContentProperty contentProperty, public CellData convertToExcelData(BigDecimal value, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) { GlobalConfiguration globalConfiguration) {
return NumberUtils.formatToCellData(value, contentProperty); return NumberUtils.formatToCellDataString(value, contentProperty);
} }
} }

8
src/main/java/com/alibaba/excel/converters/byteconverter/ByteNumberConverter.java

@ -7,6 +7,8 @@ import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.GlobalConfiguration; import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.util.NumberUtils;
import com.alibaba.excel.write.metadata.holder.WriteHolder;
/** /**
* Byte and number converter * Byte and number converter
@ -32,9 +34,9 @@ public class ByteNumberConverter implements Converter<Byte> {
} }
@Override @Override
public CellData convertToExcelData(Byte value, ExcelContentProperty contentProperty, public CellData<?> convertToExcelData(Byte value, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) { WriteHolder currentWriteHolder) {
return new CellData(new BigDecimal(Byte.toString(value))); return NumberUtils.formatToCellData(value, contentProperty, currentWriteHolder);
} }
} }

2
src/main/java/com/alibaba/excel/converters/byteconverter/ByteStringConverter.java

@ -35,7 +35,7 @@ public class ByteStringConverter implements Converter<Byte> {
@Override @Override
public CellData convertToExcelData(Byte value, ExcelContentProperty contentProperty, public CellData convertToExcelData(Byte value, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) { GlobalConfiguration globalConfiguration) {
return NumberUtils.formatToCellData(value, contentProperty); return NumberUtils.formatToCellDataString(value, contentProperty);
} }
} }

34
src/main/java/com/alibaba/excel/converters/date/DateDateConverter.java

@ -0,0 +1,34 @@
package com.alibaba.excel.converters.date;
import java.util.Date;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.util.WorkBookUtil;
import com.alibaba.excel.write.metadata.holder.WriteHolder;
/**
* Date and date converter
*
* @author Jiaju Zhuang
*/
public class DateDateConverter implements Converter<Date> {
@Override
public Class<Date> supportJavaTypeKey() {
return Date.class;
}
@Override
public CellData<?> convertToExcelData(Date value, ExcelContentProperty contentProperty,
WriteHolder currentWriteHolder) throws Exception {
CellData<?> cellData = new CellData<>(value);
if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null
|| contentProperty.getDateTimeFormatProperty().getFormat() == null) {
return cellData;
}
WorkBookUtil.fillDataFormat(cellData, currentWriteHolder,
contentProperty.getDateTimeFormatProperty().getFormat());
return cellData;
}
}

9
src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleNumberConverter.java

@ -7,6 +7,8 @@ import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.GlobalConfiguration; import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.util.NumberUtils;
import com.alibaba.excel.write.metadata.holder.WriteHolder;
/** /**
* Double and number converter * Double and number converter
@ -32,9 +34,8 @@ public class DoubleNumberConverter implements Converter<Double> {
} }
@Override @Override
public CellData convertToExcelData(Double value, ExcelContentProperty contentProperty, public CellData<?> convertToExcelData(Double value, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) { WriteHolder currentWriteHolder) {
return new CellData(BigDecimal.valueOf(value)); return NumberUtils.formatToCellData(value, contentProperty, currentWriteHolder);
} }
} }

2
src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleStringConverter.java

@ -35,6 +35,6 @@ public class DoubleStringConverter implements Converter<Double> {
@Override @Override
public CellData convertToExcelData(Double value, ExcelContentProperty contentProperty, public CellData convertToExcelData(Double value, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) { GlobalConfiguration globalConfiguration) {
return NumberUtils.formatToCellData(value, contentProperty); return NumberUtils.formatToCellDataString(value, contentProperty);
} }
} }

11
src/main/java/com/alibaba/excel/converters/floatconverter/FloatNumberConverter.java

@ -1,12 +1,12 @@
package com.alibaba.excel.converters.floatconverter; package com.alibaba.excel.converters.floatconverter;
import java.math.BigDecimal;
import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.GlobalConfiguration; import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.util.NumberUtils;
import com.alibaba.excel.write.metadata.holder.WriteHolder;
/** /**
* Float and number converter * Float and number converter
@ -32,9 +32,8 @@ public class FloatNumberConverter implements Converter<Float> {
} }
@Override @Override
public CellData convertToExcelData(Float value, ExcelContentProperty contentProperty, public CellData<?> convertToExcelData(Float value, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) { WriteHolder currentWriteHolder) {
return new CellData(new BigDecimal(Float.toString(value))); return NumberUtils.formatToCellData(value, contentProperty, currentWriteHolder);
} }
} }

2
src/main/java/com/alibaba/excel/converters/floatconverter/FloatStringConverter.java

@ -35,6 +35,6 @@ public class FloatStringConverter implements Converter<Float> {
@Override @Override
public CellData convertToExcelData(Float value, ExcelContentProperty contentProperty, public CellData convertToExcelData(Float value, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) { GlobalConfiguration globalConfiguration) {
return NumberUtils.formatToCellData(value, contentProperty); return NumberUtils.formatToCellDataString(value, contentProperty);
} }
} }

10
src/main/java/com/alibaba/excel/converters/integer/IntegerNumberConverter.java

@ -1,12 +1,12 @@
package com.alibaba.excel.converters.integer; package com.alibaba.excel.converters.integer;
import java.math.BigDecimal;
import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.GlobalConfiguration; import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.util.NumberUtils;
import com.alibaba.excel.write.metadata.holder.WriteHolder;
/** /**
* Integer and number converter * Integer and number converter
@ -32,9 +32,9 @@ public class IntegerNumberConverter implements Converter<Integer> {
} }
@Override @Override
public CellData convertToExcelData(Integer value, ExcelContentProperty contentProperty, public CellData<?> convertToExcelData(Integer value, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) { WriteHolder currentWriteHolder) {
return new CellData(new BigDecimal(Integer.toString(value))); return NumberUtils.formatToCellData(value, contentProperty, currentWriteHolder);
} }
} }

2
src/main/java/com/alibaba/excel/converters/integer/IntegerStringConverter.java

@ -35,6 +35,6 @@ public class IntegerStringConverter implements Converter<Integer> {
@Override @Override
public CellData convertToExcelData(Integer value, ExcelContentProperty contentProperty, public CellData convertToExcelData(Integer value, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) { GlobalConfiguration globalConfiguration) {
return NumberUtils.formatToCellData(value, contentProperty); return NumberUtils.formatToCellDataString(value, contentProperty);
} }
} }

10
src/main/java/com/alibaba/excel/converters/longconverter/LongBooleanConverter.java

@ -16,7 +16,7 @@ public class LongBooleanConverter implements Converter<Long> {
private static final Long ZERO = 0L; private static final Long ZERO = 0L;
@Override @Override
public Class supportJavaTypeKey() { public Class<Long> supportJavaTypeKey() {
return Long.class; return Long.class;
} }
@ -26,7 +26,7 @@ public class LongBooleanConverter implements Converter<Long> {
} }
@Override @Override
public Long convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, public Long convertToJavaData(CellData<?> cellData, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) { GlobalConfiguration globalConfiguration) {
if (cellData.getBooleanValue()) { if (cellData.getBooleanValue()) {
return ONE; return ONE;
@ -35,12 +35,12 @@ public class LongBooleanConverter implements Converter<Long> {
} }
@Override @Override
public CellData convertToExcelData(Long value, ExcelContentProperty contentProperty, public CellData<?> convertToExcelData(Long value, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) { GlobalConfiguration globalConfiguration) {
if (ONE.equals(value)) { if (ONE.equals(value)) {
return new CellData(Boolean.TRUE); return new CellData<>(Boolean.TRUE);
} }
return new CellData(Boolean.FALSE); return new CellData<>(Boolean.FALSE);
} }
} }

14
src/main/java/com/alibaba/excel/converters/longconverter/LongNumberConverter.java

@ -1,12 +1,12 @@
package com.alibaba.excel.converters.longconverter; package com.alibaba.excel.converters.longconverter;
import java.math.BigDecimal;
import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.GlobalConfiguration; import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.util.NumberUtils;
import com.alibaba.excel.write.metadata.holder.WriteHolder;
/** /**
* Long and number converter * Long and number converter
@ -16,7 +16,7 @@ import com.alibaba.excel.metadata.property.ExcelContentProperty;
public class LongNumberConverter implements Converter<Long> { public class LongNumberConverter implements Converter<Long> {
@Override @Override
public Class supportJavaTypeKey() { public Class<Long> supportJavaTypeKey() {
return Long.class; return Long.class;
} }
@ -26,15 +26,15 @@ public class LongNumberConverter implements Converter<Long> {
} }
@Override @Override
public Long convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, public Long convertToJavaData(CellData<?> cellData, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) { GlobalConfiguration globalConfiguration) {
return cellData.getNumberValue().longValue(); return cellData.getNumberValue().longValue();
} }
@Override @Override
public CellData convertToExcelData(Long value, ExcelContentProperty contentProperty, public CellData<?> convertToExcelData(Long value, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) { WriteHolder currentWriteHolder) {
return new CellData(BigDecimal.valueOf(value)); return NumberUtils.formatToCellData(value, contentProperty, currentWriteHolder);
} }
} }

8
src/main/java/com/alibaba/excel/converters/longconverter/LongStringConverter.java

@ -17,7 +17,7 @@ import com.alibaba.excel.util.NumberUtils;
public class LongStringConverter implements Converter<Long> { public class LongStringConverter implements Converter<Long> {
@Override @Override
public Class supportJavaTypeKey() { public Class<Long> supportJavaTypeKey() {
return Long.class; return Long.class;
} }
@ -27,14 +27,14 @@ public class LongStringConverter implements Converter<Long> {
} }
@Override @Override
public Long convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, public Long convertToJavaData(CellData<?> cellData, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) throws ParseException { GlobalConfiguration globalConfiguration) throws ParseException {
return NumberUtils.parseLong(cellData.getStringValue(), contentProperty); return NumberUtils.parseLong(cellData.getStringValue(), contentProperty);
} }
@Override @Override
public CellData convertToExcelData(Long value, ExcelContentProperty contentProperty, public CellData<?> convertToExcelData(Long value, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) { GlobalConfiguration globalConfiguration) {
return NumberUtils.formatToCellData(value, contentProperty); return NumberUtils.formatToCellDataString(value, contentProperty);
} }
} }

10
src/main/java/com/alibaba/excel/converters/shortconverter/ShortBooleanConverter.java

@ -16,7 +16,7 @@ public class ShortBooleanConverter implements Converter<Short> {
private static final Short ZERO = 0; private static final Short ZERO = 0;
@Override @Override
public Class supportJavaTypeKey() { public Class<Short> supportJavaTypeKey() {
return Short.class; return Short.class;
} }
@ -26,7 +26,7 @@ public class ShortBooleanConverter implements Converter<Short> {
} }
@Override @Override
public Short convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, public Short convertToJavaData(CellData<?> cellData, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) { GlobalConfiguration globalConfiguration) {
if (cellData.getBooleanValue()) { if (cellData.getBooleanValue()) {
return ONE; return ONE;
@ -35,12 +35,12 @@ public class ShortBooleanConverter implements Converter<Short> {
} }
@Override @Override
public CellData convertToExcelData(Short value, ExcelContentProperty contentProperty, public CellData<?> convertToExcelData(Short value, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) { GlobalConfiguration globalConfiguration) {
if (ONE.equals(value)) { if (ONE.equals(value)) {
return new CellData(Boolean.TRUE); return new CellData<>(Boolean.TRUE);
} }
return new CellData(Boolean.FALSE); return new CellData<>(Boolean.FALSE);
} }
} }

13
src/main/java/com/alibaba/excel/converters/shortconverter/ShortNumberConverter.java

@ -7,6 +7,8 @@ import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.GlobalConfiguration; import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.util.NumberUtils;
import com.alibaba.excel.write.metadata.holder.WriteHolder;
/** /**
* Short and number converter * Short and number converter
@ -16,7 +18,7 @@ import com.alibaba.excel.metadata.property.ExcelContentProperty;
public class ShortNumberConverter implements Converter<Short> { public class ShortNumberConverter implements Converter<Short> {
@Override @Override
public Class supportJavaTypeKey() { public Class<Short> supportJavaTypeKey() {
return Short.class; return Short.class;
} }
@ -26,15 +28,14 @@ public class ShortNumberConverter implements Converter<Short> {
} }
@Override @Override
public Short convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, public Short convertToJavaData(CellData<?> cellData, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) { GlobalConfiguration globalConfiguration) {
return cellData.getNumberValue().shortValue(); return cellData.getNumberValue().shortValue();
} }
@Override @Override
public CellData convertToExcelData(Short value, ExcelContentProperty contentProperty, public CellData<?> convertToExcelData(Short value, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) { WriteHolder currentWriteHolder) {
return new CellData(new BigDecimal(Short.toString(value))); return NumberUtils.formatToCellData(value, contentProperty, currentWriteHolder);
} }
} }

2
src/main/java/com/alibaba/excel/converters/shortconverter/ShortStringConverter.java

@ -35,6 +35,6 @@ public class ShortStringConverter implements Converter<Short> {
@Override @Override
public CellData convertToExcelData(Short value, ExcelContentProperty contentProperty, public CellData convertToExcelData(Short value, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) { GlobalConfiguration globalConfiguration) {
return NumberUtils.formatToCellData(value, contentProperty); return NumberUtils.formatToCellDataString(value, contentProperty);
} }
} }

8
src/main/java/com/alibaba/excel/enums/CellDataTypeEnum.java

@ -39,9 +39,15 @@ public enum CellDataTypeEnum {
/** /**
* Images are currently supported only when writing * Images are currently supported only when writing
*/ */
IMAGE; IMAGE,
/**
* date.Support only when writing.
*/
DATE,
;
private static final Map<String, CellDataTypeEnum> TYPE_ROUTING_MAP = new HashMap<String, CellDataTypeEnum>(16); private static final Map<String, CellDataTypeEnum> TYPE_ROUTING_MAP = new HashMap<String, CellDataTypeEnum>(16);
static { static {
TYPE_ROUTING_MAP.put("s", STRING); TYPE_ROUTING_MAP.put("s", STRING);
TYPE_ROUTING_MAP.put("str", DIRECT_STRING); TYPE_ROUTING_MAP.put("str", DIRECT_STRING);

2
src/main/java/com/alibaba/excel/event/AnalysisEventListener.java

@ -16,7 +16,7 @@ import com.alibaba.excel.util.ConverterUtils;
public abstract class AnalysisEventListener<T> implements ReadListener<T> { public abstract class AnalysisEventListener<T> implements ReadListener<T> {
@Override @Override
public void invokeHead(Map<Integer, CellData> headMap, AnalysisContext context) { public void invokeHead(Map<Integer, CellData<?>> headMap, AnalysisContext context) {
invokeHeadMap(ConverterUtils.convertToStringMap(headMap, context), context); invokeHeadMap(ConverterUtils.convertToStringMap(headMap, context), context);
} }

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

@ -34,7 +34,7 @@ public abstract class AbstractHolder implements ConfigurationHolder {
* <p> * <p>
* Write key: * Write key:
*/ */
private Map<String, Converter> converterMap; private Map<String, Converter<?>> converterMap;
public AbstractHolder(BasicParameter basicParameter, AbstractHolder prentAbstractHolder) { public AbstractHolder(BasicParameter basicParameter, AbstractHolder prentAbstractHolder) {
this.newInitialization = Boolean.TRUE; this.newInitialization = Boolean.TRUE;
@ -103,16 +103,16 @@ public abstract class AbstractHolder implements ConfigurationHolder {
this.globalConfiguration = globalConfiguration; this.globalConfiguration = globalConfiguration;
} }
public Map<String, Converter> getConverterMap() { public Map<String, Converter<?>> getConverterMap() {
return converterMap; return converterMap;
} }
public void setConverterMap(Map<String, Converter> converterMap) { public void setConverterMap(Map<String, Converter<?>> converterMap) {
this.converterMap = converterMap; this.converterMap = converterMap;
} }
@Override @Override
public Map<String, Converter> converterMap() { public Map<String, Converter<?>> converterMap() {
return getConverterMap(); return getConverterMap();
} }

110
src/main/java/com/alibaba/excel/metadata/CellData.java

@ -1,10 +1,14 @@
package com.alibaba.excel.metadata; package com.alibaba.excel.metadata;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Date;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.util.StringUtils; import com.alibaba.excel.util.StringUtils;
import lombok.Getter;
import lombok.Setter;
/** /**
* Excel internal cell data. * Excel internal cell data.
* *
@ -12,6 +16,8 @@ import com.alibaba.excel.util.StringUtils;
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Getter
@Setter
public class CellData<T> extends AbstractCell { public class CellData<T> extends AbstractCell {
private CellDataTypeEnum type; private CellDataTypeEnum type;
/** /**
@ -30,11 +36,15 @@ public class CellData<T> extends AbstractCell {
private String formulaValue; private String formulaValue;
private byte[] imageValue; private byte[] imageValue;
/** /**
* The number formatting.Currently only supported when reading * Support only when writing.
*/
private Date dateValue;
/**
* The number formatting.
*/ */
private Integer dataFormat; private Short dataFormat;
/** /**
* The string of number formatting.Currently only supported when reading * The string of number formatting.
*/ */
private String dataFormatString; private String dataFormatString;
/** /**
@ -120,86 +130,6 @@ public class CellData<T> extends AbstractCell {
this.formula = Boolean.FALSE; this.formula = Boolean.FALSE;
} }
public CellDataTypeEnum getType() {
return type;
}
public void setType(CellDataTypeEnum type) {
this.type = type;
}
public BigDecimal getNumberValue() {
return numberValue;
}
public void setNumberValue(BigDecimal numberValue) {
this.numberValue = numberValue;
}
public String getStringValue() {
return stringValue;
}
public void setStringValue(String stringValue) {
this.stringValue = stringValue;
}
public Boolean getBooleanValue() {
return booleanValue;
}
public void setBooleanValue(Boolean booleanValue) {
this.booleanValue = booleanValue;
}
public Boolean getFormula() {
return formula;
}
public void setFormula(Boolean formula) {
this.formula = formula;
}
public String getFormulaValue() {
return formulaValue;
}
public void setFormulaValue(String formulaValue) {
this.formulaValue = formulaValue;
}
public byte[] getImageValue() {
return imageValue;
}
public void setImageValue(byte[] imageValue) {
this.imageValue = imageValue;
}
public Integer getDataFormat() {
return dataFormat;
}
public void setDataFormat(Integer dataFormat) {
this.dataFormat = dataFormat;
}
public String getDataFormatString() {
return dataFormatString;
}
public void setDataFormatString(String dataFormatString) {
this.dataFormatString = dataFormatString;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
/** /**
* Ensure that the object does not appear null * Ensure that the object does not appear null
*/ */
@ -271,14 +201,28 @@ public class CellData<T> extends AbstractCell {
} }
switch (type) { switch (type) {
case NUMBER: case NUMBER:
if (numberValue == null) {
return StringUtils.EMPTY;
}
return numberValue.toString(); return numberValue.toString();
case BOOLEAN: case BOOLEAN:
if (booleanValue == null) {
return StringUtils.EMPTY;
}
return booleanValue.toString(); return booleanValue.toString();
case DIRECT_STRING: case DIRECT_STRING:
case STRING: case STRING:
case ERROR: case ERROR:
return stringValue; return stringValue;
case DATE:
if (dateValue == null) {
return StringUtils.EMPTY;
}
return dateValue.toString();
case IMAGE: case IMAGE:
if (imageValue == null) {
return StringUtils.EMPTY;
}
return "image[" + imageValue.length + "]"; return "image[" + imageValue.length + "]";
default: default:
return StringUtils.EMPTY; return StringUtils.EMPTY;

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

@ -32,5 +32,5 @@ public interface ConfigurationHolder extends Holder {
* *
* @return Converter * @return Converter
*/ */
Map<String, Converter> converterMap(); Map<String, Converter<?>> converterMap();
} }

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

@ -170,7 +170,7 @@ public class DataFormatter {
this.decimalSymbols = DecimalFormatSymbols.getInstance(this.locale); this.decimalSymbols = DecimalFormatSymbols.getInstance(this.locale);
} }
private Format getFormat(Double data,Integer dataFormat, String dataFormatString) { private Format getFormat(Double data,Short dataFormat, String dataFormatString) {
// Might be better to separate out the n p and z formats, falling back to p when n and z are not set. // Might be better to separate out the n p and z formats, falling back to p when n and z are not set.
// That however would require other code to be re factored. // That however would require other code to be re factored.
@ -225,7 +225,7 @@ public class DataFormatter {
return format; return format;
} }
private Format createFormat(Integer dataFormat, String dataFormatString) { private Format createFormat(Short dataFormat, String dataFormatString) {
String formatStr = dataFormatString; String formatStr = dataFormatString;
Format format = checkSpecialConverter(formatStr); Format format = checkSpecialConverter(formatStr);
@ -607,7 +607,7 @@ public class DataFormatter {
* @param dataFormatString * @param dataFormatString
* @return Formatted value * @return Formatted value
*/ */
private String getFormattedDateString(Double data, Integer dataFormat, String dataFormatString) { private String getFormattedDateString(Double data, Short dataFormat, String dataFormatString) {
Format dateFormat = getFormat(data, dataFormat, dataFormatString); Format dateFormat = getFormat(data, dataFormat, dataFormatString);
if (dateFormat instanceof ExcelStyleDateFormatter) { if (dateFormat instanceof ExcelStyleDateFormatter) {
// Hint about the raw excel value // Hint about the raw excel value
@ -630,7 +630,7 @@ public class DataFormatter {
* @param dataFormatString * @param dataFormatString
* @return a formatted number string * @return a formatted number string
*/ */
private String getFormattedNumberString(Double data, Integer dataFormat, String dataFormatString) { private String getFormattedNumberString(Double data, Short dataFormat, String dataFormatString) {
Format numberFormat = getFormat(data, dataFormat, dataFormatString); Format numberFormat = getFormat(data, dataFormat, dataFormatString);
String formatted = numberFormat.format(data); String formatted = numberFormat.format(data);
return formatted.replaceFirst("E(\\d)", "E+$1"); // to match Excel's E-notation return formatted.replaceFirst("E(\\d)", "E+$1"); // to match Excel's E-notation
@ -644,7 +644,7 @@ public class DataFormatter {
* @param dataFormatString * @param dataFormatString
* @return * @return
*/ */
public String format(Double data, Integer dataFormat, String dataFormatString) { public String format(Double data, Short dataFormat, String dataFormatString) {
if (DateUtils.isADateFormat(dataFormat, dataFormatString)) { if (DateUtils.isADateFormat(dataFormat, dataFormatString)) {
return getFormattedDateString(data, dataFormat, dataFormatString); return getFormattedDateString(data, dataFormat, dataFormatString);
} }

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

@ -14,7 +14,7 @@ import com.alibaba.excel.exception.ExcelDataConvertException;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.read.metadata.holder.ReadHolder; import com.alibaba.excel.read.metadata.holder.ReadSheetHolder;
import com.alibaba.excel.read.metadata.property.ExcelReadHeadProperty; import com.alibaba.excel.read.metadata.property.ExcelReadHeadProperty;
import com.alibaba.excel.util.ConverterUtils; import com.alibaba.excel.util.ConverterUtils;
import com.alibaba.excel.util.FieldUtils; import com.alibaba.excel.util.FieldUtils;
@ -26,28 +26,28 @@ import net.sf.cglib.beans.BeanMap;
* *
* @author jipengfei * @author jipengfei
*/ */
public class ModelBuildEventListener extends AbstractIgnoreExceptionReadListener<Map<Integer, CellData>> { public class ModelBuildEventListener extends AbstractIgnoreExceptionReadListener<Map<Integer, CellData<?>>> {
@Override @Override
public void invokeHead(Map<Integer, CellData> cellDataMap, AnalysisContext context) {} public void invokeHead(Map<Integer, CellData<?>> cellDataMap, AnalysisContext context) {}
@Override @Override
public void invoke(Map<Integer, CellData> cellDataMap, AnalysisContext context) { public void invoke(Map<Integer, CellData<?>> cellDataMap, AnalysisContext context) {
ReadHolder currentReadHolder = context.currentReadHolder(); ReadSheetHolder readSheetHolder = context.readSheetHolder();
if (HeadKindEnum.CLASS.equals(currentReadHolder.excelReadHeadProperty().getHeadKind())) { if (HeadKindEnum.CLASS.equals(readSheetHolder.excelReadHeadProperty().getHeadKind())) {
context.readRowHolder() context.readRowHolder()
.setCurrentRowAnalysisResult(buildUserModel(cellDataMap, currentReadHolder, context)); .setCurrentRowAnalysisResult(buildUserModel(cellDataMap, readSheetHolder, context));
return; return;
} }
context.readRowHolder().setCurrentRowAnalysisResult(buildStringList(cellDataMap, currentReadHolder, context)); context.readRowHolder().setCurrentRowAnalysisResult(buildStringList(cellDataMap, readSheetHolder, context));
} }
private Object buildStringList(Map<Integer, CellData> cellDataMap, ReadHolder currentReadHolder, private Object buildStringList(Map<Integer, CellData<?>> cellDataMap, ReadSheetHolder readSheetHolder,
AnalysisContext context) { AnalysisContext context) {
int index = 0; int index = 0;
if (context.readWorkbookHolder().getDefaultReturnMap()) { if (context.readWorkbookHolder().getDefaultReturnMap()) {
Map<Integer, String> map = new LinkedHashMap<Integer, String>(cellDataMap.size() * 4 / 3 + 1); Map<Integer, String> map = new LinkedHashMap<Integer, String>(cellDataMap.size() * 4 / 3 + 1);
for (Map.Entry<Integer, CellData> entry : cellDataMap.entrySet()) { for (Map.Entry<Integer, CellData<?>> entry : cellDataMap.entrySet()) {
Integer key = entry.getKey(); Integer key = entry.getKey();
CellData cellData = entry.getValue(); CellData cellData = entry.getValue();
while (index < key) { while (index < key) {
@ -60,10 +60,10 @@ public class ModelBuildEventListener extends AbstractIgnoreExceptionReadListener
continue; continue;
} }
map.put(key, map.put(key,
(String)ConverterUtils.convertToJavaObject(cellData, null, null, currentReadHolder.converterMap(), (String)ConverterUtils.convertToJavaObject(cellData, null, null, readSheetHolder.converterMap(),
currentReadHolder.globalConfiguration(), context.readRowHolder().getRowIndex(), key)); readSheetHolder, context.readRowHolder().getRowIndex(), key));
} }
int headSize = currentReadHolder.excelReadHeadProperty().getHeadMap().size(); int headSize = readSheetHolder.excelReadHeadProperty().getHeadMap().size();
while (index < headSize) { while (index < headSize) {
map.put(index, null); map.put(index, null);
index++; index++;
@ -71,10 +71,10 @@ public class ModelBuildEventListener extends AbstractIgnoreExceptionReadListener
return map; return map;
} else { } else {
// Compatible with the old code the old code returns a list // Compatible with the old code the old code returns a list
List<String> list = new ArrayList<String>(); List<String> list = new ArrayList<>();
for (Map.Entry<Integer, CellData> entry : cellDataMap.entrySet()) { for (Map.Entry<Integer, CellData<?>> entry : cellDataMap.entrySet()) {
Integer key = entry.getKey(); Integer key = entry.getKey();
CellData cellData = entry.getValue(); CellData<?> cellData = entry.getValue();
while (index < key) { while (index < key) {
list.add(null); list.add(null);
index++; index++;
@ -85,10 +85,10 @@ public class ModelBuildEventListener extends AbstractIgnoreExceptionReadListener
continue; continue;
} }
list.add( list.add(
(String)ConverterUtils.convertToJavaObject(cellData, null, null, currentReadHolder.converterMap(), (String)ConverterUtils.convertToJavaObject(cellData, null, null, readSheetHolder.converterMap(),
currentReadHolder.globalConfiguration(), context.readRowHolder().getRowIndex(), key)); readSheetHolder, context.readRowHolder().getRowIndex(), key));
} }
int headSize = currentReadHolder.excelReadHeadProperty().getHeadMap().size(); int headSize = readSheetHolder.excelReadHeadProperty().getHeadMap().size();
while (index < headSize) { while (index < headSize) {
list.add(null); list.add(null);
index++; index++;
@ -97,15 +97,15 @@ public class ModelBuildEventListener extends AbstractIgnoreExceptionReadListener
} }
} }
private Object buildUserModel(Map<Integer, CellData> cellDataMap, ReadHolder currentReadHolder, private Object buildUserModel(Map<Integer, CellData<?>> cellDataMap, ReadSheetHolder readSheetHolder,
AnalysisContext context) { AnalysisContext context) {
ExcelReadHeadProperty excelReadHeadProperty = currentReadHolder.excelReadHeadProperty(); ExcelReadHeadProperty excelReadHeadProperty = readSheetHolder.excelReadHeadProperty();
Object resultModel; Object resultModel;
try { try {
resultModel = excelReadHeadProperty.getHeadClazz().newInstance(); resultModel = excelReadHeadProperty.getHeadClazz().newInstance();
} catch (Exception e) { } catch (Exception e) {
throw new ExcelDataConvertException(context.readRowHolder().getRowIndex(), 0, throw new ExcelDataConvertException(context.readRowHolder().getRowIndex(), 0,
new CellData(CellDataTypeEnum.EMPTY), null, new CellData<>(CellDataTypeEnum.EMPTY), null,
"Can not instance class: " + excelReadHeadProperty.getHeadClazz().getName(), e); "Can not instance class: " + excelReadHeadProperty.getHeadClazz().getName(), e);
} }
Map<Integer, Head> headMap = excelReadHeadProperty.getHeadMap(); Map<Integer, Head> headMap = excelReadHeadProperty.getHeadMap();
@ -116,13 +116,13 @@ public class ModelBuildEventListener extends AbstractIgnoreExceptionReadListener
if (!cellDataMap.containsKey(index)) { if (!cellDataMap.containsKey(index)) {
continue; continue;
} }
CellData cellData = cellDataMap.get(index); CellData<?> cellData = cellDataMap.get(index);
if (cellData.getType() == CellDataTypeEnum.EMPTY) { if (cellData.getType() == CellDataTypeEnum.EMPTY) {
continue; continue;
} }
ExcelContentProperty excelContentProperty = contentPropertyMap.get(index); ExcelContentProperty excelContentProperty = contentPropertyMap.get(index);
Object value = ConverterUtils.convertToJavaObject(cellData, excelContentProperty.getField(), Object value = ConverterUtils.convertToJavaObject(cellData, excelContentProperty.getField(),
excelContentProperty, currentReadHolder.converterMap(), currentReadHolder.globalConfiguration(), excelContentProperty, readSheetHolder.converterMap(), readSheetHolder,
context.readRowHolder().getRowIndex(), index); context.readRowHolder().getRowIndex(), index);
if (value != null) { if (value != null) {
map.put(FieldUtils.resolveCglibFieldName(excelContentProperty.getField()), value); map.put(FieldUtils.resolveCglibFieldName(excelContentProperty.getField()), value);

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

@ -29,7 +29,7 @@ public interface ReadListener<T> extends Listener {
* @param headMap * @param headMap
* @param context * @param context
*/ */
void invokeHead(Map<Integer, CellData> headMap, AnalysisContext context); void invokeHead(Map<Integer, CellData<?>> headMap, AnalysisContext context);
/** /**
* When analysis one row trigger invoke function. * When analysis one row trigger invoke function.

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

@ -1,12 +1,8 @@
package com.alibaba.excel.read.metadata.holder; package com.alibaba.excel.read.metadata.holder;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.converters.ConverterKeyBuild; import com.alibaba.excel.converters.ConverterKeyBuild;
import com.alibaba.excel.converters.DefaultConverterLoader; import com.alibaba.excel.converters.DefaultConverterLoader;
@ -17,6 +13,10 @@ import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.read.metadata.ReadBasicParameter; import com.alibaba.excel.read.metadata.ReadBasicParameter;
import com.alibaba.excel.read.metadata.ReadWorkbook; import com.alibaba.excel.read.metadata.ReadWorkbook;
import com.alibaba.excel.read.metadata.property.ExcelReadHeadProperty; import com.alibaba.excel.read.metadata.property.ExcelReadHeadProperty;
import com.alibaba.excel.util.ListUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* Read Holder * Read Holder
@ -24,8 +24,6 @@ import com.alibaba.excel.read.metadata.property.ExcelReadHeadProperty;
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
public abstract class AbstractReadHolder extends AbstractHolder implements ReadHolder { public abstract class AbstractReadHolder extends AbstractHolder implements ReadHolder {
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractReadHolder.class);
/** /**
* Count the number of added heads when read sheet. * Count the number of added heads when read sheet.
* *
@ -84,9 +82,9 @@ public abstract class AbstractReadHolder extends AbstractHolder implements ReadH
} }
if (parentAbstractReadHolder == null) { if (parentAbstractReadHolder == null) {
this.readListenerList = new ArrayList<ReadListener>(); this.readListenerList = ListUtils.newArrayList();
} else { } else {
this.readListenerList = new ArrayList<ReadListener>(parentAbstractReadHolder.getReadListenerList()); this.readListenerList = ListUtils.newArrayList(parentAbstractReadHolder.getReadListenerList());
} }
if (HolderEnum.WORKBOOK.equals(holderType())) { if (HolderEnum.WORKBOOK.equals(holderType())) {
Boolean useDefaultListener = ((ReadWorkbook)readBasicParameter).getUseDefaultListener(); Boolean useDefaultListener = ((ReadWorkbook)readBasicParameter).getUseDefaultListener();
@ -102,11 +100,11 @@ public abstract class AbstractReadHolder extends AbstractHolder implements ReadH
if (parentAbstractReadHolder == null) { if (parentAbstractReadHolder == null) {
setConverterMap(DefaultConverterLoader.loadDefaultReadConverter()); setConverterMap(DefaultConverterLoader.loadDefaultReadConverter());
} else { } else {
setConverterMap(new HashMap<String, Converter>(parentAbstractReadHolder.getConverterMap())); setConverterMap(new HashMap<>(parentAbstractReadHolder.getConverterMap()));
} }
if (readBasicParameter.getCustomConverterList() != null if (readBasicParameter.getCustomConverterList() != null
&& !readBasicParameter.getCustomConverterList().isEmpty()) { && !readBasicParameter.getCustomConverterList().isEmpty()) {
for (Converter converter : readBasicParameter.getCustomConverterList()) { for (Converter<?> converter : readBasicParameter.getCustomConverterList()) {
getConverterMap().put( getConverterMap().put(
ConverterKeyBuild.buildKey(converter.supportJavaTypeKey(), converter.supportExcelTypeKey()), ConverterKeyBuild.buildKey(converter.supportJavaTypeKey(), converter.supportExcelTypeKey()),
converter); converter);

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

@ -82,7 +82,7 @@ public class DefaultAnalysisEventProcessor implements AnalysisEventProcessor {
private void dealData(AnalysisContext analysisContext) { private void dealData(AnalysisContext analysisContext) {
ReadRowHolder readRowHolder = analysisContext.readRowHolder(); ReadRowHolder readRowHolder = analysisContext.readRowHolder();
Map<Integer, CellData> cellDataMap = (Map)readRowHolder.getCellMap(); Map<Integer, CellData<?>> cellDataMap = (Map)readRowHolder.getCellMap();
readRowHolder.setCurrentRowAnalysisResult(cellDataMap); readRowHolder.setCurrentRowAnalysisResult(cellDataMap);
int rowIndex = readRowHolder.getRowIndex(); int rowIndex = readRowHolder.getRowIndex();
int currentHeadRowNumber = analysisContext.readSheetHolder().getHeadRowNumber(); int currentHeadRowNumber = analysisContext.readSheetHolder().getHeadRowNumber();
@ -111,7 +111,7 @@ public class DefaultAnalysisEventProcessor implements AnalysisEventProcessor {
} }
} }
private void buildHead(AnalysisContext analysisContext, Map<Integer, CellData> cellDataMap) { private void buildHead(AnalysisContext analysisContext, Map<Integer, CellData<?>> cellDataMap) {
if (!HeadKindEnum.CLASS.equals(analysisContext.currentReadHolder().excelReadHeadProperty().getHeadKind())) { if (!HeadKindEnum.CLASS.equals(analysisContext.currentReadHolder().excelReadHeadProperty().getHeadKind())) {
return; return;
} }

75
src/main/java/com/alibaba/excel/util/BooleanUtils.java

@ -25,4 +25,79 @@ public class BooleanUtils {
} }
} }
// boolean Boolean methods
//-----------------------------------------------------------------------
/**
* <p>Checks if a {@code Boolean} value is {@code true},
* handling {@code null} by returning {@code false}.</p>
*
* <pre>
* BooleanUtils.isTrue(Boolean.TRUE) = true
* BooleanUtils.isTrue(Boolean.FALSE) = false
* BooleanUtils.isTrue(null) = false
* </pre>
*
* @param bool the boolean to check, null returns {@code false}
* @return {@code true} only if the input is non-null and true
* @since 2.1
*/
public static boolean isTrue(final Boolean bool) {
return Boolean.TRUE.equals(bool);
}
/**
* <p>Checks if a {@code Boolean} value is <i>not</i> {@code true},
* handling {@code null} by returning {@code true}.</p>
*
* <pre>
* BooleanUtils.isNotTrue(Boolean.TRUE) = false
* BooleanUtils.isNotTrue(Boolean.FALSE) = true
* BooleanUtils.isNotTrue(null) = true
* </pre>
*
* @param bool the boolean to check, null returns {@code true}
* @return {@code true} if the input is null or false
* @since 2.3
*/
public static boolean isNotTrue(final Boolean bool) {
return !isTrue(bool);
}
/**
* <p>Checks if a {@code Boolean} value is {@code false},
* handling {@code null} by returning {@code false}.</p>
*
* <pre>
* BooleanUtils.isFalse(Boolean.TRUE) = false
* BooleanUtils.isFalse(Boolean.FALSE) = true
* BooleanUtils.isFalse(null) = false
* </pre>
*
* @param bool the boolean to check, null returns {@code false}
* @return {@code true} only if the input is non-null and false
* @since 2.1
*/
public static boolean isFalse(final Boolean bool) {
return Boolean.FALSE.equals(bool);
}
/**
* <p>Checks if a {@code Boolean} value is <i>not</i> {@code false},
* handling {@code null} by returning {@code true}.</p>
*
* <pre>
* BooleanUtils.isNotFalse(Boolean.TRUE) = true
* BooleanUtils.isNotFalse(Boolean.FALSE) = false
* BooleanUtils.isNotFalse(null) = true
* </pre>
*
* @param bool the boolean to check, null returns {@code true}
* @return {@code true} if the input is null or true
* @since 2.3
*/
public static boolean isNotFalse(final Boolean bool) {
return !isFalse(bool);
}
} }

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

@ -3,7 +3,6 @@ package com.alibaba.excel.util;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType; import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.context.AnalysisContext;
@ -12,9 +11,9 @@ import com.alibaba.excel.converters.ConverterKeyBuild;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.exception.ExcelDataConvertException; import com.alibaba.excel.exception.ExcelDataConvertException;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.read.metadata.holder.ReadHolder; import com.alibaba.excel.read.metadata.holder.ReadHolder;
import com.alibaba.excel.read.metadata.holder.ReadSheetHolder;
/** /**
* Converting objects * Converting objects
@ -32,13 +31,13 @@ public class ConverterUtils {
* @param context * @param context
* @return * @return
*/ */
public static Map<Integer, String> convertToStringMap(Map<Integer, CellData> cellDataMap, AnalysisContext context) { public static Map<Integer, String> convertToStringMap(Map<Integer, CellData<?>> cellDataMap, AnalysisContext context) {
Map<Integer, String> stringMap = new HashMap<Integer, String>(cellDataMap.size() * 4 / 3 + 1); Map<Integer, String> stringMap = MapUtils.newHashMapWithExpectedSize(cellDataMap.size());
ReadHolder currentReadHolder = context.currentReadHolder(); ReadSheetHolder readSheetHolder = context.readSheetHolder();
int index = 0; int index = 0;
for (Map.Entry<Integer, CellData> entry : cellDataMap.entrySet()) { for (Map.Entry<Integer, CellData<?>> entry : cellDataMap.entrySet()) {
Integer key = entry.getKey(); Integer key = entry.getKey();
CellData cellData = entry.getValue(); CellData<?> cellData = entry.getValue();
while (index < key) { while (index < key) {
stringMap.put(index, null); stringMap.put(index, null);
index++; index++;
@ -48,15 +47,15 @@ public class ConverterUtils {
stringMap.put(key, null); stringMap.put(key, null);
continue; continue;
} }
Converter converter = Converter<?> converter =
currentReadHolder.converterMap().get(ConverterKeyBuild.buildKey(String.class, cellData.getType())); readSheetHolder.converterMap().get(ConverterKeyBuild.buildKey(String.class, cellData.getType()));
if (converter == null) { if (converter == null) {
throw new ExcelDataConvertException(context.readRowHolder().getRowIndex(), key, cellData, null, throw new ExcelDataConvertException(context.readRowHolder().getRowIndex(), key, cellData, null,
"Converter not found, convert " + cellData.getType() + " to String"); "Converter not found, convert " + cellData.getType() + " to String");
} }
try { try {
stringMap.put(key, stringMap.put(key,
(String)(converter.convertToJavaData(cellData, null, currentReadHolder.globalConfiguration()))); (String)(converter.convertToJavaData(cellData, null, readSheetHolder)));
} catch (Exception e) { } catch (Exception e) {
throw new ExcelDataConvertException(context.readRowHolder().getRowIndex(), key, cellData, null, throw new ExcelDataConvertException(context.readRowHolder().getRowIndex(), key, cellData, null,
"Convert data " + cellData + " to String error ", e); "Convert data " + cellData + " to String error ", e);
@ -72,15 +71,15 @@ public class ConverterUtils {
* @param field * @param field
* @param contentProperty * @param contentProperty
* @param converterMap * @param converterMap
* @param globalConfiguration * @param readSheetHolder
* @param rowIndex * @param rowIndex
* @param columnIndex * @param columnIndex
* @return * @return
*/ */
public static Object convertToJavaObject(CellData cellData, Field field, ExcelContentProperty contentProperty, public static Object convertToJavaObject(CellData<?> cellData, Field field, ExcelContentProperty contentProperty,
Map<String, Converter> converterMap, GlobalConfiguration globalConfiguration, Integer rowIndex, Map<String, Converter<?>> converterMap, ReadSheetHolder readSheetHolder, Integer rowIndex,
Integer columnIndex) { Integer columnIndex) {
Class clazz; Class<?> clazz;
if (field == null) { if (field == null) {
clazz = String.class; clazz = String.class;
} else { } else {
@ -88,37 +87,37 @@ public class ConverterUtils {
} }
if (clazz == CellData.class) { if (clazz == CellData.class) {
Type type = field.getGenericType(); Type type = field.getGenericType();
Class classGeneric; Class<?> classGeneric;
if (type instanceof ParameterizedType) { if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType)type; ParameterizedType parameterizedType = (ParameterizedType)type;
classGeneric = (Class)parameterizedType.getActualTypeArguments()[0]; classGeneric = (Class<?>)parameterizedType.getActualTypeArguments()[0];
} else { } else {
classGeneric = String.class; classGeneric = String.class;
} }
CellData cellDataReturn = new CellData(cellData); CellData<Object> cellDataReturn = new CellData<Object>(cellData);
cellDataReturn.setData(doConvertToJavaObject(cellData, classGeneric, contentProperty, converterMap, cellDataReturn.setData(doConvertToJavaObject(cellData, classGeneric, contentProperty, converterMap,
globalConfiguration, rowIndex, columnIndex)); readSheetHolder, rowIndex, columnIndex));
return cellDataReturn; return cellDataReturn;
} }
return doConvertToJavaObject(cellData, clazz, contentProperty, converterMap, globalConfiguration, rowIndex, return doConvertToJavaObject(cellData, clazz, contentProperty, converterMap, readSheetHolder, rowIndex,
columnIndex); columnIndex);
} }
/** /**
*
* @param cellData * @param cellData
* @param clazz * @param clazz
* @param contentProperty * @param contentProperty
* @param converterMap * @param converterMap
* @param globalConfiguration * @param readSheetHolder
* @param rowIndex * @param rowIndex
* @param columnIndex * @param columnIndex
* @return * @return
*/ */
private static Object doConvertToJavaObject(CellData cellData, Class clazz, ExcelContentProperty contentProperty, private static Object doConvertToJavaObject(CellData<?> cellData, Class<?> clazz,
Map<String, Converter> converterMap, GlobalConfiguration globalConfiguration, Integer rowIndex, ExcelContentProperty contentProperty,
Map<String, Converter<?>> converterMap, ReadSheetHolder readSheetHolder, Integer rowIndex,
Integer columnIndex) { Integer columnIndex) {
Converter converter = null; Converter<?> converter = null;
if (contentProperty != null) { if (contentProperty != null) {
converter = contentProperty.getConverter(); converter = contentProperty.getConverter();
} }
@ -130,7 +129,7 @@ public class ConverterUtils {
"Converter not found, convert " + cellData.getType() + " to " + clazz.getName()); "Converter not found, convert " + cellData.getType() + " to " + clazz.getName());
} }
try { try {
return converter.convertToJavaData(cellData, contentProperty, globalConfiguration); return converter.convertToJavaData(cellData, contentProperty, readSheetHolder);
} catch (Exception e) { } catch (Exception e) {
throw new ExcelDataConvertException(rowIndex, columnIndex, cellData, contentProperty, throw new ExcelDataConvertException(rowIndex, columnIndex, cellData, contentProperty,
"Convert data " + cellData + " to " + clazz + " error ", e); "Convert data " + cellData + " to " + clazz + " error ", e);

24
src/main/java/com/alibaba/excel/util/DateUtils.java

@ -17,16 +17,16 @@ public class DateUtils {
/** /**
* Is a cache of dates * Is a cache of dates
*/ */
private static final ThreadLocal<Map<Integer, Boolean>> DATE_THREAD_LOCAL = private static final ThreadLocal<Map<Short, Boolean>> DATE_THREAD_LOCAL =
new ThreadLocal<Map<Integer, Boolean>>(); new ThreadLocal<>();
/** /**
* Is a cache of dates * Is a cache of dates
*/ */
private static final ThreadLocal<Map<String, SimpleDateFormat>> DATE_FORMAT_THREAD_LOCAL = private static final ThreadLocal<Map<String, SimpleDateFormat>> DATE_FORMAT_THREAD_LOCAL =
new ThreadLocal<Map<String, SimpleDateFormat>>(); new ThreadLocal<>();
/** /**
* The following patterns are used in {@link #isADateFormat(Integer, String)} * The following patterns are used in {@link #isADateFormat(Short, String)}
*/ */
private static final Pattern date_ptrn1 = Pattern.compile("^\\[\\$\\-.*?\\]"); private static final Pattern date_ptrn1 = Pattern.compile("^\\[\\$\\-.*?\\]");
private static final Pattern date_ptrn2 = Pattern.compile("^\\[[a-zA-Z]+\\]"); private static final Pattern date_ptrn2 = Pattern.compile("^\\[[a-zA-Z]+\\]");
@ -50,6 +50,8 @@ public class DateUtils {
public static final String DATE_FORMAT_19_FORWARD_SLASH = "yyyy/MM/dd HH:mm:ss"; public static final String DATE_FORMAT_19_FORWARD_SLASH = "yyyy/MM/dd HH:mm:ss";
private static final String MINUS = "-"; private static final String MINUS = "-";
public static String defaultDateFormat = DATE_FORMAT_19;
private DateUtils() {} private DateUtils() {}
/** /**
@ -134,7 +136,7 @@ public class DateUtils {
return ""; return "";
} }
if (StringUtils.isEmpty(dateFormat)) { if (StringUtils.isEmpty(dateFormat)) {
dateFormat = DATE_FORMAT_19; dateFormat = defaultDateFormat;
} }
return getCacheDateFormat(dateFormat).format(date); return getCacheDateFormat(dateFormat).format(date);
} }
@ -162,13 +164,13 @@ public class DateUtils {
* @param formatString * @param formatString
* @return * @return
*/ */
public static boolean isADateFormat(Integer formatIndex, String formatString) { public static boolean isADateFormat(Short formatIndex, String formatString) {
if (formatIndex == null) { if (formatIndex == null) {
return false; return false;
} }
Map<Integer, Boolean> isDateCache = DATE_THREAD_LOCAL.get(); Map<Short, Boolean> isDateCache = DATE_THREAD_LOCAL.get();
if (isDateCache == null) { if (isDateCache == null) {
isDateCache = new HashMap<Integer, Boolean>(); isDateCache = MapUtils.newHashMap();
DATE_THREAD_LOCAL.set(isDateCache); DATE_THREAD_LOCAL.set(isDateCache);
} else { } else {
Boolean isDateCachedData = isDateCache.get(formatIndex); Boolean isDateCachedData = isDateCache.get(formatIndex);
@ -188,7 +190,7 @@ public class DateUtils {
* @param formatString * @param formatString
* @return * @return
*/ */
public static boolean isADateFormatUncached(Integer formatIndex, String formatString) { public static boolean isADateFormatUncached(Short formatIndex, String formatString) {
// First up, is this an internal date format? // First up, is this an internal date format?
if (isInternalDateFormat(formatIndex)) { if (isInternalDateFormat(formatIndex)) {
return true; return true;
@ -264,9 +266,9 @@ public class DateUtils {
/** /**
* Given a format ID this will check whether the format represents an internal excel date format or not. * Given a format ID this will check whether the format represents an internal excel date format or not.
* *
* @see #isADateFormat(Integer, String) * @see #isADateFormat(Short, String)
*/ */
public static boolean isInternalDateFormat(int format) { public static boolean isInternalDateFormat(short format) {
switch (format) { switch (format) {
// Internal Date Formats as described on page 427 in // Internal Date Formats as described on page 427 in
// Microsoft Excel Dev's Kit... // Microsoft Excel Dev's Kit...

9
src/main/java/com/alibaba/excel/util/IntUtils.java

@ -10,6 +10,15 @@ import java.util.List;
**/ **/
public class IntUtils { public class IntUtils {
private IntUtils() {} private IntUtils() {}
/**
* The largest power of two that can be represented as an {@code int}.
*
* @since 10.0
*/
public static final int MAX_POWER_OF_TWO = 1 << (Integer.SIZE - 2);
/** /**
* Returns the {@code int} nearest in value to {@code value}. * Returns the {@code int} nearest in value to {@code value}.
* *

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

@ -1,8 +1,13 @@
package com.alibaba.excel.util; package com.alibaba.excel.util;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List; import java.util.List;
import lombok.NonNull;
import org.apache.commons.compress.utils.Iterators;
/** /**
* List utils * List utils
* *
@ -11,6 +16,45 @@ import java.util.List;
public class ListUtils { public class ListUtils {
private ListUtils() {} private ListUtils() {}
/**
* Creates a <i>mutable</i>, empty {@code ArrayList} instance (for Java 6 and earlier).
*
* <p><b>Note for Java 7 and later:</b> this method is now unnecessary and should be treated as
* deprecated. Instead, use the {@code ArrayList} {@linkplain ArrayList#ArrayList() constructor}
* directly, taking advantage of the new <a href="http://goo.gl/iz2Wi">"diamond" syntax</a>.
*/
public static <E> ArrayList<E> newArrayList() {
return new ArrayList<>();
}
/**
* Creates a <i>mutable</i> {@code ArrayList} instance containing the given elements; a very thin
* shortcut for creating an empty list and then calling {@link Iterators#addAll}.
*
*/
public static <E> ArrayList<E> newArrayList(Iterator<? extends E> elements) {
ArrayList<E> list = newArrayList();
Iterators.addAll(list, elements);
return list;
}
/**
* Creates a <i>mutable</i> {@code ArrayList} instance containing the given elements;
*
*
* <p><b>Note for Java 7 and later:</b> if {@code elements} is a {@link Collection}, you don't
* need this method. Use the {@code ArrayList} {@linkplain ArrayList#ArrayList(Collection)
* constructor} directly, taking advantage of the new <a href="http://goo.gl/iz2Wi">"diamond"
* syntax</a>.
*/
public static <E> ArrayList<E> newArrayList(Iterable<? extends E> elements) {
checkNotNull(elements); // for GWT
// Let ArrayList's sizing logic work, if possible
return (elements instanceof Collection)
? new ArrayList<>((Collection<? extends E>)elements)
: newArrayList(elements.iterator());
}
/** /**
* Creates an {@code ArrayList} instance backed by an array with the specified initial size; * Creates an {@code ArrayList} instance backed by an array with the specified initial size;
* simply delegates to {@link ArrayList#ArrayList(int)}. * simply delegates to {@link ArrayList#ArrayList(int)}.
@ -60,4 +104,18 @@ public class ListUtils {
} }
return value; return value;
} }
/**
* Ensures that an object reference passed as a parameter to the calling method is not null.
*
* @param reference an object reference
* @return the non-null reference that was validated
* @throws NullPointerException if {@code reference} is null
*/
public static <T extends @NonNull Object> T checkNotNull(T reference) {
if (reference == null) {
throw new NullPointerException();
}
return reference;
}
} }

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

@ -0,0 +1,63 @@
package com.alibaba.excel.util;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Map utils
*
* @author Jiaju Zhuang
**/
public class MapUtils {
private MapUtils() {}
/**
* Creates a <i>mutable</i>, empty {@code HashMap} instance.
*
* <p><b>Note:</b> if mutability is not required, use {@link ImmutableMap#of()} instead.
*
* <p><b>Note:</b> if {@code K} is an {@code enum} type, use {@link #newEnumMap} instead.
*
* <p><b>Note for Java 7 and later:</b> this method is now unnecessary and should be treated as
* deprecated. Instead, use the {@code HashMap} constructor directly, taking advantage of the new
* <a href="http://goo.gl/iz2Wi">"diamond" syntax</a>.
*
* @return a new, empty {@code HashMap}
*/
public static <K, V> HashMap<K, V> newHashMap() {
return new HashMap<>();
}
/**
* Creates a {@code HashMap} instance, with a high enough "initial capacity" that it <i>should</i>
* hold {@code expectedSize} elements without growth. This behavior cannot be broadly guaranteed,
* but it is observed to be true for OpenJDK 1.7. It also can't be guaranteed that the method
* isn't inadvertently <i>oversizing</i> the returned map.
*
* @param expectedSize the number of entries you expect to add to the returned map
* @return a new, empty {@code HashMap} with enough capacity to hold {@code expectedSize} entries
* without resizing
* @throws IllegalArgumentException if {@code expectedSize} is negative
*/
public static <K, V> HashMap<K, V> newHashMapWithExpectedSize(int expectedSize) {
return new HashMap<>(capacity(expectedSize));
}
/**
* Returns a capacity that is sufficient to keep the map from being resized as long as it grows no
* larger than expectedSize and the load factor is its default (0.75).
*/
static int capacity(int expectedSize) {
if (expectedSize < 3) {
return expectedSize + 1;
}
if (expectedSize < IntUtils.MAX_POWER_OF_TWO) {
// This is the calculation used in JDK8 to resize when a putAll
// happens; it seems to be the most conservative calculation we
// can make. 0.75 is the default load factor.
return (int) ((float) expectedSize / 0.75F + 1.0F);
}
return Integer.MAX_VALUE;
}
}

2
src/main/java/com/alibaba/excel/util/NumberDataFormatterUtils.java

@ -24,7 +24,7 @@ public class NumberDataFormatterUtils {
* @param globalConfiguration * @param globalConfiguration
* @return * @return
*/ */
public static String format(Double data, Integer dataFormat, String dataFormatString, public static String format(Double data, Short dataFormat, String dataFormatString,
GlobalConfiguration globalConfiguration) { GlobalConfiguration globalConfiguration) {
DataFormatter dataFormatter = DATA_FORMATTER_THREAD_LOCAL.get(); DataFormatter dataFormatter = DATA_FORMATTER_THREAD_LOCAL.get();
if (dataFormatter == null) { if (dataFormatter == null) {

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

@ -7,6 +7,7 @@ import java.text.ParseException;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.write.metadata.holder.WriteHolder;
/** /**
* Number utils * Number utils
@ -46,8 +47,27 @@ public class NumberUtils {
* @param contentProperty * @param contentProperty
* @return * @return
*/ */
public static CellData formatToCellData(Number num, ExcelContentProperty contentProperty) { public static CellData<?> formatToCellDataString(Number num, ExcelContentProperty contentProperty) {
return new CellData(format(num, contentProperty)); return new CellData<>(format(num, contentProperty));
}
/**
* format
*
* @param num
* @param contentProperty
* @param currentWriteHolder
* @return
*/
public static CellData<?> formatToCellData(Number num, ExcelContentProperty contentProperty,
WriteHolder currentWriteHolder) {
CellData<?> cellData = new CellData<>(BigDecimal.valueOf(num.doubleValue()));
if (contentProperty != null && contentProperty.getNumberFormatProperty() != null
&& StringUtils.isNotBlank(contentProperty.getNumberFormatProperty().getFormat())) {
WorkBookUtil.fillDataFormat(cellData, currentWriteHolder,
contentProperty.getNumberFormatProperty().getFormat());
}
return cellData;
} }
/** /**

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

@ -2,6 +2,13 @@ package com.alibaba.excel.util;
import java.io.IOException; import java.io.IOException;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.holder.WriteHolder;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey; import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;
import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.poifs.filesystem.POIFSFileSystem;
@ -13,16 +20,12 @@ import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
/** /**
*
* @author jipengfei * @author jipengfei
*/ */
public class WorkBookUtil { public class WorkBookUtil {
private static final int ROW_ACCESS_WINDOW_SIZE = 500; public static final int ROW_ACCESS_WINDOW_SIZE = 500;
private WorkBookUtil() {} private WorkBookUtil() {}
@ -91,4 +94,16 @@ public class WorkBookUtil {
cell.setCellValue(cellValue); cell.setCellValue(cellValue);
return cell; return cell;
} }
public static void fillDataFormat(CellData<?> cellData, WriteHolder currentWriteHolder, String format) {
WriteWorkbookHolder writeWorkbookHolder;
if (currentWriteHolder instanceof WriteSheetHolder) {
writeWorkbookHolder = ((WriteSheetHolder)currentWriteHolder).getParentWriteWorkbookHolder();
} else {
writeWorkbookHolder = ((WriteTableHolder)currentWriteHolder).getParentWriteSheetHolder()
.getParentWriteWorkbookHolder();
}
cellData.setDataFormat(writeWorkbookHolder.getDataFormat(format));
cellData.setDataFormatString(format);
}
} }

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

@ -157,14 +157,14 @@ public class WriteHandlerUtils {
public static void afterCellDispose(WriteContext writeContext, CellData cellData, Cell cell, Head head, public static void afterCellDispose(WriteContext writeContext, CellData cellData, Cell cell, Head head,
Integer relativeRowIndex, Boolean isHead) { Integer relativeRowIndex, Boolean isHead) {
List<CellData> cellDataList = new ArrayList<CellData>(); List<CellData<?>> cellDataList = new ArrayList<>();
if (cell != null) { if (cell != null) {
cellDataList.add(cellData); cellDataList.add(cellData);
} }
afterCellDispose(writeContext, cellDataList, cell, head, relativeRowIndex, isHead); afterCellDispose(writeContext, cellDataList, cell, head, relativeRowIndex, isHead);
} }
public static void afterCellDispose(WriteContext writeContext, List<CellData> cellDataList, Cell cell, Head head, public static void afterCellDispose(WriteContext writeContext, List<CellData<?>> cellDataList, Cell cell, Head head,
Integer relativeRowIndex, Boolean isHead) { Integer relativeRowIndex, Boolean isHead) {
List<WriteHandler> handlerList = List<WriteHandler> handlerList =
writeContext.currentWriteHolder().writeHandlerMap().get(CellWriteHandler.class); writeContext.currentWriteHolder().writeHandlerMap().get(CellWriteHandler.class);

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

@ -1,12 +1,5 @@
package com.alibaba.excel.write.executor; package com.alibaba.excel.write.executor;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.Drawing;
import org.apache.poi.ss.usermodel.Sheet;
import com.alibaba.excel.context.WriteContext; import com.alibaba.excel.context.WriteContext;
import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.converters.ConverterKeyBuild; import com.alibaba.excel.converters.ConverterKeyBuild;
@ -18,6 +11,13 @@ import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.util.WriteHandlerUtils; import com.alibaba.excel.util.WriteHandlerUtils;
import com.alibaba.excel.write.metadata.holder.WriteHolder; import com.alibaba.excel.write.metadata.holder.WriteHolder;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.Drawing;
import org.apache.poi.ss.usermodel.Sheet;
/** /**
* Excel write Executor * Excel write Executor
* *
@ -56,6 +56,9 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor {
case NUMBER: case NUMBER:
cell.setCellValue(cellData.getNumberValue().doubleValue()); cell.setCellValue(cellData.getNumberValue().doubleValue());
return cellData; return cellData;
case DATE:
cell.setCellValue(cellData.getDateValue());
return cellData;
case IMAGE: case IMAGE:
setImageValue(cellData, cell); setImageValue(cellData, cell);
return cellData; return cellData;
@ -113,7 +116,7 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor {
CellData cellData; CellData cellData;
try { try {
cellData = cellData =
converter.convertToExcelData(value, excelContentProperty, currentWriteHolder.globalConfiguration()); converter.convertToExcelData(value, excelContentProperty, currentWriteHolder);
} catch (Exception e) { } catch (Exception e) {
throw new ExcelDataConvertException(cell.getRow().getRowNum(), cell.getColumnIndex(), throw new ExcelDataConvertException(cell.getRow().getRowNum(), cell.getColumnIndex(),
new CellData(CellDataTypeEnum.EMPTY), excelContentProperty, new CellData(CellDataTypeEnum.EMPTY), excelContentProperty,

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

@ -204,7 +204,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
} else { } else {
StringBuilder cellValueBuild = new StringBuilder(); StringBuilder cellValueBuild = new StringBuilder();
int index = 0; int index = 0;
List<CellData> cellDataList = new ArrayList<CellData>(); List<CellData<?>> cellDataList = new ArrayList<>();
for (String variable : analysisCell.getVariableList()) { for (String variable : analysisCell.getVariableList()) {
cellValueBuild.append(analysisCell.getPrepareDataList().get(index++)); cellValueBuild.append(analysisCell.getPrepareDataList().get(index++));
if (!dataMap.containsKey(variable)) { if (!dataMap.containsKey(variable)) {

2
src/main/java/com/alibaba/excel/write/handler/AbstractCellWriteHandler.java

@ -39,7 +39,7 @@ public abstract class AbstractCellWriteHandler implements CellWriteHandler {
@Override @Override
public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
List<CellData> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { List<CellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
} }
} }

4
src/main/java/com/alibaba/excel/write/handler/CellWriteHandler.java

@ -56,7 +56,7 @@ public interface CellWriteHandler extends WriteHandler {
* @param isHead It will always be false when fill data. * @param isHead It will always be false when fill data.
*/ */
default void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, default void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
CellData cellData, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {} CellData<?> cellData, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {}
/** /**
* Called after all operations on the cell have been completed * Called after all operations on the cell have been completed
@ -70,5 +70,5 @@ public interface CellWriteHandler extends WriteHandler {
* @param isHead It will always be false when fill data. * @param isHead It will always be false when fill data.
*/ */
default void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, default void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
List<CellData> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {} List<CellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {}
} }

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

@ -5,6 +5,7 @@ import java.util.List;
import com.alibaba.excel.write.handler.impl.DefaultRowWriteHandler; import com.alibaba.excel.write.handler.impl.DefaultRowWriteHandler;
import com.alibaba.excel.write.handler.impl.DimensionWorkbookWriteHandler; import com.alibaba.excel.write.handler.impl.DimensionWorkbookWriteHandler;
import com.alibaba.excel.write.handler.impl.FillDataFormatCellWriteHandler;
import com.alibaba.excel.write.metadata.style.WriteCellStyle; import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont; import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy; import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
@ -43,6 +44,7 @@ public class DefaultWriteHandlerLoader {
handlerList.add(new HorizontalCellStyleStrategy(headWriteCellStyle, new ArrayList<>())); handlerList.add(new HorizontalCellStyleStrategy(headWriteCellStyle, new ArrayList<>()));
} }
handlerList.addAll(DEFAULT_WRITE_HANDLER_LIST); handlerList.addAll(DEFAULT_WRITE_HANDLER_LIST);
handlerList.add(new FillDataFormatCellWriteHandler());
return handlerList; return handlerList;
} }

75
src/main/java/com/alibaba/excel/write/handler/impl/FillDataFormatCellWriteHandler.java

@ -0,0 +1,75 @@
package com.alibaba.excel.write.handler.impl;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.alibaba.excel.constant.OrderConstant;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.event.Order;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.util.DateUtils;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.DataFormat;
import org.apache.poi.ss.usermodel.Workbook;
/**
* fill cell style.
*
* @author Jiaju Zhuang
*/
@Slf4j
public class FillDataFormatCellWriteHandler implements CellWriteHandler, Order {
private final Set<CellStyle> cellStyleSet = new HashSet<>();
private CellStyle defaultDateCellStyle;
@Override
public int order() {
return OrderConstant.FILL_DATA_FORMAT;
}
@Override
public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
List<CellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
if (CollectionUtils.isEmpty(cellDataList) || cellDataList.size() > 1) {
return;
}
CellData<?> cellData = cellDataList.get(0);
CellStyle cellStyle = cell.getCellStyle();
if (cellStyle == null) {
if (cellData.getType() == CellDataTypeEnum.DATE) {
cell.setCellStyle(getDefaultDateCellStyle(writeSheetHolder));
}
return;
}
if (cellStyleSet.contains(cellStyle)) {
return;
}
if (cellData.getDataFormat() != null && cellData.getDataFormat() >= 0) {
cellStyle.setDataFormat(cellData.getDataFormat());
}
cellStyleSet.add(cellStyle);
}
private CellStyle getDefaultDateCellStyle(WriteSheetHolder writeSheetHolder) {
if (defaultDateCellStyle != null) {
return defaultDateCellStyle;
}
Workbook workbook = writeSheetHolder.getParentWriteWorkbookHolder().getWorkbook();
defaultDateCellStyle = workbook.createCellStyle();
DataFormat dataFormat = workbook.createDataFormat();
defaultDateCellStyle.setDataFormat(dataFormat.getFormat(DateUtils.defaultDateFormat));
return defaultDateCellStyle;
}
}

25
src/main/java/com/alibaba/excel/write/merge/AbstractMergeStrategy.java

@ -2,42 +2,25 @@ package com.alibaba.excel.write.merge;
import java.util.List; import java.util.List;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.handler.CellWriteHandler; import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder; import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Sheet;
/** /**
* Merge strategy * Merge strategy
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
public abstract class AbstractMergeStrategy implements CellWriteHandler { public abstract class AbstractMergeStrategy implements CellWriteHandler {
@Override
public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row,
Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {
}
@Override
public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell,
Head head, Integer relativeRowIndex, Boolean isHead) {}
@Override
public void afterCellDataConverted(WriteSheetHolder writeSheetHolder,
WriteTableHolder writeTableHolder, CellData cellData, Cell cell, Head head, Integer relativeRowIndex,
Boolean isHead) {
}
@Override @Override
public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
List<CellData> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { List<CellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
if (isHead) { if (isHead) {
return; return;
} }

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

@ -207,7 +207,7 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ
if (parentAbstractWriteHolder == null) { if (parentAbstractWriteHolder == null) {
setConverterMap(DefaultConverterLoader.loadDefaultWriteConverter()); setConverterMap(DefaultConverterLoader.loadDefaultWriteConverter());
} else { } else {
setConverterMap(new HashMap<String, Converter>(parentAbstractWriteHolder.getConverterMap())); setConverterMap(new HashMap<>(parentAbstractWriteHolder.getConverterMap()));
} }
if (writeBasicParameter.getCustomConverterList() != null if (writeBasicParameter.getCustomConverterList() != null
&& !writeBasicParameter.getCustomConverterList().isEmpty()) { && !writeBasicParameter.getCustomConverterList().isEmpty()) {

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

@ -10,23 +10,30 @@ import java.io.OutputStream;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import com.alibaba.excel.enums.HolderEnum; import com.alibaba.excel.enums.HolderEnum;
import com.alibaba.excel.exception.ExcelGenerateException; import com.alibaba.excel.exception.ExcelGenerateException;
import com.alibaba.excel.support.ExcelTypeEnum; import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.util.FileUtils; import com.alibaba.excel.util.FileUtils;
import com.alibaba.excel.util.IoUtils; import com.alibaba.excel.util.IoUtils;
import com.alibaba.excel.util.MapUtils;
import com.alibaba.excel.util.StringUtils;
import com.alibaba.excel.write.metadata.WriteWorkbook; import com.alibaba.excel.write.metadata.WriteWorkbook;
import lombok.Getter;
import lombok.Setter;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.DataFormat;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
/** /**
* Workbook holder * Workbook holder
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Getter
@Setter
public class WriteWorkbookHolder extends AbstractWriteHolder { public class WriteWorkbookHolder extends AbstractWriteHolder {
/*** /***
* Current poi Workbook.This is only for writing, and there may be no data in version 07 when template data needs to * Current poi Workbook.This is only for writing, and there may be no data in version 07 when template data needs to
@ -111,7 +118,10 @@ public class WriteWorkbookHolder extends AbstractWriteHolder {
* Excel is also written in the event of an exception being thrown.The default false. * Excel is also written in the event of an exception being thrown.The default false.
*/ */
private Boolean writeExcelOnException; private Boolean writeExcelOnException;
/**
* Used to cache data Format.
*/
private Map<String, Short> dataFormatCache;
public WriteWorkbookHolder(WriteWorkbook writeWorkbook) { public WriteWorkbookHolder(WriteWorkbook writeWorkbook) {
super(writeWorkbook, null, writeWorkbook.getConvertAllFiled()); super(writeWorkbook, null, writeWorkbook.getConvertAllFiled());
@ -166,6 +176,7 @@ public class WriteWorkbookHolder extends AbstractWriteHolder {
} else { } else {
this.writeExcelOnException = writeWorkbook.getWriteExcelOnException(); this.writeExcelOnException = writeWorkbook.getWriteExcelOnException();
} }
this.dataFormatCache = MapUtils.newHashMap();
} }
private void copyTemplate() throws IOException { private void copyTemplate() throws IOException {
@ -187,136 +198,29 @@ public class WriteWorkbookHolder extends AbstractWriteHolder {
this.tempTemplateInputStream = new ByteArrayInputStream(templateFileByte); this.tempTemplateInputStream = new ByteArrayInputStream(templateFileByte);
} }
public Workbook getWorkbook() { @Override
return workbook; public HolderEnum holderType() {
} return HolderEnum.WORKBOOK;
public void setWorkbook(Workbook workbook) {
this.workbook = workbook;
}
public Workbook getCachedWorkbook() {
return cachedWorkbook;
}
public void setCachedWorkbook(Workbook cachedWorkbook) {
this.cachedWorkbook = cachedWorkbook;
}
public Map<Integer, WriteSheetHolder> getHasBeenInitializedSheetIndexMap() {
return hasBeenInitializedSheetIndexMap;
}
public void setHasBeenInitializedSheetIndexMap(Map<Integer, WriteSheetHolder> hasBeenInitializedSheetIndexMap) {
this.hasBeenInitializedSheetIndexMap = hasBeenInitializedSheetIndexMap;
}
public Map<String, WriteSheetHolder> getHasBeenInitializedSheetNameMap() {
return hasBeenInitializedSheetNameMap;
}
public void setHasBeenInitializedSheetNameMap(Map<String, WriteSheetHolder> hasBeenInitializedSheetNameMap) {
this.hasBeenInitializedSheetNameMap = hasBeenInitializedSheetNameMap;
}
public WriteWorkbook getWriteWorkbook() {
return writeWorkbook;
}
public void setWriteWorkbook(WriteWorkbook writeWorkbook) {
this.writeWorkbook = writeWorkbook;
}
public File getFile() {
return file;
}
public void setFile(File file) {
this.file = file;
}
public OutputStream getOutputStream() {
return outputStream;
}
public void setOutputStream(OutputStream outputStream) {
this.outputStream = outputStream;
}
public InputStream getTemplateInputStream() {
return templateInputStream;
}
public void setTemplateInputStream(InputStream templateInputStream) {
this.templateInputStream = templateInputStream;
}
public InputStream getTempTemplateInputStream() {
return tempTemplateInputStream;
}
public void setTempTemplateInputStream(InputStream tempTemplateInputStream) {
this.tempTemplateInputStream = tempTemplateInputStream;
}
public File getTemplateFile() {
return templateFile;
}
public void setTemplateFile(File templateFile) {
this.templateFile = templateFile;
}
public Boolean getAutoCloseStream() {
return autoCloseStream;
}
public void setAutoCloseStream(Boolean autoCloseStream) {
this.autoCloseStream = autoCloseStream;
}
public ExcelTypeEnum getExcelType() {
return excelType;
}
public void setExcelType(ExcelTypeEnum excelType) {
this.excelType = excelType;
}
public Boolean getMandatoryUseInputStream() {
return mandatoryUseInputStream;
}
public void setMandatoryUseInputStream(Boolean mandatoryUseInputStream) {
this.mandatoryUseInputStream = mandatoryUseInputStream;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Boolean getInMemory() {
return inMemory;
} }
public void setInMemory(Boolean inMemory) { /**
this.inMemory = inMemory; * Get a data format.
*
* @param format
* @return
*/
public Short getDataFormat(String format) {
if (StringUtils.isEmpty(format)) {
return 0;
} }
Short dataFormat = dataFormatCache.get(format);
public Boolean getWriteExcelOnException() { if (dataFormat != null) {
return writeExcelOnException; return dataFormat;
} }
DataFormat dataFormatCreate = workbook.createDataFormat();
public void setWriteExcelOnException(Boolean writeExcelOnException) { dataFormat = dataFormatCreate.getFormat(format);
this.writeExcelOnException = writeExcelOnException; dataFormatCache.put(format,dataFormat);
return dataFormat;
} }
@Override
public HolderEnum holderType() {
return HolderEnum.WORKBOOK;
}
} }

38
src/main/java/com/alibaba/excel/write/style/AbstractCellStyleStrategy.java

@ -2,20 +2,18 @@ package com.alibaba.excel.write.style;
import java.util.List; import java.util.List;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Workbook;
import com.alibaba.excel.event.NotRepeatExecutor; import com.alibaba.excel.event.NotRepeatExecutor;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.handler.CellWriteHandler; import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.handler.WorkbookWriteHandler; import com.alibaba.excel.write.handler.WorkbookWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder; import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Workbook;
/** /**
* Cell style strategy * Cell style strategy
* *
@ -30,27 +28,9 @@ public abstract class AbstractCellStyleStrategy implements CellWriteHandler, Wor
return "CellStyleStrategy"; return "CellStyleStrategy";
} }
@Override
public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row,
Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {
}
@Override
public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell,
Head head, Integer relativeRowIndex, Boolean isHead) {
}
@Override
public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
CellData cellData, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
}
@Override @Override
public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
List<CellData> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { List<CellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
if (isHead == null) { if (isHead == null) {
return; return;
} }
@ -61,22 +41,12 @@ public abstract class AbstractCellStyleStrategy implements CellWriteHandler, Wor
} }
} }
@Override
public void beforeWorkbookCreate() {
}
@Override @Override
public void afterWorkbookCreate(WriteWorkbookHolder writeWorkbookHolder) { public void afterWorkbookCreate(WriteWorkbookHolder writeWorkbookHolder) {
initCellStyle(writeWorkbookHolder.getWorkbook()); initCellStyle(writeWorkbookHolder.getWorkbook());
hasInitialized = true; hasInitialized = true;
} }
@Override
public void afterWorkbookDispose(WriteWorkbookHolder writeWorkbookHolder) {
}
/** /**
* Initialization cell style * Initialization cell style
* *

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

@ -3,14 +3,14 @@ package com.alibaba.excel.write.style;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Workbook;
import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.util.StyleUtil; import com.alibaba.excel.util.StyleUtil;
import com.alibaba.excel.write.metadata.style.WriteCellStyle; import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Workbook;
/** /**
* Use the same style for the column * Use the same style for the column
* *
@ -63,7 +63,7 @@ public abstract class AbstractVerticalCellStyleStrategy extends AbstractCellStyl
} }
return; return;
} }
WriteCellStyle contentCellStyle = contentCellStyle(head); WriteCellStyle contentCellStyle = contentCellStyle(cell, head, relativeRowIndex);
if (contentCellStyle == null) { if (contentCellStyle == null) {
contentCellStyleCache.put(columnIndex, null); contentCellStyleCache.put(columnIndex, null);
} else { } else {
@ -73,6 +73,18 @@ public abstract class AbstractVerticalCellStyleStrategy extends AbstractCellStyl
} }
} }
/**
* Returns the column width corresponding to each column head.
*
* @param cell
* @param head
* @param relativeRowIndex
* @return
*/
protected WriteCellStyle contentCellStyle(Cell cell, Head head, Integer relativeRowIndex) {
return contentCellStyle(head);
}
/** /**
* Returns the column width corresponding to each column head * Returns the column width corresponding to each column head
* *
@ -87,6 +99,10 @@ public abstract class AbstractVerticalCellStyleStrategy extends AbstractCellStyl
* @param head Nullable * @param head Nullable
* @return * @return
*/ */
protected abstract WriteCellStyle contentCellStyle(Head head); 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.");
}
} }

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

@ -1,29 +1,23 @@
package com.alibaba.excel.write.style; package com.alibaba.excel.write.style;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Workbook;
import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.util.StyleUtil; import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.write.metadata.style.WriteCellStyle; import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.ss.usermodel.Cell;
/** /**
*
* Use the same style for the row * Use the same style for the row
* *
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
public class HorizontalCellStyleStrategy extends AbstractCellStyleStrategy { public class HorizontalCellStyleStrategy extends AbstractVerticalCellStyleStrategy {
private WriteCellStyle headWriteCellStyle;
private List<WriteCellStyle> contentWriteCellStyleList;
private CellStyle headCellStyle; private final WriteCellStyle headWriteCellStyle;
private List<CellStyle> contentCellStyleList; private final List<WriteCellStyle> contentWriteCellStyleList;
public HorizontalCellStyleStrategy(WriteCellStyle headWriteCellStyle, public HorizontalCellStyleStrategy(WriteCellStyle headWriteCellStyle,
List<WriteCellStyle> contentWriteCellStyleList) { List<WriteCellStyle> contentWriteCellStyleList) {
@ -33,37 +27,21 @@ public class HorizontalCellStyleStrategy extends AbstractCellStyleStrategy {
public HorizontalCellStyleStrategy(WriteCellStyle headWriteCellStyle, WriteCellStyle contentWriteCellStyle) { public HorizontalCellStyleStrategy(WriteCellStyle headWriteCellStyle, WriteCellStyle contentWriteCellStyle) {
this.headWriteCellStyle = headWriteCellStyle; this.headWriteCellStyle = headWriteCellStyle;
contentWriteCellStyleList = new ArrayList<WriteCellStyle>(); contentWriteCellStyleList = ListUtils.newArrayList();
contentWriteCellStyleList.add(contentWriteCellStyle); contentWriteCellStyleList.add(contentWriteCellStyle);
} }
@Override @Override
protected void initCellStyle(Workbook workbook) { protected WriteCellStyle headCellStyle(Head head) {
if (headWriteCellStyle != null) { return headWriteCellStyle;
headCellStyle = StyleUtil.buildHeadCellStyle(workbook, headWriteCellStyle);
}
if (contentWriteCellStyleList != null && !contentWriteCellStyleList.isEmpty()) {
contentCellStyleList = new ArrayList<CellStyle>();
for (WriteCellStyle writeCellStyle : contentWriteCellStyleList) {
contentCellStyleList.add(StyleUtil.buildContentCellStyle(workbook, writeCellStyle));
}
}
}
@Override
protected void setHeadCellStyle(Cell cell, Head head, Integer relativeRowIndex) {
if (headCellStyle == null) {
return;
}
cell.setCellStyle(headCellStyle);
} }
@Override @Override
protected void setContentCellStyle(Cell cell, Head head, Integer relativeRowIndex) { protected WriteCellStyle contentCellStyle(Cell cell, Head head, Integer relativeRowIndex) {
if (contentCellStyleList == null || contentCellStyleList.isEmpty()) { if (CollectionUtils.isEmpty(contentWriteCellStyleList)) {
return; return null;
} }
cell.setCellStyle(contentCellStyleList.get(relativeRowIndex % contentCellStyleList.size())); return contentWriteCellStyleList.get(relativeRowIndex % contentWriteCellStyleList.size());
} }
} }

4
src/main/java/com/alibaba/excel/write/style/column/AbstractColumnWidthStyleStrategy.java

@ -26,7 +26,7 @@ public abstract class AbstractColumnWidthStyleStrategy implements CellWriteHandl
@Override @Override
public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
List<CellData> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { List<CellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
setColumnWidth(writeSheetHolder, cellDataList, cell, head, relativeRowIndex, isHead); setColumnWidth(writeSheetHolder, cellDataList, cell, head, relativeRowIndex, isHead);
} }
@ -40,7 +40,7 @@ public abstract class AbstractColumnWidthStyleStrategy implements CellWriteHandl
* @param relativeRowIndex * @param relativeRowIndex
* @param isHead * @param isHead
*/ */
protected abstract void setColumnWidth(WriteSheetHolder writeSheetHolder, List<CellData> cellDataList, Cell cell, protected abstract void setColumnWidth(WriteSheetHolder writeSheetHolder, List<CellData<?>> cellDataList, Cell cell,
Head head, Integer relativeRowIndex, Boolean isHead); Head head, Integer relativeRowIndex, Boolean isHead);
} }

2
src/main/java/com/alibaba/excel/write/style/column/AbstractHeadColumnWidthStyleStrategy.java

@ -16,7 +16,7 @@ import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
public abstract class AbstractHeadColumnWidthStyleStrategy extends AbstractColumnWidthStyleStrategy { public abstract class AbstractHeadColumnWidthStyleStrategy extends AbstractColumnWidthStyleStrategy {
@Override @Override
protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<CellData> cellDataList, Cell cell, Head head, protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<CellData<?>> cellDataList, Cell cell, Head head,
Integer relativeRowIndex, Boolean isHead) { Integer relativeRowIndex, Boolean isHead) {
boolean needSetWidth = relativeRowIndex != null && (isHead || relativeRowIndex == 0); boolean needSetWidth = relativeRowIndex != null && (isHead || relativeRowIndex == 0);
if (!needSetWidth) { if (!needSetWidth) {

4
src/main/java/com/alibaba/excel/write/style/column/LongestMatchColumnWidthStyleStrategy.java

@ -27,7 +27,7 @@ public class LongestMatchColumnWidthStyleStrategy extends AbstractColumnWidthSty
private Map<Integer, Map<Integer, Integer>> cache = new HashMap<Integer, Map<Integer, Integer>>(8); private Map<Integer, Map<Integer, Integer>> cache = new HashMap<Integer, Map<Integer, Integer>>(8);
@Override @Override
protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<CellData> cellDataList, Cell cell, Head head, protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<CellData<?>> cellDataList, Cell cell, Head head,
Integer relativeRowIndex, Boolean isHead) { Integer relativeRowIndex, Boolean isHead) {
boolean needSetWidth = isHead || !CollectionUtils.isEmpty(cellDataList); boolean needSetWidth = isHead || !CollectionUtils.isEmpty(cellDataList);
if (!needSetWidth) { if (!needSetWidth) {
@ -52,7 +52,7 @@ public class LongestMatchColumnWidthStyleStrategy extends AbstractColumnWidthSty
} }
} }
private Integer dataLength(List<CellData> cellDataList, Cell cell, Boolean isHead) { private Integer dataLength(List<CellData<?>> cellDataList, Cell cell, Boolean isHead) {
if (isHead) { if (isHead) {
return cell.getStringCellValue().getBytes().length; return cell.getStringCellValue().getBytes().length;
} }

2
src/test/java/com/alibaba/easyexcel/test/core/handler/WriteHandler.java

@ -98,7 +98,7 @@ public class WriteHandler implements WorkbookWriteHandler, SheetWriteHandler, Ro
@Override @Override
public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
List<CellData> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { List<CellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
if (isHead) { if (isHead) {
Assert.assertEquals(1L, beforeCellCreate); Assert.assertEquals(1L, beforeCellCreate);
Assert.assertEquals(1L, afterCellCreate); Assert.assertEquals(1L, afterCellCreate);

2
src/test/java/com/alibaba/easyexcel/test/demo/write/CustomCellWriteHandler.java

@ -27,7 +27,7 @@ public class CustomCellWriteHandler implements CellWriteHandler {
@Override @Override
public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
List<CellData> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { List<CellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
// 这里可以对cell进行任何操作 // 这里可以对cell进行任何操作
LOGGER.info("第{}行,第{}列写入完成。", cell.getRowIndex(), cell.getColumnIndex()); LOGGER.info("第{}行,第{}列写入完成。", cell.getRowIndex(), cell.getColumnIndex());
if (isHead && cell.getColumnIndex() == 0) { if (isHead && cell.getColumnIndex() == 0) {

4
src/test/java/com/alibaba/easyexcel/test/temp/dataformat/DataFormatTest.java

@ -44,7 +44,7 @@ public class DataFormatTest {
EasyExcel.read(file, DataFormatData.class, null).sheet().headRowNumber(0).doReadSync(); EasyExcel.read(file, DataFormatData.class, null).sheet().headRowNumber(0).doReadSync();
LOGGER.info("数据:{}", list.size()); LOGGER.info("数据:{}", list.size());
for (DataFormatData data : list) { for (DataFormatData data : list) {
Integer dataFormat = data.getDate().getDataFormat(); Short dataFormat = data.getDate().getDataFormat();
String dataFormatString = data.getDate().getDataFormatString(); String dataFormatString = data.getDate().getDataFormatString();
@ -67,7 +67,7 @@ public class DataFormatTest {
EasyExcel.read(file, DataFormatData.class, null).sheet().headRowNumber(0).doReadSync(); EasyExcel.read(file, DataFormatData.class, null).sheet().headRowNumber(0).doReadSync();
LOGGER.info("数据:{}", list.size()); LOGGER.info("数据:{}", list.size());
for (DataFormatData data : list) { for (DataFormatData data : list) {
Integer dataFormat = data.getDate().getDataFormat(); Short dataFormat = data.getDate().getDataFormat();
String dataFormatString = data.getDate().getDataFormatString(); String dataFormatString = data.getDate().getDataFormatString();

Loading…
Cancel
Save