diff --git a/src/main/java/com/alibaba/excel/analysis/v03/handlers/FormulaRecordHandler.java b/src/main/java/com/alibaba/excel/analysis/v03/handlers/FormulaRecordHandler.java index f78d4102..5f18b841 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/handlers/FormulaRecordHandler.java +++ b/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.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.constant.BuiltinFormats; 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.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 * @@ -32,7 +31,7 @@ public class FormulaRecordHandler extends AbstractXlsRecordHandler implements Ig public void processRecord(XlsReadContext xlsReadContext, Record record) { FormulaRecord frec = (FormulaRecord)record; Map cellMap = xlsReadContext.xlsReadSheetHolder().getCellMap(); - CellData tempCellData = new CellData(); + CellData tempCellData = new CellData<>(); tempCellData.setRowIndex(frec.getRow()); tempCellData.setColumnIndex((int)frec.getColumn()); CellType cellType = CellType.forInt(frec.getCachedResultType()); @@ -58,8 +57,9 @@ public class FormulaRecordHandler extends AbstractXlsRecordHandler implements Ig tempCellData.setNumberValue(BigDecimal.valueOf(frec.getValue())); Integer dataFormat = xlsReadContext.xlsReadWorkbookHolder().getFormatTrackingHSSFListener().getFormatIndex(frec); - tempCellData.setDataFormat(dataFormat); - tempCellData.setDataFormatString(BuiltinFormats.getBuiltinFormat(dataFormat, + Short dataFormatShort = dataFormat.shortValue(); + tempCellData.setDataFormat(dataFormatShort); + tempCellData.setDataFormatString(BuiltinFormats.getBuiltinFormat(dataFormatShort, xlsReadContext.xlsReadWorkbookHolder().getFormatTrackingHSSFListener().getFormatString(frec), xlsReadContext.readSheetHolder().getGlobalConfiguration().getLocale())); cellMap.put((int)frec.getColumn(), tempCellData); diff --git a/src/main/java/com/alibaba/excel/analysis/v03/handlers/NumberRecordHandler.java b/src/main/java/com/alibaba/excel/analysis/v03/handlers/NumberRecordHandler.java index 50608095..954acd35 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/handlers/NumberRecordHandler.java +++ b/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 org.apache.poi.hssf.record.NumberRecord; -import org.apache.poi.hssf.record.Record; - import com.alibaba.excel.analysis.v03.IgnorableXlsRecordHandler; import com.alibaba.excel.constant.BuiltinFormats; import com.alibaba.excel.context.xls.XlsReadContext; import com.alibaba.excel.enums.RowTypeEnum; import com.alibaba.excel.metadata.CellData; +import org.apache.poi.hssf.record.NumberRecord; +import org.apache.poi.hssf.record.Record; + /** * Record handler * @@ -22,7 +22,8 @@ public class NumberRecordHandler extends AbstractXlsRecordHandler implements Ign public void processRecord(XlsReadContext xlsReadContext, Record record) { NumberRecord nr = (NumberRecord)record; 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.setDataFormatString(BuiltinFormats.getBuiltinFormat(dataFormat, xlsReadContext.xlsReadWorkbookHolder().getFormatTrackingHSSFListener().getFormatString(nr), diff --git a/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java index 1ef54e3f..135153e0 100644 --- a/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java @@ -52,7 +52,7 @@ public class CellTagHandler extends AbstractXlsxTagHandler { return; } XSSFCellStyle xssfCellStyle = stylesTable.getStyleAt(dateFormatIndexInteger); - int dataFormat = xssfCellStyle.getDataFormat(); + short dataFormat = xssfCellStyle.getDataFormat(); xlsxReadSheetHolder.getTempCellData().setDataFormat(dataFormat); xlsxReadSheetHolder.getTempCellData().setDataFormatString(BuiltinFormats.getBuiltinFormat(dataFormat, xssfCellStyle.getDataFormatString(), xlsxReadSheetHolder.getGlobalConfiguration().getLocale())); diff --git a/src/main/java/com/alibaba/excel/constant/BuiltinFormats.java b/src/main/java/com/alibaba/excel/constant/BuiltinFormats.java index 95eb0b8f..b525916a 100644 --- a/src/main/java/com/alibaba/excel/constant/BuiltinFormats.java +++ b/src/main/java/com/alibaba/excel/constant/BuiltinFormats.java @@ -17,7 +17,7 @@ import java.util.Locale; **/ public class BuiltinFormats { - private static final String[] BUILTIN_FORMATS_CN = { + public static final String[] BUILTIN_FORMATS_CN = { // 0 "General", // 1 @@ -189,7 +189,7 @@ public class BuiltinFormats { // end }; - private static final String[] BUILTIN_FORMATS_US = { + public static final String[] BUILTIN_FORMATS_US = { // 0 "General", // 1 @@ -361,7 +361,7 @@ public class BuiltinFormats { // 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); if (index == null || index < 0 || index >= builtinFormat.length) { return defaultFormat; diff --git a/src/main/java/com/alibaba/excel/constant/OrderConstant.java b/src/main/java/com/alibaba/excel/constant/OrderConstant.java new file mode 100644 index 00000000..a955025c --- /dev/null +++ b/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; +} diff --git a/src/main/java/com/alibaba/excel/converters/Converter.java b/src/main/java/com/alibaba/excel/converters/Converter.java index 8700d127..293daf42 100644 --- a/src/main/java/com/alibaba/excel/converters/Converter.java +++ b/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.GlobalConfiguration; 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 * - * @author Dan Zheng * @param + * @author Dan Zheng */ public interface Converter { @@ -18,44 +22,72 @@ public interface Converter { * * @return Support for Java class */ - Class supportJavaTypeKey(); + default Class supportJavaTypeKey() { + throw new UnsupportedOperationException("The current operation is not supported by the current converter."); + } /** * Back to object enum in excel * * @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 * - * @param cellData - * Excel cell data.NotNull. - * @param contentProperty - * Content property.Nullable. - * @param globalConfiguration - * Global configuration.NotNull. + * @param cellData Excel cell data.NotNull. + * @param contentProperty Content property.Nullable. + * @param readSheetHolder .NotNull. * @return Data to put into a Java object - * @throws Exception - * Exception. + * @throws 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, - GlobalConfiguration globalConfiguration) throws Exception; + default CellData convertToExcelData(T value, ExcelContentProperty contentProperty, + GlobalConfiguration globalConfiguration) throws Exception { + throw new UnsupportedOperationException("The current operation is not supported by the current converter."); + } /** * Convert Java objects to excel objects * - * @param value - * Java Data.NotNull. - * @param contentProperty - * Content property.Nullable. - * @param globalConfiguration - * Global configuration.NotNull. + * @param value Java Data.NotNull. + * @param contentProperty Content property.Nullable. + * @param currentWriteHolder He would be {@link WriteSheetHolder} or {@link WriteTableHolder}.NotNull. * @return Data to put into a Excel - * @throws Exception - * Exception. + * @throws Exception Exception. */ - CellData convertToExcelData(T value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) - throws Exception; + default CellData convertToExcelData(T value, ExcelContentProperty contentProperty, + WriteHolder currentWriteHolder) throws Exception { + return convertToExcelData(value, contentProperty, currentWriteHolder.globalConfiguration()); + } } diff --git a/src/main/java/com/alibaba/excel/converters/DefaultConverterLoader.java b/src/main/java/com/alibaba/excel/converters/DefaultConverterLoader.java index 01822559..09fb9d91 100644 --- a/src/main/java/com/alibaba/excel/converters/DefaultConverterLoader.java +++ b/src/main/java/com/alibaba/excel/converters/DefaultConverterLoader.java @@ -1,6 +1,5 @@ package com.alibaba.excel.converters; -import java.util.HashMap; import java.util.Map; 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.ByteNumberConverter; 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.DateStringConverter; 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.StringStringConverter; import com.alibaba.excel.converters.url.UrlImageConverter; +import com.alibaba.excel.util.MapUtils; /** * Load default handler @@ -45,8 +46,8 @@ import com.alibaba.excel.converters.url.UrlImageConverter; * @author Jiaju Zhuang */ public class DefaultConverterLoader { - private static Map defaultWriteConverter; - private static Map allConverter; + private static Map> defaultWriteConverter; + private static Map> allConverter; static { initDefaultWriteConverter(); @@ -54,7 +55,7 @@ public class DefaultConverterLoader { } private static void initAllConverter() { - allConverter = new HashMap(64); + allConverter = MapUtils.newHashMapWithExpectedSize(40); putAllConverter(new BigDecimalBooleanConverter()); putAllConverter(new BigDecimalNumberConverter()); putAllConverter(new BigDecimalStringConverter()); @@ -97,11 +98,11 @@ public class DefaultConverterLoader { } private static void initDefaultWriteConverter() { - defaultWriteConverter = new HashMap(32); + defaultWriteConverter = MapUtils.newHashMapWithExpectedSize(20); putWriteConverter(new BigDecimalNumberConverter()); putWriteConverter(new BooleanBooleanConverter()); putWriteConverter(new ByteNumberConverter()); - putWriteConverter(new DateStringConverter()); + putWriteConverter(new DateDateConverter()); putWriteConverter(new DoubleNumberConverter()); putWriteConverter(new FloatNumberConverter()); putWriteConverter(new IntegerNumberConverter()); @@ -120,11 +121,11 @@ public class DefaultConverterLoader { * * @return */ - public static Map loadDefaultWriteConverter() { + public static Map> loadDefaultWriteConverter() { return defaultWriteConverter; } - private static void putWriteConverter(Converter converter) { + private static void putWriteConverter(Converter converter) { defaultWriteConverter.put(ConverterKeyBuild.buildKey(converter.supportJavaTypeKey()), converter); } @@ -133,7 +134,7 @@ public class DefaultConverterLoader { * * @return */ - public static Map loadDefaultReadConverter() { + public static Map> loadDefaultReadConverter() { return loadAllConverter(); } @@ -142,11 +143,11 @@ public class DefaultConverterLoader { * * @return */ - public static Map loadAllConverter() { + public static Map> loadAllConverter() { return allConverter; } - private static void putAllConverter(Converter converter) { + private static void putAllConverter(Converter converter) { allConverter.put(ConverterKeyBuild.buildKey(converter.supportJavaTypeKey(), converter.supportExcelTypeKey()), converter); } diff --git a/src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalNumberConverter.java b/src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalNumberConverter.java index bf9b735f..402490c7 100644 --- a/src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalNumberConverter.java +++ b/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.GlobalConfiguration; 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 @@ -32,8 +34,8 @@ public class BigDecimalNumberConverter implements Converter { } @Override - public CellData convertToExcelData(BigDecimal value, ExcelContentProperty contentProperty, - GlobalConfiguration globalConfiguration) { - return new CellData(value); + public CellData convertToExcelData(BigDecimal value, ExcelContentProperty contentProperty, + WriteHolder currentWriteHolder) { + return NumberUtils.formatToCellData(value, contentProperty, currentWriteHolder); } } diff --git a/src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalStringConverter.java b/src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalStringConverter.java index 8c5f0f48..c6bd3eae 100644 --- a/src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalStringConverter.java +++ b/src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalStringConverter.java @@ -36,6 +36,6 @@ public class BigDecimalStringConverter implements Converter { @Override public CellData convertToExcelData(BigDecimal value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return NumberUtils.formatToCellData(value, contentProperty); + return NumberUtils.formatToCellDataString(value, contentProperty); } } diff --git a/src/main/java/com/alibaba/excel/converters/byteconverter/ByteNumberConverter.java b/src/main/java/com/alibaba/excel/converters/byteconverter/ByteNumberConverter.java index f1facdfb..63a3598a 100644 --- a/src/main/java/com/alibaba/excel/converters/byteconverter/ByteNumberConverter.java +++ b/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.GlobalConfiguration; 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 @@ -32,9 +34,9 @@ public class ByteNumberConverter implements Converter { } @Override - public CellData convertToExcelData(Byte value, ExcelContentProperty contentProperty, - GlobalConfiguration globalConfiguration) { - return new CellData(new BigDecimal(Byte.toString(value))); + public CellData convertToExcelData(Byte value, ExcelContentProperty contentProperty, + WriteHolder currentWriteHolder) { + return NumberUtils.formatToCellData(value, contentProperty, currentWriteHolder); } } diff --git a/src/main/java/com/alibaba/excel/converters/byteconverter/ByteStringConverter.java b/src/main/java/com/alibaba/excel/converters/byteconverter/ByteStringConverter.java index c96114de..e1f014b6 100644 --- a/src/main/java/com/alibaba/excel/converters/byteconverter/ByteStringConverter.java +++ b/src/main/java/com/alibaba/excel/converters/byteconverter/ByteStringConverter.java @@ -35,7 +35,7 @@ public class ByteStringConverter implements Converter { @Override public CellData convertToExcelData(Byte value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return NumberUtils.formatToCellData(value, contentProperty); + return NumberUtils.formatToCellDataString(value, contentProperty); } } diff --git a/src/main/java/com/alibaba/excel/converters/date/DateDateConverter.java b/src/main/java/com/alibaba/excel/converters/date/DateDateConverter.java new file mode 100644 index 00000000..0bde87d3 --- /dev/null +++ b/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 { + @Override + public Class 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; + } +} diff --git a/src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleNumberConverter.java b/src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleNumberConverter.java index 15fbdae3..0b9541f5 100644 --- a/src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleNumberConverter.java +++ b/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.GlobalConfiguration; 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 @@ -32,9 +34,8 @@ public class DoubleNumberConverter implements Converter { } @Override - public CellData convertToExcelData(Double value, ExcelContentProperty contentProperty, - GlobalConfiguration globalConfiguration) { - return new CellData(BigDecimal.valueOf(value)); + public CellData convertToExcelData(Double value, ExcelContentProperty contentProperty, + WriteHolder currentWriteHolder) { + return NumberUtils.formatToCellData(value, contentProperty, currentWriteHolder); } - } diff --git a/src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleStringConverter.java b/src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleStringConverter.java index 2572b4ee..116dc129 100644 --- a/src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleStringConverter.java +++ b/src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleStringConverter.java @@ -35,6 +35,6 @@ public class DoubleStringConverter implements Converter { @Override public CellData convertToExcelData(Double value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return NumberUtils.formatToCellData(value, contentProperty); + return NumberUtils.formatToCellDataString(value, contentProperty); } } diff --git a/src/main/java/com/alibaba/excel/converters/floatconverter/FloatNumberConverter.java b/src/main/java/com/alibaba/excel/converters/floatconverter/FloatNumberConverter.java index 69cc22e7..7d90e4c3 100644 --- a/src/main/java/com/alibaba/excel/converters/floatconverter/FloatNumberConverter.java +++ b/src/main/java/com/alibaba/excel/converters/floatconverter/FloatNumberConverter.java @@ -1,12 +1,12 @@ package com.alibaba.excel.converters.floatconverter; -import java.math.BigDecimal; - import com.alibaba.excel.converters.Converter; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.GlobalConfiguration; 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 @@ -32,9 +32,8 @@ public class FloatNumberConverter implements Converter { } @Override - public CellData convertToExcelData(Float value, ExcelContentProperty contentProperty, - GlobalConfiguration globalConfiguration) { - return new CellData(new BigDecimal(Float.toString(value))); + public CellData convertToExcelData(Float value, ExcelContentProperty contentProperty, + WriteHolder currentWriteHolder) { + return NumberUtils.formatToCellData(value, contentProperty, currentWriteHolder); } - } diff --git a/src/main/java/com/alibaba/excel/converters/floatconverter/FloatStringConverter.java b/src/main/java/com/alibaba/excel/converters/floatconverter/FloatStringConverter.java index ee2ef551..a7fd79f1 100644 --- a/src/main/java/com/alibaba/excel/converters/floatconverter/FloatStringConverter.java +++ b/src/main/java/com/alibaba/excel/converters/floatconverter/FloatStringConverter.java @@ -35,6 +35,6 @@ public class FloatStringConverter implements Converter { @Override public CellData convertToExcelData(Float value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return NumberUtils.formatToCellData(value, contentProperty); + return NumberUtils.formatToCellDataString(value, contentProperty); } } diff --git a/src/main/java/com/alibaba/excel/converters/integer/IntegerNumberConverter.java b/src/main/java/com/alibaba/excel/converters/integer/IntegerNumberConverter.java index 117d4c11..0edae3e1 100644 --- a/src/main/java/com/alibaba/excel/converters/integer/IntegerNumberConverter.java +++ b/src/main/java/com/alibaba/excel/converters/integer/IntegerNumberConverter.java @@ -1,12 +1,12 @@ package com.alibaba.excel.converters.integer; -import java.math.BigDecimal; - import com.alibaba.excel.converters.Converter; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.GlobalConfiguration; 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 @@ -32,9 +32,9 @@ public class IntegerNumberConverter implements Converter { } @Override - public CellData convertToExcelData(Integer value, ExcelContentProperty contentProperty, - GlobalConfiguration globalConfiguration) { - return new CellData(new BigDecimal(Integer.toString(value))); + public CellData convertToExcelData(Integer value, ExcelContentProperty contentProperty, + WriteHolder currentWriteHolder) { + return NumberUtils.formatToCellData(value, contentProperty, currentWriteHolder); } } diff --git a/src/main/java/com/alibaba/excel/converters/integer/IntegerStringConverter.java b/src/main/java/com/alibaba/excel/converters/integer/IntegerStringConverter.java index 07bc1b77..a0bad356 100644 --- a/src/main/java/com/alibaba/excel/converters/integer/IntegerStringConverter.java +++ b/src/main/java/com/alibaba/excel/converters/integer/IntegerStringConverter.java @@ -35,6 +35,6 @@ public class IntegerStringConverter implements Converter { @Override public CellData convertToExcelData(Integer value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return NumberUtils.formatToCellData(value, contentProperty); + return NumberUtils.formatToCellDataString(value, contentProperty); } } diff --git a/src/main/java/com/alibaba/excel/converters/longconverter/LongBooleanConverter.java b/src/main/java/com/alibaba/excel/converters/longconverter/LongBooleanConverter.java index 6ee0217b..298fed5e 100644 --- a/src/main/java/com/alibaba/excel/converters/longconverter/LongBooleanConverter.java +++ b/src/main/java/com/alibaba/excel/converters/longconverter/LongBooleanConverter.java @@ -16,7 +16,7 @@ public class LongBooleanConverter implements Converter { private static final Long ZERO = 0L; @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return Long.class; } @@ -26,7 +26,7 @@ public class LongBooleanConverter implements Converter { } @Override - public Long convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public Long convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { if (cellData.getBooleanValue()) { return ONE; @@ -35,12 +35,12 @@ public class LongBooleanConverter implements Converter { } @Override - public CellData convertToExcelData(Long value, ExcelContentProperty contentProperty, + public CellData convertToExcelData(Long value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { if (ONE.equals(value)) { - return new CellData(Boolean.TRUE); + return new CellData<>(Boolean.TRUE); } - return new CellData(Boolean.FALSE); + return new CellData<>(Boolean.FALSE); } } diff --git a/src/main/java/com/alibaba/excel/converters/longconverter/LongNumberConverter.java b/src/main/java/com/alibaba/excel/converters/longconverter/LongNumberConverter.java index 8058d624..7e4aa235 100644 --- a/src/main/java/com/alibaba/excel/converters/longconverter/LongNumberConverter.java +++ b/src/main/java/com/alibaba/excel/converters/longconverter/LongNumberConverter.java @@ -1,12 +1,12 @@ package com.alibaba.excel.converters.longconverter; -import java.math.BigDecimal; - import com.alibaba.excel.converters.Converter; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.GlobalConfiguration; 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 @@ -16,7 +16,7 @@ import com.alibaba.excel.metadata.property.ExcelContentProperty; public class LongNumberConverter implements Converter { @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return Long.class; } @@ -26,15 +26,15 @@ public class LongNumberConverter implements Converter { } @Override - public Long convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public Long convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { return cellData.getNumberValue().longValue(); } @Override - public CellData convertToExcelData(Long value, ExcelContentProperty contentProperty, - GlobalConfiguration globalConfiguration) { - return new CellData(BigDecimal.valueOf(value)); + public CellData convertToExcelData(Long value, ExcelContentProperty contentProperty, + WriteHolder currentWriteHolder) { + return NumberUtils.formatToCellData(value, contentProperty, currentWriteHolder); } } diff --git a/src/main/java/com/alibaba/excel/converters/longconverter/LongStringConverter.java b/src/main/java/com/alibaba/excel/converters/longconverter/LongStringConverter.java index 06e94f03..873fb113 100644 --- a/src/main/java/com/alibaba/excel/converters/longconverter/LongStringConverter.java +++ b/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 { @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return Long.class; } @@ -27,14 +27,14 @@ public class LongStringConverter implements Converter { } @Override - public Long convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public Long convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws ParseException { return NumberUtils.parseLong(cellData.getStringValue(), contentProperty); } @Override - public CellData convertToExcelData(Long value, ExcelContentProperty contentProperty, + public CellData convertToExcelData(Long value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return NumberUtils.formatToCellData(value, contentProperty); + return NumberUtils.formatToCellDataString(value, contentProperty); } } diff --git a/src/main/java/com/alibaba/excel/converters/shortconverter/ShortBooleanConverter.java b/src/main/java/com/alibaba/excel/converters/shortconverter/ShortBooleanConverter.java index 2c0cc61d..eb39b7de 100644 --- a/src/main/java/com/alibaba/excel/converters/shortconverter/ShortBooleanConverter.java +++ b/src/main/java/com/alibaba/excel/converters/shortconverter/ShortBooleanConverter.java @@ -16,7 +16,7 @@ public class ShortBooleanConverter implements Converter { private static final Short ZERO = 0; @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return Short.class; } @@ -26,7 +26,7 @@ public class ShortBooleanConverter implements Converter { } @Override - public Short convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public Short convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { if (cellData.getBooleanValue()) { return ONE; @@ -35,12 +35,12 @@ public class ShortBooleanConverter implements Converter { } @Override - public CellData convertToExcelData(Short value, ExcelContentProperty contentProperty, + public CellData convertToExcelData(Short value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { if (ONE.equals(value)) { - return new CellData(Boolean.TRUE); + return new CellData<>(Boolean.TRUE); } - return new CellData(Boolean.FALSE); + return new CellData<>(Boolean.FALSE); } } diff --git a/src/main/java/com/alibaba/excel/converters/shortconverter/ShortNumberConverter.java b/src/main/java/com/alibaba/excel/converters/shortconverter/ShortNumberConverter.java index 357c6aeb..eedfca4f 100644 --- a/src/main/java/com/alibaba/excel/converters/shortconverter/ShortNumberConverter.java +++ b/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.GlobalConfiguration; 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 @@ -16,7 +18,7 @@ import com.alibaba.excel.metadata.property.ExcelContentProperty; public class ShortNumberConverter implements Converter { @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return Short.class; } @@ -26,15 +28,14 @@ public class ShortNumberConverter implements Converter { } @Override - public Short convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public Short convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { return cellData.getNumberValue().shortValue(); } @Override - public CellData convertToExcelData(Short value, ExcelContentProperty contentProperty, - GlobalConfiguration globalConfiguration) { - return new CellData(new BigDecimal(Short.toString(value))); + public CellData convertToExcelData(Short value, ExcelContentProperty contentProperty, + WriteHolder currentWriteHolder) { + return NumberUtils.formatToCellData(value, contentProperty, currentWriteHolder); } - } diff --git a/src/main/java/com/alibaba/excel/converters/shortconverter/ShortStringConverter.java b/src/main/java/com/alibaba/excel/converters/shortconverter/ShortStringConverter.java index a683a038..9d78f48e 100644 --- a/src/main/java/com/alibaba/excel/converters/shortconverter/ShortStringConverter.java +++ b/src/main/java/com/alibaba/excel/converters/shortconverter/ShortStringConverter.java @@ -35,6 +35,6 @@ public class ShortStringConverter implements Converter { @Override public CellData convertToExcelData(Short value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return NumberUtils.formatToCellData(value, contentProperty); + return NumberUtils.formatToCellDataString(value, contentProperty); } } diff --git a/src/main/java/com/alibaba/excel/enums/CellDataTypeEnum.java b/src/main/java/com/alibaba/excel/enums/CellDataTypeEnum.java index 44efc179..6220340a 100644 --- a/src/main/java/com/alibaba/excel/enums/CellDataTypeEnum.java +++ b/src/main/java/com/alibaba/excel/enums/CellDataTypeEnum.java @@ -39,9 +39,15 @@ public enum CellDataTypeEnum { /** * Images are currently supported only when writing */ - IMAGE; + IMAGE, + /** + * date.Support only when writing. + */ + DATE, + ; private static final Map TYPE_ROUTING_MAP = new HashMap(16); + static { TYPE_ROUTING_MAP.put("s", STRING); TYPE_ROUTING_MAP.put("str", DIRECT_STRING); diff --git a/src/main/java/com/alibaba/excel/event/AnalysisEventListener.java b/src/main/java/com/alibaba/excel/event/AnalysisEventListener.java index 4b1b802a..a0cd5078 100644 --- a/src/main/java/com/alibaba/excel/event/AnalysisEventListener.java +++ b/src/main/java/com/alibaba/excel/event/AnalysisEventListener.java @@ -16,7 +16,7 @@ import com.alibaba.excel.util.ConverterUtils; public abstract class AnalysisEventListener implements ReadListener { @Override - public void invokeHead(Map headMap, AnalysisContext context) { + public void invokeHead(Map> headMap, AnalysisContext context) { invokeHeadMap(ConverterUtils.convertToStringMap(headMap, context), context); } diff --git a/src/main/java/com/alibaba/excel/metadata/AbstractHolder.java b/src/main/java/com/alibaba/excel/metadata/AbstractHolder.java index f7cb1ced..548503d0 100644 --- a/src/main/java/com/alibaba/excel/metadata/AbstractHolder.java +++ b/src/main/java/com/alibaba/excel/metadata/AbstractHolder.java @@ -34,7 +34,7 @@ public abstract class AbstractHolder implements ConfigurationHolder { *

* Write key: */ - private Map converterMap; + private Map> converterMap; public AbstractHolder(BasicParameter basicParameter, AbstractHolder prentAbstractHolder) { this.newInitialization = Boolean.TRUE; @@ -103,16 +103,16 @@ public abstract class AbstractHolder implements ConfigurationHolder { this.globalConfiguration = globalConfiguration; } - public Map getConverterMap() { + public Map> getConverterMap() { return converterMap; } - public void setConverterMap(Map converterMap) { + public void setConverterMap(Map> converterMap) { this.converterMap = converterMap; } @Override - public Map converterMap() { + public Map> converterMap() { return getConverterMap(); } diff --git a/src/main/java/com/alibaba/excel/metadata/CellData.java b/src/main/java/com/alibaba/excel/metadata/CellData.java index ac18fb8a..1cac53c2 100644 --- a/src/main/java/com/alibaba/excel/metadata/CellData.java +++ b/src/main/java/com/alibaba/excel/metadata/CellData.java @@ -1,10 +1,14 @@ package com.alibaba.excel.metadata; import java.math.BigDecimal; +import java.util.Date; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.util.StringUtils; +import lombok.Getter; +import lombok.Setter; + /** * Excel internal cell data. * @@ -12,6 +16,8 @@ import com.alibaba.excel.util.StringUtils; * * @author Jiaju Zhuang */ +@Getter +@Setter public class CellData extends AbstractCell { private CellDataTypeEnum type; /** @@ -30,11 +36,15 @@ public class CellData extends AbstractCell { private String formulaValue; 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; /** @@ -120,86 +130,6 @@ public class CellData extends AbstractCell { 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 */ @@ -271,14 +201,28 @@ public class CellData extends AbstractCell { } switch (type) { case NUMBER: + if (numberValue == null) { + return StringUtils.EMPTY; + } return numberValue.toString(); case BOOLEAN: + if (booleanValue == null) { + return StringUtils.EMPTY; + } return booleanValue.toString(); case DIRECT_STRING: case STRING: case ERROR: return stringValue; + case DATE: + if (dateValue == null) { + return StringUtils.EMPTY; + } + return dateValue.toString(); case IMAGE: + if (imageValue == null) { + return StringUtils.EMPTY; + } return "image[" + imageValue.length + "]"; default: return StringUtils.EMPTY; diff --git a/src/main/java/com/alibaba/excel/metadata/ConfigurationHolder.java b/src/main/java/com/alibaba/excel/metadata/ConfigurationHolder.java index d84b1d58..ee4d7edf 100644 --- a/src/main/java/com/alibaba/excel/metadata/ConfigurationHolder.java +++ b/src/main/java/com/alibaba/excel/metadata/ConfigurationHolder.java @@ -32,5 +32,5 @@ public interface ConfigurationHolder extends Holder { * * @return Converter */ - Map converterMap(); + Map> converterMap(); } diff --git a/src/main/java/com/alibaba/excel/metadata/format/DataFormatter.java b/src/main/java/com/alibaba/excel/metadata/format/DataFormatter.java index be9d2ad6..e9266c71 100644 --- a/src/main/java/com/alibaba/excel/metadata/format/DataFormatter.java +++ b/src/main/java/com/alibaba/excel/metadata/format/DataFormatter.java @@ -170,7 +170,7 @@ public class DataFormatter { 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. // That however would require other code to be re factored. @@ -225,7 +225,7 @@ public class DataFormatter { return format; } - private Format createFormat(Integer dataFormat, String dataFormatString) { + private Format createFormat(Short dataFormat, String dataFormatString) { String formatStr = dataFormatString; Format format = checkSpecialConverter(formatStr); @@ -607,7 +607,7 @@ public class DataFormatter { * @param dataFormatString * @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); if (dateFormat instanceof ExcelStyleDateFormatter) { // Hint about the raw excel value @@ -630,7 +630,7 @@ public class DataFormatter { * @param dataFormatString * @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); String formatted = numberFormat.format(data); return formatted.replaceFirst("E(\\d)", "E+$1"); // to match Excel's E-notation @@ -644,7 +644,7 @@ public class DataFormatter { * @param dataFormatString * @return */ - public String format(Double data, Integer dataFormat, String dataFormatString) { + public String format(Double data, Short dataFormat, String dataFormatString) { if (DateUtils.isADateFormat(dataFormat, dataFormatString)) { return getFormattedDateString(data, dataFormat, dataFormatString); } diff --git a/src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java b/src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java index 000e298d..13e3d45b 100644 --- a/src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java +++ b/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.Head; 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.util.ConverterUtils; import com.alibaba.excel.util.FieldUtils; @@ -26,28 +26,28 @@ import net.sf.cglib.beans.BeanMap; * * @author jipengfei */ -public class ModelBuildEventListener extends AbstractIgnoreExceptionReadListener> { +public class ModelBuildEventListener extends AbstractIgnoreExceptionReadListener>> { @Override - public void invokeHead(Map cellDataMap, AnalysisContext context) {} + public void invokeHead(Map> cellDataMap, AnalysisContext context) {} @Override - public void invoke(Map cellDataMap, AnalysisContext context) { - ReadHolder currentReadHolder = context.currentReadHolder(); - if (HeadKindEnum.CLASS.equals(currentReadHolder.excelReadHeadProperty().getHeadKind())) { + public void invoke(Map> cellDataMap, AnalysisContext context) { + ReadSheetHolder readSheetHolder = context.readSheetHolder(); + if (HeadKindEnum.CLASS.equals(readSheetHolder.excelReadHeadProperty().getHeadKind())) { context.readRowHolder() - .setCurrentRowAnalysisResult(buildUserModel(cellDataMap, currentReadHolder, context)); + .setCurrentRowAnalysisResult(buildUserModel(cellDataMap, readSheetHolder, context)); return; } - context.readRowHolder().setCurrentRowAnalysisResult(buildStringList(cellDataMap, currentReadHolder, context)); + context.readRowHolder().setCurrentRowAnalysisResult(buildStringList(cellDataMap, readSheetHolder, context)); } - private Object buildStringList(Map cellDataMap, ReadHolder currentReadHolder, + private Object buildStringList(Map> cellDataMap, ReadSheetHolder readSheetHolder, AnalysisContext context) { int index = 0; if (context.readWorkbookHolder().getDefaultReturnMap()) { Map map = new LinkedHashMap(cellDataMap.size() * 4 / 3 + 1); - for (Map.Entry entry : cellDataMap.entrySet()) { + for (Map.Entry> entry : cellDataMap.entrySet()) { Integer key = entry.getKey(); CellData cellData = entry.getValue(); while (index < key) { @@ -60,10 +60,10 @@ public class ModelBuildEventListener extends AbstractIgnoreExceptionReadListener continue; } map.put(key, - (String)ConverterUtils.convertToJavaObject(cellData, null, null, currentReadHolder.converterMap(), - currentReadHolder.globalConfiguration(), context.readRowHolder().getRowIndex(), key)); + (String)ConverterUtils.convertToJavaObject(cellData, null, null, readSheetHolder.converterMap(), + readSheetHolder, context.readRowHolder().getRowIndex(), key)); } - int headSize = currentReadHolder.excelReadHeadProperty().getHeadMap().size(); + int headSize = readSheetHolder.excelReadHeadProperty().getHeadMap().size(); while (index < headSize) { map.put(index, null); index++; @@ -71,10 +71,10 @@ public class ModelBuildEventListener extends AbstractIgnoreExceptionReadListener return map; } else { // Compatible with the old code the old code returns a list - List list = new ArrayList(); - for (Map.Entry entry : cellDataMap.entrySet()) { + List list = new ArrayList<>(); + for (Map.Entry> entry : cellDataMap.entrySet()) { Integer key = entry.getKey(); - CellData cellData = entry.getValue(); + CellData cellData = entry.getValue(); while (index < key) { list.add(null); index++; @@ -85,10 +85,10 @@ public class ModelBuildEventListener extends AbstractIgnoreExceptionReadListener continue; } list.add( - (String)ConverterUtils.convertToJavaObject(cellData, null, null, currentReadHolder.converterMap(), - currentReadHolder.globalConfiguration(), context.readRowHolder().getRowIndex(), key)); + (String)ConverterUtils.convertToJavaObject(cellData, null, null, readSheetHolder.converterMap(), + readSheetHolder, context.readRowHolder().getRowIndex(), key)); } - int headSize = currentReadHolder.excelReadHeadProperty().getHeadMap().size(); + int headSize = readSheetHolder.excelReadHeadProperty().getHeadMap().size(); while (index < headSize) { list.add(null); index++; @@ -97,15 +97,15 @@ public class ModelBuildEventListener extends AbstractIgnoreExceptionReadListener } } - private Object buildUserModel(Map cellDataMap, ReadHolder currentReadHolder, + private Object buildUserModel(Map> cellDataMap, ReadSheetHolder readSheetHolder, AnalysisContext context) { - ExcelReadHeadProperty excelReadHeadProperty = currentReadHolder.excelReadHeadProperty(); + ExcelReadHeadProperty excelReadHeadProperty = readSheetHolder.excelReadHeadProperty(); Object resultModel; try { resultModel = excelReadHeadProperty.getHeadClazz().newInstance(); } catch (Exception e) { 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); } Map headMap = excelReadHeadProperty.getHeadMap(); @@ -116,13 +116,13 @@ public class ModelBuildEventListener extends AbstractIgnoreExceptionReadListener if (!cellDataMap.containsKey(index)) { continue; } - CellData cellData = cellDataMap.get(index); + CellData cellData = cellDataMap.get(index); if (cellData.getType() == CellDataTypeEnum.EMPTY) { continue; } ExcelContentProperty excelContentProperty = contentPropertyMap.get(index); Object value = ConverterUtils.convertToJavaObject(cellData, excelContentProperty.getField(), - excelContentProperty, currentReadHolder.converterMap(), currentReadHolder.globalConfiguration(), + excelContentProperty, readSheetHolder.converterMap(), readSheetHolder, context.readRowHolder().getRowIndex(), index); if (value != null) { map.put(FieldUtils.resolveCglibFieldName(excelContentProperty.getField()), value); diff --git a/src/main/java/com/alibaba/excel/read/listener/ReadListener.java b/src/main/java/com/alibaba/excel/read/listener/ReadListener.java index f1d341f5..b3a2e970 100644 --- a/src/main/java/com/alibaba/excel/read/listener/ReadListener.java +++ b/src/main/java/com/alibaba/excel/read/listener/ReadListener.java @@ -29,7 +29,7 @@ public interface ReadListener extends Listener { * @param headMap * @param context */ - void invokeHead(Map headMap, AnalysisContext context); + void invokeHead(Map> headMap, AnalysisContext context); /** * When analysis one row trigger invoke function. diff --git a/src/main/java/com/alibaba/excel/read/metadata/holder/AbstractReadHolder.java b/src/main/java/com/alibaba/excel/read/metadata/holder/AbstractReadHolder.java index c431ab49..95bf6f89 100644 --- a/src/main/java/com/alibaba/excel/read/metadata/holder/AbstractReadHolder.java +++ b/src/main/java/com/alibaba/excel/read/metadata/holder/AbstractReadHolder.java @@ -1,12 +1,8 @@ package com.alibaba.excel.read.metadata.holder; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.ConverterKeyBuild; 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.ReadWorkbook; import com.alibaba.excel.read.metadata.property.ExcelReadHeadProperty; +import com.alibaba.excel.util.ListUtils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Read Holder @@ -24,8 +24,6 @@ import com.alibaba.excel.read.metadata.property.ExcelReadHeadProperty; * @author Jiaju Zhuang */ 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. * @@ -84,9 +82,9 @@ public abstract class AbstractReadHolder extends AbstractHolder implements ReadH } if (parentAbstractReadHolder == null) { - this.readListenerList = new ArrayList(); + this.readListenerList = ListUtils.newArrayList(); } else { - this.readListenerList = new ArrayList(parentAbstractReadHolder.getReadListenerList()); + this.readListenerList = ListUtils.newArrayList(parentAbstractReadHolder.getReadListenerList()); } if (HolderEnum.WORKBOOK.equals(holderType())) { Boolean useDefaultListener = ((ReadWorkbook)readBasicParameter).getUseDefaultListener(); @@ -102,11 +100,11 @@ public abstract class AbstractReadHolder extends AbstractHolder implements ReadH if (parentAbstractReadHolder == null) { setConverterMap(DefaultConverterLoader.loadDefaultReadConverter()); } else { - setConverterMap(new HashMap(parentAbstractReadHolder.getConverterMap())); + setConverterMap(new HashMap<>(parentAbstractReadHolder.getConverterMap())); } if (readBasicParameter.getCustomConverterList() != null && !readBasicParameter.getCustomConverterList().isEmpty()) { - for (Converter converter : readBasicParameter.getCustomConverterList()) { + for (Converter converter : readBasicParameter.getCustomConverterList()) { getConverterMap().put( ConverterKeyBuild.buildKey(converter.supportJavaTypeKey(), converter.supportExcelTypeKey()), converter); diff --git a/src/main/java/com/alibaba/excel/read/processor/DefaultAnalysisEventProcessor.java b/src/main/java/com/alibaba/excel/read/processor/DefaultAnalysisEventProcessor.java index ddd19504..f23f58c9 100644 --- a/src/main/java/com/alibaba/excel/read/processor/DefaultAnalysisEventProcessor.java +++ b/src/main/java/com/alibaba/excel/read/processor/DefaultAnalysisEventProcessor.java @@ -82,7 +82,7 @@ public class DefaultAnalysisEventProcessor implements AnalysisEventProcessor { private void dealData(AnalysisContext analysisContext) { ReadRowHolder readRowHolder = analysisContext.readRowHolder(); - Map cellDataMap = (Map)readRowHolder.getCellMap(); + Map> cellDataMap = (Map)readRowHolder.getCellMap(); readRowHolder.setCurrentRowAnalysisResult(cellDataMap); int rowIndex = readRowHolder.getRowIndex(); int currentHeadRowNumber = analysisContext.readSheetHolder().getHeadRowNumber(); @@ -111,7 +111,7 @@ public class DefaultAnalysisEventProcessor implements AnalysisEventProcessor { } } - private void buildHead(AnalysisContext analysisContext, Map cellDataMap) { + private void buildHead(AnalysisContext analysisContext, Map> cellDataMap) { if (!HeadKindEnum.CLASS.equals(analysisContext.currentReadHolder().excelReadHeadProperty().getHeadKind())) { return; } diff --git a/src/main/java/com/alibaba/excel/util/BooleanUtils.java b/src/main/java/com/alibaba/excel/util/BooleanUtils.java index 55c48a18..18f6dd39 100644 --- a/src/main/java/com/alibaba/excel/util/BooleanUtils.java +++ b/src/main/java/com/alibaba/excel/util/BooleanUtils.java @@ -25,4 +25,79 @@ public class BooleanUtils { } } + + // boolean Boolean methods + //----------------------------------------------------------------------- + /** + *

Checks if a {@code Boolean} value is {@code true}, + * handling {@code null} by returning {@code false}.

+ * + *
+     *   BooleanUtils.isTrue(Boolean.TRUE)  = true
+     *   BooleanUtils.isTrue(Boolean.FALSE) = false
+     *   BooleanUtils.isTrue(null)          = false
+     * 
+ * + * @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); + } + + /** + *

Checks if a {@code Boolean} value is not {@code true}, + * handling {@code null} by returning {@code true}.

+ * + *
+     *   BooleanUtils.isNotTrue(Boolean.TRUE)  = false
+     *   BooleanUtils.isNotTrue(Boolean.FALSE) = true
+     *   BooleanUtils.isNotTrue(null)          = true
+     * 
+ * + * @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); + } + + /** + *

Checks if a {@code Boolean} value is {@code false}, + * handling {@code null} by returning {@code false}.

+ * + *
+     *   BooleanUtils.isFalse(Boolean.TRUE)  = false
+     *   BooleanUtils.isFalse(Boolean.FALSE) = true
+     *   BooleanUtils.isFalse(null)          = false
+     * 
+ * + * @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); + } + + /** + *

Checks if a {@code Boolean} value is not {@code false}, + * handling {@code null} by returning {@code true}.

+ * + *
+     *   BooleanUtils.isNotFalse(Boolean.TRUE)  = true
+     *   BooleanUtils.isNotFalse(Boolean.FALSE) = false
+     *   BooleanUtils.isNotFalse(null)          = true
+     * 
+ * + * @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); + } + } diff --git a/src/main/java/com/alibaba/excel/util/ConverterUtils.java b/src/main/java/com/alibaba/excel/util/ConverterUtils.java index 43b12c53..61f69ac4 100644 --- a/src/main/java/com/alibaba/excel/util/ConverterUtils.java +++ b/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.ParameterizedType; import java.lang.reflect.Type; -import java.util.HashMap; import java.util.Map; 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.exception.ExcelDataConvertException; import com.alibaba.excel.metadata.CellData; -import com.alibaba.excel.metadata.GlobalConfiguration; import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.read.metadata.holder.ReadHolder; +import com.alibaba.excel.read.metadata.holder.ReadSheetHolder; /** * Converting objects @@ -32,13 +31,13 @@ public class ConverterUtils { * @param context * @return */ - public static Map convertToStringMap(Map cellDataMap, AnalysisContext context) { - Map stringMap = new HashMap(cellDataMap.size() * 4 / 3 + 1); - ReadHolder currentReadHolder = context.currentReadHolder(); + public static Map convertToStringMap(Map> cellDataMap, AnalysisContext context) { + Map stringMap = MapUtils.newHashMapWithExpectedSize(cellDataMap.size()); + ReadSheetHolder readSheetHolder = context.readSheetHolder(); int index = 0; - for (Map.Entry entry : cellDataMap.entrySet()) { + for (Map.Entry> entry : cellDataMap.entrySet()) { Integer key = entry.getKey(); - CellData cellData = entry.getValue(); + CellData cellData = entry.getValue(); while (index < key) { stringMap.put(index, null); index++; @@ -48,15 +47,15 @@ public class ConverterUtils { stringMap.put(key, null); continue; } - Converter converter = - currentReadHolder.converterMap().get(ConverterKeyBuild.buildKey(String.class, cellData.getType())); + Converter converter = + readSheetHolder.converterMap().get(ConverterKeyBuild.buildKey(String.class, cellData.getType())); if (converter == null) { throw new ExcelDataConvertException(context.readRowHolder().getRowIndex(), key, cellData, null, "Converter not found, convert " + cellData.getType() + " to String"); } try { stringMap.put(key, - (String)(converter.convertToJavaData(cellData, null, currentReadHolder.globalConfiguration()))); + (String)(converter.convertToJavaData(cellData, null, readSheetHolder))); } catch (Exception e) { throw new ExcelDataConvertException(context.readRowHolder().getRowIndex(), key, cellData, null, "Convert data " + cellData + " to String error ", e); @@ -72,15 +71,15 @@ public class ConverterUtils { * @param field * @param contentProperty * @param converterMap - * @param globalConfiguration + * @param readSheetHolder * @param rowIndex * @param columnIndex * @return */ - public static Object convertToJavaObject(CellData cellData, Field field, ExcelContentProperty contentProperty, - Map converterMap, GlobalConfiguration globalConfiguration, Integer rowIndex, + public static Object convertToJavaObject(CellData cellData, Field field, ExcelContentProperty contentProperty, + Map> converterMap, ReadSheetHolder readSheetHolder, Integer rowIndex, Integer columnIndex) { - Class clazz; + Class clazz; if (field == null) { clazz = String.class; } else { @@ -88,37 +87,37 @@ public class ConverterUtils { } if (clazz == CellData.class) { Type type = field.getGenericType(); - Class classGeneric; + Class classGeneric; if (type instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType)type; - classGeneric = (Class)parameterizedType.getActualTypeArguments()[0]; + classGeneric = (Class)parameterizedType.getActualTypeArguments()[0]; } else { classGeneric = String.class; } - CellData cellDataReturn = new CellData(cellData); + CellData cellDataReturn = new CellData(cellData); cellDataReturn.setData(doConvertToJavaObject(cellData, classGeneric, contentProperty, converterMap, - globalConfiguration, rowIndex, columnIndex)); + readSheetHolder, rowIndex, columnIndex)); return cellDataReturn; } - return doConvertToJavaObject(cellData, clazz, contentProperty, converterMap, globalConfiguration, rowIndex, + return doConvertToJavaObject(cellData, clazz, contentProperty, converterMap, readSheetHolder, rowIndex, columnIndex); } /** - * * @param cellData * @param clazz * @param contentProperty * @param converterMap - * @param globalConfiguration + * @param readSheetHolder * @param rowIndex * @param columnIndex * @return */ - private static Object doConvertToJavaObject(CellData cellData, Class clazz, ExcelContentProperty contentProperty, - Map converterMap, GlobalConfiguration globalConfiguration, Integer rowIndex, + private static Object doConvertToJavaObject(CellData cellData, Class clazz, + ExcelContentProperty contentProperty, + Map> converterMap, ReadSheetHolder readSheetHolder, Integer rowIndex, Integer columnIndex) { - Converter converter = null; + Converter converter = null; if (contentProperty != null) { converter = contentProperty.getConverter(); } @@ -130,7 +129,7 @@ public class ConverterUtils { "Converter not found, convert " + cellData.getType() + " to " + clazz.getName()); } try { - return converter.convertToJavaData(cellData, contentProperty, globalConfiguration); + return converter.convertToJavaData(cellData, contentProperty, readSheetHolder); } catch (Exception e) { throw new ExcelDataConvertException(rowIndex, columnIndex, cellData, contentProperty, "Convert data " + cellData + " to " + clazz + " error ", e); diff --git a/src/main/java/com/alibaba/excel/util/DateUtils.java b/src/main/java/com/alibaba/excel/util/DateUtils.java index cef0098a..bc85adf6 100644 --- a/src/main/java/com/alibaba/excel/util/DateUtils.java +++ b/src/main/java/com/alibaba/excel/util/DateUtils.java @@ -17,16 +17,16 @@ public class DateUtils { /** * Is a cache of dates */ - private static final ThreadLocal> DATE_THREAD_LOCAL = - new ThreadLocal>(); + private static final ThreadLocal> DATE_THREAD_LOCAL = + new ThreadLocal<>(); /** * Is a cache of dates */ private static final ThreadLocal> DATE_FORMAT_THREAD_LOCAL = - new ThreadLocal>(); + 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_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"; private static final String MINUS = "-"; + public static String defaultDateFormat = DATE_FORMAT_19; + private DateUtils() {} /** @@ -134,7 +136,7 @@ public class DateUtils { return ""; } if (StringUtils.isEmpty(dateFormat)) { - dateFormat = DATE_FORMAT_19; + dateFormat = defaultDateFormat; } return getCacheDateFormat(dateFormat).format(date); } @@ -162,13 +164,13 @@ public class DateUtils { * @param formatString * @return */ - public static boolean isADateFormat(Integer formatIndex, String formatString) { + public static boolean isADateFormat(Short formatIndex, String formatString) { if (formatIndex == null) { return false; } - Map isDateCache = DATE_THREAD_LOCAL.get(); + Map isDateCache = DATE_THREAD_LOCAL.get(); if (isDateCache == null) { - isDateCache = new HashMap(); + isDateCache = MapUtils.newHashMap(); DATE_THREAD_LOCAL.set(isDateCache); } else { Boolean isDateCachedData = isDateCache.get(formatIndex); @@ -188,7 +190,7 @@ public class DateUtils { * @param formatString * @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? if (isInternalDateFormat(formatIndex)) { 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. * - * @see #isADateFormat(Integer, String) + * @see #isADateFormat(Short, String) */ - public static boolean isInternalDateFormat(int format) { + public static boolean isInternalDateFormat(short format) { switch (format) { // Internal Date Formats as described on page 427 in // Microsoft Excel Dev's Kit... diff --git a/src/main/java/com/alibaba/excel/util/IntUtils.java b/src/main/java/com/alibaba/excel/util/IntUtils.java index 0237e452..6d2e244c 100644 --- a/src/main/java/com/alibaba/excel/util/IntUtils.java +++ b/src/main/java/com/alibaba/excel/util/IntUtils.java @@ -10,6 +10,15 @@ import java.util.List; **/ public class 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}. * diff --git a/src/main/java/com/alibaba/excel/util/ListUtils.java b/src/main/java/com/alibaba/excel/util/ListUtils.java index 6b4d7499..85d06b4d 100644 --- a/src/main/java/com/alibaba/excel/util/ListUtils.java +++ b/src/main/java/com/alibaba/excel/util/ListUtils.java @@ -1,8 +1,13 @@ package com.alibaba.excel.util; import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; import java.util.List; +import lombok.NonNull; +import org.apache.commons.compress.utils.Iterators; + /** * List utils * @@ -11,6 +16,45 @@ import java.util.List; public class ListUtils { private ListUtils() {} + /** + * Creates a mutable, empty {@code ArrayList} instance (for Java 6 and earlier). + * + *

Note for Java 7 and later: 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 "diamond" syntax. + */ + public static ArrayList newArrayList() { + return new ArrayList<>(); + } + + /** + * Creates a mutable {@code ArrayList} instance containing the given elements; a very thin + * shortcut for creating an empty list and then calling {@link Iterators#addAll}. + * + */ + public static ArrayList newArrayList(Iterator elements) { + ArrayList list = newArrayList(); + Iterators.addAll(list, elements); + return list; + } + + /** + * Creates a mutable {@code ArrayList} instance containing the given elements; + * + * + *

Note for Java 7 and later: 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 "diamond" + * syntax. + */ + public static ArrayList newArrayList(Iterable elements) { + checkNotNull(elements); // for GWT + // Let ArrayList's sizing logic work, if possible + return (elements instanceof Collection) + ? new ArrayList<>((Collection)elements) + : newArrayList(elements.iterator()); + } + /** * Creates an {@code ArrayList} instance backed by an array with the specified initial size; * simply delegates to {@link ArrayList#ArrayList(int)}. @@ -60,4 +104,18 @@ public class ListUtils { } 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 checkNotNull(T reference) { + if (reference == null) { + throw new NullPointerException(); + } + return reference; + } } diff --git a/src/main/java/com/alibaba/excel/util/MapUtils.java b/src/main/java/com/alibaba/excel/util/MapUtils.java new file mode 100644 index 00000000..6af4129e --- /dev/null +++ b/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 mutable, empty {@code HashMap} instance. + * + *

Note: if mutability is not required, use {@link ImmutableMap#of()} instead. + * + *

Note: if {@code K} is an {@code enum} type, use {@link #newEnumMap} instead. + * + *

Note for Java 7 and later: this method is now unnecessary and should be treated as + * deprecated. Instead, use the {@code HashMap} constructor directly, taking advantage of the new + * "diamond" syntax. + * + * @return a new, empty {@code HashMap} + */ + public static HashMap newHashMap() { + return new HashMap<>(); + } + + /** + * Creates a {@code HashMap} instance, with a high enough "initial capacity" that it should + * 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 oversizing 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 HashMap 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; + } +} diff --git a/src/main/java/com/alibaba/excel/util/NumberDataFormatterUtils.java b/src/main/java/com/alibaba/excel/util/NumberDataFormatterUtils.java index 09d149b6..de01ad54 100644 --- a/src/main/java/com/alibaba/excel/util/NumberDataFormatterUtils.java +++ b/src/main/java/com/alibaba/excel/util/NumberDataFormatterUtils.java @@ -24,7 +24,7 @@ public class NumberDataFormatterUtils { * @param globalConfiguration * @return */ - public static String format(Double data, Integer dataFormat, String dataFormatString, + public static String format(Double data, Short dataFormat, String dataFormatString, GlobalConfiguration globalConfiguration) { DataFormatter dataFormatter = DATA_FORMATTER_THREAD_LOCAL.get(); if (dataFormatter == null) { diff --git a/src/main/java/com/alibaba/excel/util/NumberUtils.java b/src/main/java/com/alibaba/excel/util/NumberUtils.java index 4257ff44..09a15bea 100644 --- a/src/main/java/com/alibaba/excel/util/NumberUtils.java +++ b/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.property.ExcelContentProperty; +import com.alibaba.excel.write.metadata.holder.WriteHolder; /** * Number utils @@ -46,8 +47,27 @@ public class NumberUtils { * @param contentProperty * @return */ - public static CellData formatToCellData(Number num, ExcelContentProperty contentProperty) { - return new CellData(format(num, contentProperty)); + public static CellData formatToCellDataString(Number num, ExcelContentProperty 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; } /** diff --git a/src/main/java/com/alibaba/excel/util/WorkBookUtil.java b/src/main/java/com/alibaba/excel/util/WorkBookUtil.java index 186708c9..0ee92209 100644 --- a/src/main/java/com/alibaba/excel/util/WorkBookUtil.java +++ b/src/main/java/com/alibaba/excel/util/WorkBookUtil.java @@ -2,6 +2,13 @@ package com.alibaba.excel.util; 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.usermodel.HSSFWorkbook; 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.usermodel.XSSFWorkbook; -import com.alibaba.excel.support.ExcelTypeEnum; -import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; - /** - * * @author jipengfei */ public class WorkBookUtil { - private static final int ROW_ACCESS_WINDOW_SIZE = 500; + public static final int ROW_ACCESS_WINDOW_SIZE = 500; private WorkBookUtil() {} @@ -91,4 +94,16 @@ public class WorkBookUtil { cell.setCellValue(cellValue); 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); + } } diff --git a/src/main/java/com/alibaba/excel/util/WriteHandlerUtils.java b/src/main/java/com/alibaba/excel/util/WriteHandlerUtils.java index 044e7b2e..cac3f7f8 100644 --- a/src/main/java/com/alibaba/excel/util/WriteHandlerUtils.java +++ b/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, Integer relativeRowIndex, Boolean isHead) { - List cellDataList = new ArrayList(); + List> cellDataList = new ArrayList<>(); if (cell != null) { cellDataList.add(cellData); } afterCellDispose(writeContext, cellDataList, cell, head, relativeRowIndex, isHead); } - public static void afterCellDispose(WriteContext writeContext, List cellDataList, Cell cell, Head head, + public static void afterCellDispose(WriteContext writeContext, List> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { List handlerList = writeContext.currentWriteHolder().writeHandlerMap().get(CellWriteHandler.class); diff --git a/src/main/java/com/alibaba/excel/write/executor/AbstractExcelWriteExecutor.java b/src/main/java/com/alibaba/excel/write/executor/AbstractExcelWriteExecutor.java index 4eb115c5..4aa2d33a 100644 --- a/src/main/java/com/alibaba/excel/write/executor/AbstractExcelWriteExecutor.java +++ b/src/main/java/com/alibaba/excel/write/executor/AbstractExcelWriteExecutor.java @@ -1,12 +1,5 @@ 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.converters.Converter; 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.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 * @@ -56,6 +56,9 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor { case NUMBER: cell.setCellValue(cellData.getNumberValue().doubleValue()); return cellData; + case DATE: + cell.setCellValue(cellData.getDateValue()); + return cellData; case IMAGE: setImageValue(cellData, cell); return cellData; @@ -64,7 +67,7 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor { default: throw new ExcelDataConvertException(cell.getRow().getRowNum(), cell.getColumnIndex(), cellData, excelContentProperty, "Not supported data:" + value + " return type:" + cell.getCellType() - + "at row:" + cell.getRow().getRowNum()); + + "at row:" + cell.getRow().getRowNum()); } } @@ -113,7 +116,7 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor { CellData cellData; try { cellData = - converter.convertToExcelData(value, excelContentProperty, currentWriteHolder.globalConfiguration()); + converter.convertToExcelData(value, excelContentProperty, currentWriteHolder); } catch (Exception e) { throw new ExcelDataConvertException(cell.getRow().getRowNum(), cell.getColumnIndex(), new CellData(CellDataTypeEnum.EMPTY), excelContentProperty, diff --git a/src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java b/src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java index 7accb669..0c868a12 100644 --- a/src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java +++ b/src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java @@ -204,7 +204,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { } else { StringBuilder cellValueBuild = new StringBuilder(); int index = 0; - List cellDataList = new ArrayList(); + List> cellDataList = new ArrayList<>(); for (String variable : analysisCell.getVariableList()) { cellValueBuild.append(analysisCell.getPrepareDataList().get(index++)); if (!dataMap.containsKey(variable)) { diff --git a/src/main/java/com/alibaba/excel/write/handler/AbstractCellWriteHandler.java b/src/main/java/com/alibaba/excel/write/handler/AbstractCellWriteHandler.java index 963abc87..6b663ce9 100644 --- a/src/main/java/com/alibaba/excel/write/handler/AbstractCellWriteHandler.java +++ b/src/main/java/com/alibaba/excel/write/handler/AbstractCellWriteHandler.java @@ -39,7 +39,7 @@ public abstract class AbstractCellWriteHandler implements CellWriteHandler { @Override public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, - List cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { + List> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { } } diff --git a/src/main/java/com/alibaba/excel/write/handler/CellWriteHandler.java b/src/main/java/com/alibaba/excel/write/handler/CellWriteHandler.java index 66c7acaf..4c9e39ed 100644 --- a/src/main/java/com/alibaba/excel/write/handler/CellWriteHandler.java +++ b/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. */ 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 @@ -70,5 +70,5 @@ public interface CellWriteHandler extends WriteHandler { * @param isHead It will always be false when fill data. */ default void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, - List cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {} + List> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {} } diff --git a/src/main/java/com/alibaba/excel/write/handler/DefaultWriteHandlerLoader.java b/src/main/java/com/alibaba/excel/write/handler/DefaultWriteHandlerLoader.java index 4afefea6..16897076 100644 --- a/src/main/java/com/alibaba/excel/write/handler/DefaultWriteHandlerLoader.java +++ b/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.DimensionWorkbookWriteHandler; +import com.alibaba.excel.write.handler.impl.FillDataFormatCellWriteHandler; import com.alibaba.excel.write.metadata.style.WriteCellStyle; import com.alibaba.excel.write.metadata.style.WriteFont; import com.alibaba.excel.write.style.HorizontalCellStyleStrategy; @@ -43,6 +44,7 @@ public class DefaultWriteHandlerLoader { handlerList.add(new HorizontalCellStyleStrategy(headWriteCellStyle, new ArrayList<>())); } handlerList.addAll(DEFAULT_WRITE_HANDLER_LIST); + handlerList.add(new FillDataFormatCellWriteHandler()); return handlerList; } diff --git a/src/main/java/com/alibaba/excel/write/handler/impl/FillDataFormatCellWriteHandler.java b/src/main/java/com/alibaba/excel/write/handler/impl/FillDataFormatCellWriteHandler.java new file mode 100644 index 00000000..3b67d0ca --- /dev/null +++ b/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 cellStyleSet = new HashSet<>(); + + private CellStyle defaultDateCellStyle; + + @Override + public int order() { + return OrderConstant.FILL_DATA_FORMAT; + } + + @Override + public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, + List> 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; + } + +} diff --git a/src/main/java/com/alibaba/excel/write/merge/AbstractMergeStrategy.java b/src/main/java/com/alibaba/excel/write/merge/AbstractMergeStrategy.java index 2a2b7b6d..7b3d4b2b 100644 --- a/src/main/java/com/alibaba/excel/write/merge/AbstractMergeStrategy.java +++ b/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 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.Head; import com.alibaba.excel.write.handler.CellWriteHandler; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import com.alibaba.excel.write.metadata.holder.WriteTableHolder; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Sheet; + /** * Merge strategy * * @author Jiaju Zhuang */ 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 public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, - List cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { + List> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { if (isHead) { return; } diff --git a/src/main/java/com/alibaba/excel/write/metadata/holder/AbstractWriteHolder.java b/src/main/java/com/alibaba/excel/write/metadata/holder/AbstractWriteHolder.java index 6ba2c593..59a9909f 100644 --- a/src/main/java/com/alibaba/excel/write/metadata/holder/AbstractWriteHolder.java +++ b/src/main/java/com/alibaba/excel/write/metadata/holder/AbstractWriteHolder.java @@ -207,7 +207,7 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ if (parentAbstractWriteHolder == null) { setConverterMap(DefaultConverterLoader.loadDefaultWriteConverter()); } else { - setConverterMap(new HashMap(parentAbstractWriteHolder.getConverterMap())); + setConverterMap(new HashMap<>(parentAbstractWriteHolder.getConverterMap())); } if (writeBasicParameter.getCustomConverterList() != null && !writeBasicParameter.getCustomConverterList().isEmpty()) { diff --git a/src/main/java/com/alibaba/excel/write/metadata/holder/WriteWorkbookHolder.java b/src/main/java/com/alibaba/excel/write/metadata/holder/WriteWorkbookHolder.java index 8c84f1dc..e3ea80d1 100644 --- a/src/main/java/com/alibaba/excel/write/metadata/holder/WriteWorkbookHolder.java +++ b/src/main/java/com/alibaba/excel/write/metadata/holder/WriteWorkbookHolder.java @@ -10,23 +10,30 @@ import java.io.OutputStream; import java.util.HashMap; 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.exception.ExcelGenerateException; import com.alibaba.excel.support.ExcelTypeEnum; import com.alibaba.excel.util.FileUtils; 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 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 * * @author Jiaju Zhuang */ +@Getter +@Setter 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 @@ -111,7 +118,10 @@ public class WriteWorkbookHolder extends AbstractWriteHolder { * Excel is also written in the event of an exception being thrown.The default false. */ private Boolean writeExcelOnException; - + /** + * Used to cache data Format. + */ + private Map dataFormatCache; public WriteWorkbookHolder(WriteWorkbook writeWorkbook) { super(writeWorkbook, null, writeWorkbook.getConvertAllFiled()); @@ -139,7 +149,7 @@ public class WriteWorkbookHolder extends AbstractWriteHolder { if (writeWorkbook.getExcelType() == null) { boolean isXls = (file != null && file.getName().endsWith(ExcelTypeEnum.XLS.getValue())) || (writeWorkbook.getTemplateFile() != null - && writeWorkbook.getTemplateFile().getName().endsWith(ExcelTypeEnum.XLS.getValue())); + && writeWorkbook.getTemplateFile().getName().endsWith(ExcelTypeEnum.XLS.getValue())); if (isXls) { this.excelType = ExcelTypeEnum.XLS; } else { @@ -166,6 +176,7 @@ public class WriteWorkbookHolder extends AbstractWriteHolder { } else { this.writeExcelOnException = writeWorkbook.getWriteExcelOnException(); } + this.dataFormatCache = MapUtils.newHashMap(); } private void copyTemplate() throws IOException { @@ -187,136 +198,29 @@ public class WriteWorkbookHolder extends AbstractWriteHolder { this.tempTemplateInputStream = new ByteArrayInputStream(templateFileByte); } - public Workbook getWorkbook() { - return workbook; - } - - public void setWorkbook(Workbook workbook) { - this.workbook = workbook; - } - - public Workbook getCachedWorkbook() { - return cachedWorkbook; - } - - public void setCachedWorkbook(Workbook cachedWorkbook) { - this.cachedWorkbook = cachedWorkbook; - } - - public Map getHasBeenInitializedSheetIndexMap() { - return hasBeenInitializedSheetIndexMap; - } - - public void setHasBeenInitializedSheetIndexMap(Map hasBeenInitializedSheetIndexMap) { - this.hasBeenInitializedSheetIndexMap = hasBeenInitializedSheetIndexMap; - } - - public Map getHasBeenInitializedSheetNameMap() { - return hasBeenInitializedSheetNameMap; - } - - public void setHasBeenInitializedSheetNameMap(Map 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; - } - - public Boolean getWriteExcelOnException() { - return writeExcelOnException; - } - - public void setWriteExcelOnException(Boolean writeExcelOnException) { - this.writeExcelOnException = writeExcelOnException; - } - @Override public HolderEnum holderType() { return HolderEnum.WORKBOOK; } + + /** + * Get a data format. + * + * @param format + * @return + */ + public Short getDataFormat(String format) { + if (StringUtils.isEmpty(format)) { + return 0; + } + Short dataFormat = dataFormatCache.get(format); + if (dataFormat != null) { + return dataFormat; + } + DataFormat dataFormatCreate = workbook.createDataFormat(); + dataFormat = dataFormatCreate.getFormat(format); + dataFormatCache.put(format,dataFormat); + return dataFormat; + } + } diff --git a/src/main/java/com/alibaba/excel/write/style/AbstractCellStyleStrategy.java b/src/main/java/com/alibaba/excel/write/style/AbstractCellStyleStrategy.java index 14ad9ce5..2e88cc84 100644 --- a/src/main/java/com/alibaba/excel/write/style/AbstractCellStyleStrategy.java +++ b/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 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.metadata.CellData; import com.alibaba.excel.metadata.Head; 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.metadata.holder.WriteSheetHolder; import com.alibaba.excel.write.metadata.holder.WriteTableHolder; 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 * @@ -30,27 +28,9 @@ public abstract class AbstractCellStyleStrategy implements CellWriteHandler, Wor 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 public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, - List cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { + List> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { if (isHead == null) { return; } @@ -61,22 +41,12 @@ public abstract class AbstractCellStyleStrategy implements CellWriteHandler, Wor } } - @Override - public void beforeWorkbookCreate() { - - } - @Override public void afterWorkbookCreate(WriteWorkbookHolder writeWorkbookHolder) { initCellStyle(writeWorkbookHolder.getWorkbook()); hasInitialized = true; } - @Override - public void afterWorkbookDispose(WriteWorkbookHolder writeWorkbookHolder) { - - } - /** * Initialization cell style * diff --git a/src/main/java/com/alibaba/excel/write/style/AbstractVerticalCellStyleStrategy.java b/src/main/java/com/alibaba/excel/write/style/AbstractVerticalCellStyleStrategy.java index 197c5cf8..9a9261db 100644 --- a/src/main/java/com/alibaba/excel/write/style/AbstractVerticalCellStyleStrategy.java +++ b/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.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.util.StyleUtil; 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 * @@ -63,7 +63,7 @@ public abstract class AbstractVerticalCellStyleStrategy extends AbstractCellStyl } return; } - WriteCellStyle contentCellStyle = contentCellStyle(head); + WriteCellStyle contentCellStyle = contentCellStyle(cell, head, relativeRowIndex); if (contentCellStyle == null) { contentCellStyleCache.put(columnIndex, null); } 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 * @@ -87,6 +99,10 @@ public abstract class AbstractVerticalCellStyleStrategy extends AbstractCellStyl * @param head Nullable * @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."); + } } diff --git a/src/main/java/com/alibaba/excel/write/style/HorizontalCellStyleStrategy.java b/src/main/java/com/alibaba/excel/write/style/HorizontalCellStyleStrategy.java index 295cd556..7e8fbe4a 100644 --- a/src/main/java/com/alibaba/excel/write/style/HorizontalCellStyleStrategy.java +++ b/src/main/java/com/alibaba/excel/write/style/HorizontalCellStyleStrategy.java @@ -1,29 +1,23 @@ package com.alibaba.excel.write.style; -import java.util.ArrayList; 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.util.StyleUtil; +import com.alibaba.excel.util.ListUtils; 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 * * @author Jiaju Zhuang */ -public class HorizontalCellStyleStrategy extends AbstractCellStyleStrategy { - - private WriteCellStyle headWriteCellStyle; - private List contentWriteCellStyleList; +public class HorizontalCellStyleStrategy extends AbstractVerticalCellStyleStrategy { - private CellStyle headCellStyle; - private List contentCellStyleList; + private final WriteCellStyle headWriteCellStyle; + private final List contentWriteCellStyleList; public HorizontalCellStyleStrategy(WriteCellStyle headWriteCellStyle, List contentWriteCellStyleList) { @@ -33,37 +27,21 @@ public class HorizontalCellStyleStrategy extends AbstractCellStyleStrategy { public HorizontalCellStyleStrategy(WriteCellStyle headWriteCellStyle, WriteCellStyle contentWriteCellStyle) { this.headWriteCellStyle = headWriteCellStyle; - contentWriteCellStyleList = new ArrayList(); + contentWriteCellStyleList = ListUtils.newArrayList(); contentWriteCellStyleList.add(contentWriteCellStyle); } @Override - protected void initCellStyle(Workbook workbook) { - if (headWriteCellStyle != null) { - headCellStyle = StyleUtil.buildHeadCellStyle(workbook, headWriteCellStyle); - } - if (contentWriteCellStyleList != null && !contentWriteCellStyleList.isEmpty()) { - contentCellStyleList = new ArrayList(); - 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); + protected WriteCellStyle headCellStyle(Head head) { + return headWriteCellStyle; } @Override - protected void setContentCellStyle(Cell cell, Head head, Integer relativeRowIndex) { - if (contentCellStyleList == null || contentCellStyleList.isEmpty()) { - return; + protected WriteCellStyle contentCellStyle(Cell cell, Head head, Integer relativeRowIndex) { + if (CollectionUtils.isEmpty(contentWriteCellStyleList)) { + return null; } - cell.setCellStyle(contentCellStyleList.get(relativeRowIndex % contentCellStyleList.size())); + return contentWriteCellStyleList.get(relativeRowIndex % contentWriteCellStyleList.size()); } } diff --git a/src/main/java/com/alibaba/excel/write/style/column/AbstractColumnWidthStyleStrategy.java b/src/main/java/com/alibaba/excel/write/style/column/AbstractColumnWidthStyleStrategy.java index 6393745d..277f96b9 100644 --- a/src/main/java/com/alibaba/excel/write/style/column/AbstractColumnWidthStyleStrategy.java +++ b/src/main/java/com/alibaba/excel/write/style/column/AbstractColumnWidthStyleStrategy.java @@ -26,7 +26,7 @@ public abstract class AbstractColumnWidthStyleStrategy implements CellWriteHandl @Override public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, - List cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { + List> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { setColumnWidth(writeSheetHolder, cellDataList, cell, head, relativeRowIndex, isHead); } @@ -40,7 +40,7 @@ public abstract class AbstractColumnWidthStyleStrategy implements CellWriteHandl * @param relativeRowIndex * @param isHead */ - protected abstract void setColumnWidth(WriteSheetHolder writeSheetHolder, List cellDataList, Cell cell, + protected abstract void setColumnWidth(WriteSheetHolder writeSheetHolder, List> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead); } diff --git a/src/main/java/com/alibaba/excel/write/style/column/AbstractHeadColumnWidthStyleStrategy.java b/src/main/java/com/alibaba/excel/write/style/column/AbstractHeadColumnWidthStyleStrategy.java index 1a88eff6..d306d2e4 100644 --- a/src/main/java/com/alibaba/excel/write/style/column/AbstractHeadColumnWidthStyleStrategy.java +++ b/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 { @Override - protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List cellDataList, Cell cell, Head head, + protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { boolean needSetWidth = relativeRowIndex != null && (isHead || relativeRowIndex == 0); if (!needSetWidth) { diff --git a/src/main/java/com/alibaba/excel/write/style/column/LongestMatchColumnWidthStyleStrategy.java b/src/main/java/com/alibaba/excel/write/style/column/LongestMatchColumnWidthStyleStrategy.java index 717077dc..c6cc9df1 100644 --- a/src/main/java/com/alibaba/excel/write/style/column/LongestMatchColumnWidthStyleStrategy.java +++ b/src/main/java/com/alibaba/excel/write/style/column/LongestMatchColumnWidthStyleStrategy.java @@ -27,7 +27,7 @@ public class LongestMatchColumnWidthStyleStrategy extends AbstractColumnWidthSty private Map> cache = new HashMap>(8); @Override - protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List cellDataList, Cell cell, Head head, + protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { boolean needSetWidth = isHead || !CollectionUtils.isEmpty(cellDataList); if (!needSetWidth) { @@ -52,7 +52,7 @@ public class LongestMatchColumnWidthStyleStrategy extends AbstractColumnWidthSty } } - private Integer dataLength(List cellDataList, Cell cell, Boolean isHead) { + private Integer dataLength(List> cellDataList, Cell cell, Boolean isHead) { if (isHead) { return cell.getStringCellValue().getBytes().length; } diff --git a/src/test/java/com/alibaba/easyexcel/test/core/handler/WriteHandler.java b/src/test/java/com/alibaba/easyexcel/test/core/handler/WriteHandler.java index c762db79..cf9c5d26 100644 --- a/src/test/java/com/alibaba/easyexcel/test/core/handler/WriteHandler.java +++ b/src/test/java/com/alibaba/easyexcel/test/core/handler/WriteHandler.java @@ -98,7 +98,7 @@ public class WriteHandler implements WorkbookWriteHandler, SheetWriteHandler, Ro @Override public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, - List cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { + List> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { if (isHead) { Assert.assertEquals(1L, beforeCellCreate); Assert.assertEquals(1L, afterCellCreate); diff --git a/src/test/java/com/alibaba/easyexcel/test/demo/write/CustomCellWriteHandler.java b/src/test/java/com/alibaba/easyexcel/test/demo/write/CustomCellWriteHandler.java index 1222aa79..b4ade88f 100644 --- a/src/test/java/com/alibaba/easyexcel/test/demo/write/CustomCellWriteHandler.java +++ b/src/test/java/com/alibaba/easyexcel/test/demo/write/CustomCellWriteHandler.java @@ -27,7 +27,7 @@ public class CustomCellWriteHandler implements CellWriteHandler { @Override public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, - List cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { + List> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { // 这里可以对cell进行任何操作 LOGGER.info("第{}行,第{}列写入完成。", cell.getRowIndex(), cell.getColumnIndex()); if (isHead && cell.getColumnIndex() == 0) { diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/dataformat/DataFormatTest.java b/src/test/java/com/alibaba/easyexcel/test/temp/dataformat/DataFormatTest.java index e165d987..53902240 100644 --- a/src/test/java/com/alibaba/easyexcel/test/temp/dataformat/DataFormatTest.java +++ b/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(); LOGGER.info("数据:{}", list.size()); for (DataFormatData data : list) { - Integer dataFormat = data.getDate().getDataFormat(); + Short dataFormat = data.getDate().getDataFormat(); String dataFormatString = data.getDate().getDataFormatString(); @@ -67,7 +67,7 @@ public class DataFormatTest { EasyExcel.read(file, DataFormatData.class, null).sheet().headRowNumber(0).doReadSync(); LOGGER.info("数据:{}", list.size()); for (DataFormatData data : list) { - Integer dataFormat = data.getDate().getDataFormat(); + Short dataFormat = data.getDate().getDataFormat(); String dataFormatString = data.getDate().getDataFormatString();