From 058df4d77e366703b95d45115294c1a3eaad5df1 Mon Sep 17 00:00:00 2001 From: zhuangjiaju Date: Tue, 16 Jul 2019 14:18:48 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=A0=E5=85=A5=E5=86=99excel=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E6=B3=A8=E8=A7=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/alibaba/excel/EasyExcelFactory.java | 9 +- .../excel/analysis/BaseSaxAnalyser.java | 10 +- .../v07/handlers/DefaultCellHandler.java | 15 +- .../excel/annotation/ExcelColumnNum.java | 34 -- .../alibaba/excel/annotation/ExcelIgnore.java | 17 + .../excel/annotation/ExcelProperty.java | 44 ++- .../annotation/format/DateTimeFormat.java | 36 ++ .../excel/annotation/format/NumberFormat.java | 37 ++ .../annotation/write/style/ColumnWidth.java | 26 ++ .../write/style/ContentRowHeight.java | 27 ++ .../annotation/write/style/ContentStyle.java | 31 ++ .../annotation/write/style/HeadRowHeight.java | 26 ++ .../annotation/write/style/HeadStyle.java | 27 ++ .../excel/constant/ExcelXmlConstants.java | 8 +- .../excel/context/AnalysisContext.java | 2 +- .../excel/context/AnalysisContextImpl.java | 2 +- .../excel/context/WriteContextImpl.java | 27 +- .../alibaba/excel/converters/Converter.java | 10 +- ...ilder.java => DefaultConverterLoader.java} | 6 +- .../BigDecimalBooleanConverter.java | 6 +- .../bigdecimal/BigDecimalNumberConverter.java | 6 +- .../bigdecimal/BigDecimalStringConverter.java | 19 +- .../BooleanBooleanConverter.java | 6 +- .../BooleanNumberConverter.java | 6 +- .../BooleanStringConverter.java | 6 +- .../byteconverter/ByteBooleanConverter.java | 6 +- .../byteconverter/ByteNumberConverter.java | 6 +- .../byteconverter/ByteStringConverter.java | 6 +- .../converters/date/DateNumberConverter.java | 14 +- .../converters/date/DateStringConverter.java | 19 +- .../doubleconverter/ByteBooleanConverter.java | 6 +- .../doubleconverter/ByteNumberConverter.java | 35 -- .../DoubleNumberConverter.java | 35 ++ .../DoubleStringConverter.java | 6 +- .../string/StringStringConverter.java | 6 +- .../alibaba/excel/enums/CellDataTypeEnum.java | 6 +- .../excel/event/ModelBuildEventListener.java | 26 +- .../com/alibaba/excel/metadata/CellStyle.java | 13 + .../excel/metadata/ExcelColumnProperty.java | 105 ------ .../excel/metadata/ExcelHeadProperty.java | 287 -------------- .../java/com/alibaba/excel/metadata/Head.java | 43 ++- .../com/alibaba/excel/metadata/Workbook.java | 16 + .../holder/AbstractConfigurationSelector.java | 107 +++++- .../holder/ConfigurationSelector.java | 2 +- .../excel/metadata/holder/SheetHolder.java | 10 +- .../excel/metadata/holder/TableHolder.java | 9 +- .../excel/metadata/holder/WorkbookHolder.java | 33 +- .../metadata/property/CellStyleProperty.java | 84 +++++ .../property/ColumnWidthProperty.java | 31 ++ .../property/DateTimeFormatProperty.java | 41 ++ .../property/ExcelContentProperty.java | 62 ++++ .../metadata/property/ExcelHeadProperty.java | 350 ++++++++++++++++++ .../property/NumberFormatProperty.java | 43 +++ .../metadata/property/RowHeightProperty.java | 39 ++ .../com/alibaba/excel/util/StringUtils.java | 94 +++++ .../alibaba/excel/write/ExcelBuilderImpl.java | 95 +++-- .../write/builder/ExcelWriterBuilder.java | 22 +- .../excel/write/handler/CellWriteHandler.java | 16 +- ...er.java => DefaultWriteHandlerLoader.java} | 4 +- .../excel/write/handler/RowWriteHandler.java | 14 +- .../write/handler/SheetWriteHandler.java | 8 +- .../write/handler/WorkbookWriteHandler.java | 6 +- .../write/merge/AbstractMergeStrategy.java | 13 + .../style/AbstractCellStyleStrategy.java | 24 ++ .../AbstractColumnCellStyleStrategy.java | 39 +- .../AbstractColumnWidthStyleStrategy.java | 5 +- .../AbstractHeadColumnWidthStyleStrategy.java | 11 +- .../SimpleColumnWidthStyleStrategy.java | 8 +- ...va => AbstractRowHeightStyleStrategy.java} | 29 +- .../row/SimpleRowHeightStyleStrategy.java | 33 ++ .../style/row/SimpleRowHighStyleStrategy.java | 29 -- .../test/wirte/nohead/NoHeadData07Test.java | 40 ++ 72 files changed, 1671 insertions(+), 708 deletions(-) delete mode 100644 src/main/java/com/alibaba/excel/annotation/ExcelColumnNum.java create mode 100644 src/main/java/com/alibaba/excel/annotation/ExcelIgnore.java create mode 100644 src/main/java/com/alibaba/excel/annotation/format/DateTimeFormat.java create mode 100644 src/main/java/com/alibaba/excel/annotation/format/NumberFormat.java create mode 100644 src/main/java/com/alibaba/excel/annotation/write/style/ColumnWidth.java create mode 100644 src/main/java/com/alibaba/excel/annotation/write/style/ContentRowHeight.java create mode 100644 src/main/java/com/alibaba/excel/annotation/write/style/ContentStyle.java create mode 100644 src/main/java/com/alibaba/excel/annotation/write/style/HeadRowHeight.java create mode 100644 src/main/java/com/alibaba/excel/annotation/write/style/HeadStyle.java rename src/main/java/com/alibaba/excel/converters/{DefaultConverterBuilder.java => DefaultConverterLoader.java} (92%) delete mode 100644 src/main/java/com/alibaba/excel/converters/doubleconverter/ByteNumberConverter.java create mode 100644 src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleNumberConverter.java delete mode 100644 src/main/java/com/alibaba/excel/metadata/ExcelColumnProperty.java delete mode 100644 src/main/java/com/alibaba/excel/metadata/ExcelHeadProperty.java create mode 100644 src/main/java/com/alibaba/excel/metadata/property/CellStyleProperty.java create mode 100644 src/main/java/com/alibaba/excel/metadata/property/ColumnWidthProperty.java create mode 100644 src/main/java/com/alibaba/excel/metadata/property/DateTimeFormatProperty.java create mode 100644 src/main/java/com/alibaba/excel/metadata/property/ExcelContentProperty.java create mode 100644 src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java create mode 100644 src/main/java/com/alibaba/excel/metadata/property/NumberFormatProperty.java create mode 100644 src/main/java/com/alibaba/excel/metadata/property/RowHeightProperty.java rename src/main/java/com/alibaba/excel/write/handler/{DefaultWriteHandlerBuilder.java => DefaultWriteHandlerLoader.java} (93%) rename src/main/java/com/alibaba/excel/write/style/row/{AbstractRowHighStyleStrategy.java => AbstractRowHeightStyleStrategy.java} (54%) create mode 100644 src/main/java/com/alibaba/excel/write/style/row/SimpleRowHeightStyleStrategy.java delete mode 100644 src/main/java/com/alibaba/excel/write/style/row/SimpleRowHighStyleStrategy.java create mode 100644 src/test/java/com/alibaba/easyexcel/test/wirte/nohead/NoHeadData07Test.java diff --git a/src/main/java/com/alibaba/excel/EasyExcelFactory.java b/src/main/java/com/alibaba/excel/EasyExcelFactory.java index aa6cfa1e..d6229bbf 100644 --- a/src/main/java/com/alibaba/excel/EasyExcelFactory.java +++ b/src/main/java/com/alibaba/excel/EasyExcelFactory.java @@ -81,7 +81,8 @@ public class EasyExcelFactory { */ @Deprecated public static ExcelWriter getWriter(OutputStream outputStream) { - return writerBuilder().outputFile(outputStream).autoCloseStream(Boolean.FALSE).build(); + return writerBuilder().outputFile(outputStream).autoCloseStream(Boolean.FALSE).convertAllFiled(Boolean.FALSE) + .build(); } /** @@ -99,7 +100,7 @@ public class EasyExcelFactory { @Deprecated public static ExcelWriter getWriter(OutputStream outputStream, ExcelTypeEnum typeEnum, boolean needHead) { return writerBuilder().outputFile(outputStream).excelType(typeEnum).needHead(needHead) - .autoCloseStream(Boolean.FALSE).build(); + .autoCloseStream(Boolean.FALSE).convertAllFiled(Boolean.FALSE).build(); } /** @@ -119,7 +120,7 @@ public class EasyExcelFactory { public static ExcelWriter getWriterWithTemp(InputStream temp, OutputStream outputStream, ExcelTypeEnum typeEnum, boolean needHead) { return writerBuilder().withTemplate(temp).outputFile(outputStream).excelType(typeEnum).needHead(needHead) - .autoCloseStream(Boolean.FALSE).build(); + .autoCloseStream(Boolean.FALSE).convertAllFiled(Boolean.FALSE).build(); } /** @@ -142,7 +143,7 @@ public class EasyExcelFactory { public static ExcelWriter getWriterWithTempAndHandler(InputStream temp, OutputStream outputStream, ExcelTypeEnum typeEnum, boolean needHead, WriteHandler handler) { return writerBuilder().withTemplate(temp).outputFile(outputStream).excelType(typeEnum).needHead(needHead) - .registerWriteHandler(handler).autoCloseStream(Boolean.FALSE).build(); + .registerWriteHandler(handler).autoCloseStream(Boolean.FALSE).convertAllFiled(Boolean.FALSE).build(); } public static ExcelWriterBuilder writerBuilder() { diff --git a/src/main/java/com/alibaba/excel/analysis/BaseSaxAnalyser.java b/src/main/java/com/alibaba/excel/analysis/BaseSaxAnalyser.java index 8db4a89b..678cdfc5 100644 --- a/src/main/java/com/alibaba/excel/analysis/BaseSaxAnalyser.java +++ b/src/main/java/com/alibaba/excel/analysis/BaseSaxAnalyser.java @@ -1,6 +1,5 @@ package com.alibaba.excel.analysis; -import java.util.Collection; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; @@ -11,14 +10,11 @@ import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.ConverterKey; import com.alibaba.excel.converters.ConverterRegistryCenter; -import com.alibaba.excel.converters.DefaultConverterBuilder; -import com.alibaba.excel.converters.bigdecimal.BigDecimalBooleanConverter; -import com.alibaba.excel.converters.bigdecimal.BigDecimalNumberConverter; -import com.alibaba.excel.converters.string.StringStringConverter; +import com.alibaba.excel.converters.DefaultConverterLoader; import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.event.AnalysisEventRegistryCenter; import com.alibaba.excel.event.AnalysisFinishEvent; -import com.alibaba.excel.metadata.ExcelHeadProperty; +import com.alibaba.excel.metadata.property.ExcelHeadProperty; import com.alibaba.excel.metadata.Sheet; /** @@ -56,7 +52,7 @@ public abstract class BaseSaxAnalyser implements ConverterRegistryCenter, Analys } private void registerDefaultConverters() { - converters.putAll(DefaultConverterBuilder.loadDefaultReadConverter()); + converters.putAll(DefaultConverterLoader.loadDefaultReadConverter()); } @Override diff --git a/src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java index 21353113..275d9337 100644 --- a/src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java @@ -1,15 +1,16 @@ package com.alibaba.excel.analysis.v07.handlers; import static com.alibaba.excel.constant.ExcelXmlConstants.CELL_FORMULA_TAG; +import static com.alibaba.excel.constant.ExcelXmlConstants.CELL_INLINE_STRING_VALUE_TAG; import static com.alibaba.excel.constant.ExcelXmlConstants.CELL_TAG; import static com.alibaba.excel.constant.ExcelXmlConstants.CELL_VALUE_TAG; -import static com.alibaba.excel.constant.ExcelXmlConstants.CELL_VALUE_TAG_1; import static com.alibaba.excel.constant.ExcelXmlConstants.CELL_VALUE_TYPE_TAG; import java.util.Arrays; import org.apache.poi.ss.usermodel.RichTextString; import org.apache.poi.xssf.model.SharedStringsTable; +import org.apache.poi.xssf.usermodel.XSSFRichTextString; import org.xml.sax.Attributes; import com.alibaba.excel.analysis.v07.XlsxCellHandler; @@ -48,7 +49,7 @@ public class DefaultCellHandler implements XlsxCellHandler, XlsxRowResultHolder @Override public boolean support(String name) { - return CELL_VALUE_TAG.equals(name) || CELL_FORMULA_TAG.equals(name) || CELL_VALUE_TAG_1.equals(name) + return CELL_VALUE_TAG.equals(name) || CELL_FORMULA_TAG.equals(name) || CELL_INLINE_STRING_VALUE_TAG.equals(name) || CELL_TAG.equals(name); } @@ -61,13 +62,14 @@ public class DefaultCellHandler implements XlsxCellHandler, XlsxRowResultHolder int nextRow = PositionUtils.getRow(currentCellIndex); if (nextRow > curRow) { curRow = nextRow; - // endRow(ROW_TAG); } analysisContext.setCurrentRowNum(curRow); curCol = PositionUtils.getCol(currentCellIndex); // t="s" ,it's means String + // t="inlineStr" ,it's means String // t="b" ,it's means Boolean + // t="e" ,it's means Error // t is null ,it's means Empty or Number CellDataTypeEnum type = CellDataTypeEnum.buildFromCellType(attributes.getValue(CELL_VALUE_TYPE_TAG)); currentCellData = new CellData(type); @@ -89,6 +91,13 @@ public class DefaultCellHandler implements XlsxCellHandler, XlsxRowResultHolder } curRowContent[curCol] = currentCellData; } + // This is a special form of string + if (CELL_INLINE_STRING_VALUE_TAG.equals(name)) { + ensureSize(); + XSSFRichTextString richTextString = new XSSFRichTextString(currentCellData.getStringValue()); + currentCellData.setStringValue(richTextString.toString()); + curRowContent[curCol] = currentCellData; + } } private void ensureSize() { diff --git a/src/main/java/com/alibaba/excel/annotation/ExcelColumnNum.java b/src/main/java/com/alibaba/excel/annotation/ExcelColumnNum.java deleted file mode 100644 index eb56fe38..00000000 --- a/src/main/java/com/alibaba/excel/annotation/ExcelColumnNum.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.alibaba.excel.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Created by jipengfei on 17/3/19. - * Field column num at excel head - * - * @author jipengfei - */ -@Target(ElementType.FIELD) -@Retention(RetentionPolicy.RUNTIME) -@Inherited -public @interface ExcelColumnNum { - - /** - * col num - * @return - */ - int value(); - - /** - * - * Default @see com.alibaba.excel.util.TypeUtil - * if default is not meet you can set format - * - * @return - */ - String format() default ""; -} diff --git a/src/main/java/com/alibaba/excel/annotation/ExcelIgnore.java b/src/main/java/com/alibaba/excel/annotation/ExcelIgnore.java new file mode 100644 index 00000000..19666a65 --- /dev/null +++ b/src/main/java/com/alibaba/excel/annotation/ExcelIgnore.java @@ -0,0 +1,17 @@ +package com.alibaba.excel.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Ignore convert excel + * + * @author zhuangjiaju + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@Inherited +public @interface ExcelIgnore {} diff --git a/src/main/java/com/alibaba/excel/annotation/ExcelProperty.java b/src/main/java/com/alibaba/excel/annotation/ExcelProperty.java index 7b1cb273..a977aa28 100644 --- a/src/main/java/com/alibaba/excel/annotation/ExcelProperty.java +++ b/src/main/java/com/alibaba/excel/annotation/ExcelProperty.java @@ -14,20 +14,32 @@ import java.lang.annotation.Target; @Inherited public @interface ExcelProperty { - /** - * @return - */ - String[] value() default {""}; - /** - * @return - */ - int index() default 99999; - /** - * - * default @see com.alibaba.excel.util.TypeUtil - * if default is not meet you can set format - * - * @return - */ - String format() default ""; + /** + * The name of the sheet header. + * + *
  • write: It automatically merges when you have more than one head + *
  • read: When you have multiple heads, take the first one + * + * @return + */ + String[] value() default {""}; + + /** + * Index of column + * + * Read or write it on the index of column,If it's equal to -1, it's sorted by Java class + * + * @return + */ + int index() default -1; + + /** + * + * default @see com.alibaba.excel.util.TypeUtil if default is not meet you can set format + * + * @return + * @deprecated please use {@link com.alibaba.excel.annotation.format.DateTimeFormat} + */ + @Deprecated + String format() default ""; } diff --git a/src/main/java/com/alibaba/excel/annotation/format/DateTimeFormat.java b/src/main/java/com/alibaba/excel/annotation/format/DateTimeFormat.java new file mode 100644 index 00000000..92c1e7cc --- /dev/null +++ b/src/main/java/com/alibaba/excel/annotation/format/DateTimeFormat.java @@ -0,0 +1,36 @@ +package com.alibaba.excel.annotation.format; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Convert date format. + * + *
  • write: It can be used on classes {@link java.util.Date} + *
  • read: It can be used on classes {@link String} + * + * @author zhuangjiaju + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@Inherited +public @interface DateTimeFormat { + + /** + * + * Specific format reference {@link java.text.SimpleDateFormat} + * + * @return + */ + String value() default ""; + + /** + * true if date uses 1904 windowing, or false if using 1900 date windowing. + * + * @return + */ + boolean use1904windowing() default false; +} diff --git a/src/main/java/com/alibaba/excel/annotation/format/NumberFormat.java b/src/main/java/com/alibaba/excel/annotation/format/NumberFormat.java new file mode 100644 index 00000000..996fbb91 --- /dev/null +++ b/src/main/java/com/alibaba/excel/annotation/format/NumberFormat.java @@ -0,0 +1,37 @@ +package com.alibaba.excel.annotation.format; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.math.RoundingMode; + +/** + * Convert number format. + * + *
  • write: It can be used on classes that inherit {@link Number} + *
  • read: It can be used on classes {@link String} + * + * @author zhuangjiaju + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@Inherited +public @interface NumberFormat { + + /** + * + * Specific format reference {@link org.apache.commons.math3.fraction.BigFractionFormat} + * + * @return + */ + String value() default ""; + + /** + * Rounded by default + * + * @return + */ + RoundingMode roundingMode() default RoundingMode.HALF_UP; +} diff --git a/src/main/java/com/alibaba/excel/annotation/write/style/ColumnWidth.java b/src/main/java/com/alibaba/excel/annotation/write/style/ColumnWidth.java new file mode 100644 index 00000000..8661add5 --- /dev/null +++ b/src/main/java/com/alibaba/excel/annotation/write/style/ColumnWidth.java @@ -0,0 +1,26 @@ +package com.alibaba.excel.annotation.write.style; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Set the width of the table + * + * @author zhuangjiaju + */ +@Target({ElementType.FIELD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Inherited +public @interface ColumnWidth { + /** + * Using the Calibri font as an example, the maximum digit width of 11 point font size is 7 pixels (at 96 dpi). If + * you set a column width to be 8 characters wide, e.g. 8*256 + * + *

    + * -1 mean the auto set width + */ + int value() default -1; +} diff --git a/src/main/java/com/alibaba/excel/annotation/write/style/ContentRowHeight.java b/src/main/java/com/alibaba/excel/annotation/write/style/ContentRowHeight.java new file mode 100644 index 00000000..cf3be9bd --- /dev/null +++ b/src/main/java/com/alibaba/excel/annotation/write/style/ContentRowHeight.java @@ -0,0 +1,27 @@ +package com.alibaba.excel.annotation.write.style; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Set the height of each table + * + * @author zhuangjiaju + */ +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Inherited +public @interface ContentRowHeight { + + /** + * Set the content height + *

    + * -1 mean the auto set height + * + * @return + */ + short value() default -1; +} diff --git a/src/main/java/com/alibaba/excel/annotation/write/style/ContentStyle.java b/src/main/java/com/alibaba/excel/annotation/write/style/ContentStyle.java new file mode 100644 index 00000000..73fbfc93 --- /dev/null +++ b/src/main/java/com/alibaba/excel/annotation/write/style/ContentStyle.java @@ -0,0 +1,31 @@ +package com.alibaba.excel.annotation.write.style; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.apache.poi.ss.usermodel.IndexedColors; + +/** + * Convert number format. + * + *

  • write: It can be used on classes that inherit {@link Number} + *
  • read: It can be used on classes {@link String} + * + * @author zhuangjiaju + */ +@Target({ElementType.FIELD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Inherited +public @interface ContentStyle { + + String fontName() default "宋体"; + + short fontHeightInPoints() default (short)14; + + boolean bold() default true; + + IndexedColors indexedColors() default IndexedColors.WHITE1; +} diff --git a/src/main/java/com/alibaba/excel/annotation/write/style/HeadRowHeight.java b/src/main/java/com/alibaba/excel/annotation/write/style/HeadRowHeight.java new file mode 100644 index 00000000..d5ccedb8 --- /dev/null +++ b/src/main/java/com/alibaba/excel/annotation/write/style/HeadRowHeight.java @@ -0,0 +1,26 @@ +package com.alibaba.excel.annotation.write.style; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Set the height of each table + * + * @author zhuangjiaju + */ +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Inherited +public @interface HeadRowHeight { + /** + * Set the header height + *

    + * -1 mean the auto set height + * + * @return + */ + short value() default -1; +} diff --git a/src/main/java/com/alibaba/excel/annotation/write/style/HeadStyle.java b/src/main/java/com/alibaba/excel/annotation/write/style/HeadStyle.java new file mode 100644 index 00000000..f717e932 --- /dev/null +++ b/src/main/java/com/alibaba/excel/annotation/write/style/HeadStyle.java @@ -0,0 +1,27 @@ +package com.alibaba.excel.annotation.write.style; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.apache.poi.ss.usermodel.IndexedColors; + +/** + * 配置 + * + * @author zhuangjiaju + */ +@Target({ElementType.FIELD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Inherited +public @interface HeadStyle { + String fontName() default "宋体"; + + short fontHeightInPoints() default (short)14; + + boolean bold() default true; + + IndexedColors indexedColors() default IndexedColors.GREY_25_PERCENT; +} diff --git a/src/main/java/com/alibaba/excel/constant/ExcelXmlConstants.java b/src/main/java/com/alibaba/excel/constant/ExcelXmlConstants.java index b3e7c200..55d522fa 100644 --- a/src/main/java/com/alibaba/excel/constant/ExcelXmlConstants.java +++ b/src/main/java/com/alibaba/excel/constant/ExcelXmlConstants.java @@ -10,10 +10,12 @@ public class ExcelXmlConstants { public static final String ROW_TAG = "row"; public static final String CELL_TAG = "c"; + public static final String CELL_VALUE_TYPE_TAG = "t"; public static final String CELL_FORMULA_TAG = "f"; public static final String CELL_VALUE_TAG = "v"; - public static final String CELL_VALUE_TYPE_TAG = "t"; - - public static final String CELL_VALUE_TAG_1 = "t"; + /** + * When the data is "inlineStr" his tag is "t" + */ + public static final String CELL_INLINE_STRING_VALUE_TAG = "t"; } diff --git a/src/main/java/com/alibaba/excel/context/AnalysisContext.java b/src/main/java/com/alibaba/excel/context/AnalysisContext.java index 74e3782d..6025d24f 100644 --- a/src/main/java/com/alibaba/excel/context/AnalysisContext.java +++ b/src/main/java/com/alibaba/excel/context/AnalysisContext.java @@ -4,7 +4,7 @@ import java.io.InputStream; import com.alibaba.excel.converters.ConverterRegistryCenter; import com.alibaba.excel.event.AnalysisEventListener; -import com.alibaba.excel.metadata.ExcelHeadProperty; +import com.alibaba.excel.metadata.property.ExcelHeadProperty; import com.alibaba.excel.metadata.Sheet; import com.alibaba.excel.support.ExcelTypeEnum; diff --git a/src/main/java/com/alibaba/excel/context/AnalysisContextImpl.java b/src/main/java/com/alibaba/excel/context/AnalysisContextImpl.java index b7f721e4..b5e6a5de 100644 --- a/src/main/java/com/alibaba/excel/context/AnalysisContextImpl.java +++ b/src/main/java/com/alibaba/excel/context/AnalysisContextImpl.java @@ -5,7 +5,7 @@ import java.io.InputStream; import com.alibaba.excel.converters.ConverterRegistryCenter; import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.exception.ExcelAnalysisException; -import com.alibaba.excel.metadata.ExcelHeadProperty; +import com.alibaba.excel.metadata.property.ExcelHeadProperty; import com.alibaba.excel.metadata.Sheet; import com.alibaba.excel.support.ExcelTypeEnum; diff --git a/src/main/java/com/alibaba/excel/context/WriteContextImpl.java b/src/main/java/com/alibaba/excel/context/WriteContextImpl.java index 44757eeb..df28d9f9 100644 --- a/src/main/java/com/alibaba/excel/context/WriteContextImpl.java +++ b/src/main/java/com/alibaba/excel/context/WriteContextImpl.java @@ -2,6 +2,7 @@ package com.alibaba.excel.context; import java.io.IOException; import java.util.List; +import java.util.Map; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; @@ -11,13 +12,13 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.excel.exception.ExcelGenerateException; -import com.alibaba.excel.metadata.ExcelHeadProperty; import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.Table; import com.alibaba.excel.metadata.holder.ConfigurationSelector; import com.alibaba.excel.metadata.holder.SheetHolder; import com.alibaba.excel.metadata.holder.TableHolder; import com.alibaba.excel.metadata.holder.WorkbookHolder; +import com.alibaba.excel.metadata.property.ExcelHeadProperty; import com.alibaba.excel.util.WorkBookUtil; import com.alibaba.excel.write.handler.CellWriteHandler; import com.alibaba.excel.write.handler.RowWriteHandler; @@ -184,9 +185,6 @@ public class WriteContextImpl implements WriteContext { } currentSheetHolder.setSheet(currentSheet); // Initialization head - currentSheetHolder - .setExcelHeadProperty(new ExcelHeadProperty(currentSheetHolder.getClazz(), currentSheetHolder.getHead())); - // Initialization head initHead(currentSheetHolder.getExcelHeadProperty()); } @@ -203,7 +201,7 @@ public class WriteContextImpl implements WriteContext { beforeRowCreate(rowIndex, relativeRowIndex); Row row = WorkBookUtil.createRow(currentSheetHolder.getSheet(), i); afterRowCreate(row, relativeRowIndex); - addOneRowOfHeadDataToExcel(row, excelHeadProperty.getHeadList(), relativeRowIndex); + addOneRowOfHeadDataToExcel(row, excelHeadProperty.getHeadMap(), relativeRowIndex); } } @@ -237,18 +235,18 @@ public class WriteContextImpl implements WriteContext { } private void addMergedRegionToCurrentSheet(ExcelHeadProperty excelHeadProperty, int rowIndex) { - for (com.alibaba.excel.metadata.CellRange cellRangeModel : excelHeadProperty.getCellRangeModels()) { + for (com.alibaba.excel.metadata.CellRange cellRangeModel : excelHeadProperty.headCellRangeList()) { currentSheetHolder.getSheet().addMergedRegion(new CellRangeAddress(cellRangeModel.getFirstRow() + rowIndex, cellRangeModel.getLastRow() + rowIndex, cellRangeModel.getFirstCol(), cellRangeModel.getLastCol())); } } - private void addOneRowOfHeadDataToExcel(Row row, List headList, int relativeRowIndex) { - for (int i = 0; i < headList.size(); i++) { - Head head = headList.get(i); - beforeCellCreate(row, headList.get(i), relativeRowIndex); - Cell cell = WorkBookUtil.createCell(row, i, head.getHeadName(i)); - afterCellCreate(headList.get(i), cell, relativeRowIndex); + private void addOneRowOfHeadDataToExcel(Row row, Map headMap, int relativeRowIndex) { + for (Map.Entry entry : headMap.entrySet()) { + Head head = entry.getValue(); + beforeCellCreate(row, head, relativeRowIndex); + Cell cell = WorkBookUtil.createCell(row, entry.getKey(), head.getHeadNameList().get(relativeRowIndex)); + afterCellCreate(head, cell, relativeRowIndex); } } @@ -302,14 +300,11 @@ public class WriteContextImpl implements WriteContext { return; } initCurrentTableHolder(table); - // Initialization head - currentTableHolder - .setExcelHeadProperty(new ExcelHeadProperty(currentTableHolder.getClazz(), currentTableHolder.getHead())); initHead(currentTableHolder.getExcelHeadProperty()); } private void initCurrentTableHolder(com.alibaba.excel.metadata.Table table) { - currentTableHolder = new TableHolder(table, currentSheetHolder); + currentTableHolder = new TableHolder(table, currentSheetHolder, currentWorkbookHolder); currentSheetHolder.getHasBeenInitializedTable().put(table.getTableNo(), currentTableHolder); currentConfigurationSelector = currentTableHolder; if (LOGGER.isDebugEnabled()) { diff --git a/src/main/java/com/alibaba/excel/converters/Converter.java b/src/main/java/com/alibaba/excel/converters/Converter.java index d61938c1..16c36eae 100644 --- a/src/main/java/com/alibaba/excel/converters/Converter.java +++ b/src/main/java/com/alibaba/excel/converters/Converter.java @@ -2,7 +2,7 @@ package com.alibaba.excel.converters; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.CellData; -import com.alibaba.excel.metadata.ExcelColumnProperty; +import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.sun.istack.internal.NotNull; import com.sun.istack.internal.Nullable; @@ -32,19 +32,19 @@ public interface Converter { * Convert excel objects to Java objects * * @param cellData - * @param columnProperty + * @param contentProperty * @return * @throws Exception */ - T convertToJavaData(@NotNull CellData cellData, @Nullable ExcelColumnProperty columnProperty) throws Exception; + T convertToJavaData(@NotNull CellData cellData, @Nullable ExcelContentProperty contentProperty) throws Exception; /** * Convert Java objects to excel objects * * @param value - * @param columnProperty + * @param contentProperty * @return * @throws Exception */ - CellData convertToExcelData(@NotNull T value, @Nullable ExcelColumnProperty columnProperty) throws Exception; + CellData convertToExcelData(@NotNull T value, @Nullable ExcelContentProperty contentProperty) throws Exception; } diff --git a/src/main/java/com/alibaba/excel/converters/DefaultConverterBuilder.java b/src/main/java/com/alibaba/excel/converters/DefaultConverterLoader.java similarity index 92% rename from src/main/java/com/alibaba/excel/converters/DefaultConverterBuilder.java rename to src/main/java/com/alibaba/excel/converters/DefaultConverterLoader.java index 37e7240a..82dcfe97 100644 --- a/src/main/java/com/alibaba/excel/converters/DefaultConverterBuilder.java +++ b/src/main/java/com/alibaba/excel/converters/DefaultConverterLoader.java @@ -8,13 +8,13 @@ import com.alibaba.excel.converters.date.DateStringConverter; import com.alibaba.excel.converters.string.StringStringConverter; /** - * Build default handler + * Load default handler * * @author zhuangjiaju */ -public class DefaultConverterBuilder { +public class DefaultConverterLoader { /** - * Load default wirte converter + * Load default write converter * * @return */ diff --git a/src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalBooleanConverter.java b/src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalBooleanConverter.java index ac3453b7..9ce47701 100644 --- a/src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalBooleanConverter.java +++ b/src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalBooleanConverter.java @@ -5,7 +5,7 @@ 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.ExcelColumnProperty; +import com.alibaba.excel.metadata.property.ExcelContentProperty; /** * BigDecimal and boolean converter @@ -25,7 +25,7 @@ public class BigDecimalBooleanConverter implements Converter { } @Override - public BigDecimal convertToJavaData(CellData cellData, ExcelColumnProperty columnProperty) { + public BigDecimal convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) { if (cellData.getBooleanValue()) { return BigDecimal.ONE; } @@ -33,7 +33,7 @@ public class BigDecimalBooleanConverter implements Converter { } @Override - public CellData convertToExcelData(BigDecimal value, ExcelColumnProperty columnProperty) { + public CellData convertToExcelData(BigDecimal value, ExcelContentProperty contentProperty) { if (BigDecimal.ONE.equals(value)) { return new CellData(Boolean.TRUE); } 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 09ef24c1..ba3a3bc8 100644 --- a/src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalNumberConverter.java +++ b/src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalNumberConverter.java @@ -5,7 +5,7 @@ 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.ExcelColumnProperty; +import com.alibaba.excel.metadata.property.ExcelContentProperty; /** * BigDecimal and number converter @@ -25,12 +25,12 @@ public class BigDecimalNumberConverter implements Converter { } @Override - public BigDecimal convertToJavaData(CellData cellData, ExcelColumnProperty columnProperty) { + public BigDecimal convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) { return new BigDecimal(cellData.getDoubleValue()); } @Override - public CellData convertToExcelData(BigDecimal value, ExcelColumnProperty columnProperty) { + public CellData convertToExcelData(BigDecimal value, ExcelContentProperty contentProperty) { return new CellData(value.doubleValue()); } } 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 2e327c4c..b71e8b0b 100644 --- a/src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalStringConverter.java +++ b/src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalStringConverter.java @@ -1,12 +1,13 @@ package com.alibaba.excel.converters.bigdecimal; import java.math.BigDecimal; +import java.math.RoundingMode; import java.text.DecimalFormat; import com.alibaba.excel.converters.Converter; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.CellData; -import com.alibaba.excel.metadata.ExcelColumnProperty; +import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.util.StringUtils; /** @@ -27,15 +28,23 @@ public class BigDecimalStringConverter implements Converter { } @Override - public BigDecimal convertToJavaData(CellData cellData, ExcelColumnProperty columnProperty) { + public BigDecimal convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) { return new BigDecimal(cellData.getStringValue()); } @Override - public CellData convertToExcelData(BigDecimal value, ExcelColumnProperty columnProperty) { - if (StringUtils.isEmpty(columnProperty.getFormat())) { + public CellData convertToExcelData(BigDecimal value, ExcelContentProperty contentProperty) { + String format = null; + RoundingMode roundingMode = RoundingMode.HALF_UP; + if (contentProperty.getNumberFormatProperty() != null) { + format = contentProperty.getNumberFormatProperty().getFormat(); + roundingMode = contentProperty.getNumberFormatProperty().getRoundingMode(); + } + if (StringUtils.isEmpty(format)) { return new CellData(value.toString()); } - return new CellData(new DecimalFormat(columnProperty.getFormat()).format(value)); + DecimalFormat decimalFormat = new DecimalFormat(format); + decimalFormat.setRoundingMode(roundingMode); + return new CellData(decimalFormat.format(value)); } } diff --git a/src/main/java/com/alibaba/excel/converters/booleanconverter/BooleanBooleanConverter.java b/src/main/java/com/alibaba/excel/converters/booleanconverter/BooleanBooleanConverter.java index fb8188c7..2d014099 100644 --- a/src/main/java/com/alibaba/excel/converters/booleanconverter/BooleanBooleanConverter.java +++ b/src/main/java/com/alibaba/excel/converters/booleanconverter/BooleanBooleanConverter.java @@ -3,7 +3,7 @@ package com.alibaba.excel.converters.booleanconverter; import com.alibaba.excel.converters.Converter; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.CellData; -import com.alibaba.excel.metadata.ExcelColumnProperty; +import com.alibaba.excel.metadata.property.ExcelContentProperty; /** * Boolean and boolean converter @@ -23,12 +23,12 @@ public class BooleanBooleanConverter implements Converter { } @Override - public Boolean convertToJavaData(CellData cellData, ExcelColumnProperty columnProperty) { + public Boolean convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) { return cellData.getBooleanValue(); } @Override - public CellData convertToExcelData(Boolean value, ExcelColumnProperty columnProperty) { + public CellData convertToExcelData(Boolean value, ExcelContentProperty contentProperty) { return new CellData(value); } diff --git a/src/main/java/com/alibaba/excel/converters/booleanconverter/BooleanNumberConverter.java b/src/main/java/com/alibaba/excel/converters/booleanconverter/BooleanNumberConverter.java index 800b63cc..02d297fe 100644 --- a/src/main/java/com/alibaba/excel/converters/booleanconverter/BooleanNumberConverter.java +++ b/src/main/java/com/alibaba/excel/converters/booleanconverter/BooleanNumberConverter.java @@ -3,7 +3,7 @@ package com.alibaba.excel.converters.booleanconverter; import com.alibaba.excel.converters.Converter; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.CellData; -import com.alibaba.excel.metadata.ExcelColumnProperty; +import com.alibaba.excel.metadata.property.ExcelContentProperty; /** * Boolean and number converter @@ -26,7 +26,7 @@ public class BooleanNumberConverter implements Converter { } @Override - public Boolean convertToJavaData(CellData cellData, ExcelColumnProperty columnProperty) { + public Boolean convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) { if (ONE.equals(cellData.getDoubleValue())) { return Boolean.TRUE; } @@ -34,7 +34,7 @@ public class BooleanNumberConverter implements Converter { } @Override - public CellData convertToExcelData(Boolean value, ExcelColumnProperty columnProperty) { + public CellData convertToExcelData(Boolean value, ExcelContentProperty contentProperty) { if (value) { return new CellData(ONE); } diff --git a/src/main/java/com/alibaba/excel/converters/booleanconverter/BooleanStringConverter.java b/src/main/java/com/alibaba/excel/converters/booleanconverter/BooleanStringConverter.java index b9fd8bc4..6a4fcff6 100644 --- a/src/main/java/com/alibaba/excel/converters/booleanconverter/BooleanStringConverter.java +++ b/src/main/java/com/alibaba/excel/converters/booleanconverter/BooleanStringConverter.java @@ -3,7 +3,7 @@ package com.alibaba.excel.converters.booleanconverter; import com.alibaba.excel.converters.Converter; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.CellData; -import com.alibaba.excel.metadata.ExcelColumnProperty; +import com.alibaba.excel.metadata.property.ExcelContentProperty; /** * Boolean and string converter @@ -23,12 +23,12 @@ public class BooleanStringConverter implements Converter { } @Override - public Boolean convertToJavaData(CellData cellData, ExcelColumnProperty columnProperty) { + public Boolean convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) { return Boolean.valueOf(cellData.getStringValue()); } @Override - public CellData convertToExcelData(Boolean value, ExcelColumnProperty columnProperty) { + public CellData convertToExcelData(Boolean value, ExcelContentProperty contentProperty) { return new CellData(value.toString()); } diff --git a/src/main/java/com/alibaba/excel/converters/byteconverter/ByteBooleanConverter.java b/src/main/java/com/alibaba/excel/converters/byteconverter/ByteBooleanConverter.java index c41a584a..cf115e4e 100644 --- a/src/main/java/com/alibaba/excel/converters/byteconverter/ByteBooleanConverter.java +++ b/src/main/java/com/alibaba/excel/converters/byteconverter/ByteBooleanConverter.java @@ -3,7 +3,7 @@ package com.alibaba.excel.converters.byteconverter; import com.alibaba.excel.converters.Converter; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.CellData; -import com.alibaba.excel.metadata.ExcelColumnProperty; +import com.alibaba.excel.metadata.property.ExcelContentProperty; /** * Byte and boolean converter @@ -25,7 +25,7 @@ public class ByteBooleanConverter implements Converter { } @Override - public Byte convertToJavaData(CellData cellData, ExcelColumnProperty columnProperty) { + public Byte convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) { if (cellData.getBooleanValue()) { return ONE; } @@ -33,7 +33,7 @@ public class ByteBooleanConverter implements Converter { } @Override - public CellData convertToExcelData(Byte value, ExcelColumnProperty columnProperty) { + public CellData convertToExcelData(Byte value, ExcelContentProperty contentProperty) { if (ONE.equals(value)) { return new CellData(Boolean.TRUE); } 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 0d54d720..262b49f5 100644 --- a/src/main/java/com/alibaba/excel/converters/byteconverter/ByteNumberConverter.java +++ b/src/main/java/com/alibaba/excel/converters/byteconverter/ByteNumberConverter.java @@ -3,7 +3,7 @@ package com.alibaba.excel.converters.byteconverter; import com.alibaba.excel.converters.Converter; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.CellData; -import com.alibaba.excel.metadata.ExcelColumnProperty; +import com.alibaba.excel.metadata.property.ExcelContentProperty; /** * Byte and number converter @@ -23,12 +23,12 @@ public class ByteNumberConverter implements Converter { } @Override - public Byte convertToJavaData(CellData cellData, ExcelColumnProperty columnProperty) { + public Byte convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) { return cellData.getDoubleValue().byteValue(); } @Override - public CellData convertToExcelData(Byte value, ExcelColumnProperty columnProperty) { + public CellData convertToExcelData(Byte value, ExcelContentProperty contentProperty) { return new CellData((double)value); } 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 9cd02276..61b85d74 100644 --- a/src/main/java/com/alibaba/excel/converters/byteconverter/ByteStringConverter.java +++ b/src/main/java/com/alibaba/excel/converters/byteconverter/ByteStringConverter.java @@ -3,7 +3,7 @@ package com.alibaba.excel.converters.byteconverter; import com.alibaba.excel.converters.Converter; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.CellData; -import com.alibaba.excel.metadata.ExcelColumnProperty; +import com.alibaba.excel.metadata.property.ExcelContentProperty; /** * Byte and string converter @@ -23,12 +23,12 @@ public class ByteStringConverter implements Converter { } @Override - public Byte convertToJavaData(CellData cellData, ExcelColumnProperty columnProperty) { + public Byte convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) { return Byte.valueOf(cellData.getStringValue()); } @Override - public CellData convertToExcelData(Byte value, ExcelColumnProperty columnProperty) { + public CellData convertToExcelData(Byte value, ExcelContentProperty contentProperty) { return new CellData(value.toString()); } diff --git a/src/main/java/com/alibaba/excel/converters/date/DateNumberConverter.java b/src/main/java/com/alibaba/excel/converters/date/DateNumberConverter.java index e784e609..63c96d3e 100644 --- a/src/main/java/com/alibaba/excel/converters/date/DateNumberConverter.java +++ b/src/main/java/com/alibaba/excel/converters/date/DateNumberConverter.java @@ -7,7 +7,7 @@ import org.apache.poi.hssf.usermodel.HSSFDateUtil; import com.alibaba.excel.converters.Converter; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.CellData; -import com.alibaba.excel.metadata.ExcelColumnProperty; +import com.alibaba.excel.metadata.property.ExcelContentProperty; /** * Date and number converter @@ -27,13 +27,17 @@ public class DateNumberConverter implements Converter { } @Override - public Date convertToJavaData(CellData cellData, ExcelColumnProperty columnProperty) { - return HSSFDateUtil.getJavaDate(cellData.getDoubleValue(), columnProperty.getUse1904windowing(), - columnProperty.getTimeZone()); + public Date convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) { + if (contentProperty.getDateTimeFormatProperty() == null) { + return HSSFDateUtil.getJavaDate(cellData.getDoubleValue(), false, null); + } else { + return HSSFDateUtil.getJavaDate(cellData.getDoubleValue(), + contentProperty.getDateTimeFormatProperty().getUse1904windowing(), null); + } } @Override - public CellData convertToExcelData(Date value, ExcelColumnProperty columnProperty) { + public CellData convertToExcelData(Date value, ExcelContentProperty contentProperty) { return new CellData((double)(value.getTime())); } } diff --git a/src/main/java/com/alibaba/excel/converters/date/DateStringConverter.java b/src/main/java/com/alibaba/excel/converters/date/DateStringConverter.java index f346c4c3..ee31a0b6 100644 --- a/src/main/java/com/alibaba/excel/converters/date/DateStringConverter.java +++ b/src/main/java/com/alibaba/excel/converters/date/DateStringConverter.java @@ -6,7 +6,7 @@ import java.util.Date; import com.alibaba.excel.converters.Converter; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.CellData; -import com.alibaba.excel.metadata.ExcelColumnProperty; +import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.util.DateUtils; /** @@ -26,12 +26,21 @@ public class DateStringConverter implements Converter { } @Override - public Date convertToJavaData(CellData cellData, ExcelColumnProperty columnProperty) throws ParseException { - return DateUtils.parseDate(cellData.getStringValue(), columnProperty.getFormat()); + public Date convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) throws ParseException { + if (contentProperty.getDateTimeFormatProperty() == null) { + return DateUtils.parseDate(cellData.getStringValue(), null); + } else { + return DateUtils.parseDate(cellData.getStringValue(), + contentProperty.getDateTimeFormatProperty().getFormat()); + } } @Override - public CellData convertToExcelData(Date value, ExcelColumnProperty columnProperty) { - return new CellData(DateUtils.format(value, columnProperty.getFormat())); + public CellData convertToExcelData(Date value, ExcelContentProperty contentProperty) { + if (contentProperty.getDateTimeFormatProperty() == null) { + return new CellData(DateUtils.format(value, null)); + } else { + return new CellData(DateUtils.format(value, contentProperty.getDateTimeFormatProperty().getFormat())); + } } } diff --git a/src/main/java/com/alibaba/excel/converters/doubleconverter/ByteBooleanConverter.java b/src/main/java/com/alibaba/excel/converters/doubleconverter/ByteBooleanConverter.java index 2f6e1da6..0ca48335 100644 --- a/src/main/java/com/alibaba/excel/converters/doubleconverter/ByteBooleanConverter.java +++ b/src/main/java/com/alibaba/excel/converters/doubleconverter/ByteBooleanConverter.java @@ -3,7 +3,7 @@ package com.alibaba.excel.converters.doubleconverter; import com.alibaba.excel.converters.Converter; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.CellData; -import com.alibaba.excel.metadata.ExcelColumnProperty; +import com.alibaba.excel.metadata.property.ExcelContentProperty; /** * Byte and boolean converter @@ -25,7 +25,7 @@ public class ByteBooleanConverter implements Converter { } @Override - public Byte convertToJavaData(CellData cellData, ExcelColumnProperty columnProperty) { + public Byte convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) { if (cellData.getBooleanValue()) { return ONE; } @@ -33,7 +33,7 @@ public class ByteBooleanConverter implements Converter { } @Override - public CellData convertToExcelData(Byte value, ExcelColumnProperty columnProperty) { + public CellData convertToExcelData(Byte value, ExcelContentProperty contentProperty) { if (ONE.equals(value)) { return new CellData(Boolean.TRUE); } diff --git a/src/main/java/com/alibaba/excel/converters/doubleconverter/ByteNumberConverter.java b/src/main/java/com/alibaba/excel/converters/doubleconverter/ByteNumberConverter.java deleted file mode 100644 index db01aa7c..00000000 --- a/src/main/java/com/alibaba/excel/converters/doubleconverter/ByteNumberConverter.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.alibaba.excel.converters.doubleconverter; - -import com.alibaba.excel.converters.Converter; -import com.alibaba.excel.enums.CellDataTypeEnum; -import com.alibaba.excel.metadata.CellData; -import com.alibaba.excel.metadata.ExcelColumnProperty; - -/** - * Byte and number converter - * - * @author zhuangjiaju - */ -public class ByteNumberConverter implements Converter { - - @Override - public Class supportJavaTypeKey() { - return Byte.class; - } - - @Override - public CellDataTypeEnum supportExcelTypeKey() { - return CellDataTypeEnum.NUMBER; - } - - @Override - public Byte convertToJavaData(CellData cellData, ExcelColumnProperty columnProperty) { - return cellData.getDoubleValue().byteValue(); - } - - @Override - public CellData convertToExcelData(Byte value, ExcelColumnProperty columnProperty) { - return new CellData((double)value); - } - -} diff --git a/src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleNumberConverter.java b/src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleNumberConverter.java new file mode 100644 index 00000000..a2f94430 --- /dev/null +++ b/src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleNumberConverter.java @@ -0,0 +1,35 @@ +package com.alibaba.excel.converters.doubleconverter; + +import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.enums.CellDataTypeEnum; +import com.alibaba.excel.metadata.CellData; +import com.alibaba.excel.metadata.property.ExcelContentProperty; + +/** + * Double and number converter + * + * @author zhuangjiaju + */ +public class DoubleNumberConverter implements Converter { + + @Override + public Class supportJavaTypeKey() { + return Double.class; + } + + @Override + public CellDataTypeEnum supportExcelTypeKey() { + return CellDataTypeEnum.NUMBER; + } + + @Override + public Double convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) throws Exception { + return cellData.getDoubleValue(); + } + + @Override + public CellData convertToExcelData(Double value, ExcelContentProperty contentProperty) throws Exception { + return new CellData(value); + } + +} 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 e6620837..6709d8e9 100644 --- a/src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleStringConverter.java +++ b/src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleStringConverter.java @@ -3,7 +3,7 @@ package com.alibaba.excel.converters.doubleconverter; import com.alibaba.excel.converters.Converter; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.CellData; -import com.alibaba.excel.metadata.ExcelColumnProperty; +import com.alibaba.excel.metadata.property.ExcelContentProperty; /** * Double and string converter @@ -23,12 +23,12 @@ public class DoubleStringConverter implements Converter { } @Override - public Double convertToJavaData(CellData cellData, ExcelColumnProperty columnProperty) { + public Double convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) { return Double.valueOf(cellData.getStringValue()); } @Override - public CellData convertToExcelData(Double value, ExcelColumnProperty columnProperty) { + public CellData convertToExcelData(Double value, ExcelContentProperty contentProperty) { return new CellData(value.toString()); } } diff --git a/src/main/java/com/alibaba/excel/converters/string/StringStringConverter.java b/src/main/java/com/alibaba/excel/converters/string/StringStringConverter.java index 0fb7e30e..3b2a49d1 100644 --- a/src/main/java/com/alibaba/excel/converters/string/StringStringConverter.java +++ b/src/main/java/com/alibaba/excel/converters/string/StringStringConverter.java @@ -3,7 +3,7 @@ package com.alibaba.excel.converters.string; import com.alibaba.excel.converters.Converter; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.CellData; -import com.alibaba.excel.metadata.ExcelColumnProperty; +import com.alibaba.excel.metadata.property.ExcelContentProperty; /** * String and string converter @@ -22,12 +22,12 @@ public class StringStringConverter implements Converter { } @Override - public String convertToJavaData(CellData cellData, ExcelColumnProperty columnProperty) { + public String convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) { return cellData.getStringValue(); } @Override - public CellData convertToExcelData(String value, ExcelColumnProperty columnProperty) { + public CellData convertToExcelData(String value, ExcelContentProperty contentProperty) { return new CellData(value); } diff --git a/src/main/java/com/alibaba/excel/enums/CellDataTypeEnum.java b/src/main/java/com/alibaba/excel/enums/CellDataTypeEnum.java index d0c5edfd..e880aa2a 100644 --- a/src/main/java/com/alibaba/excel/enums/CellDataTypeEnum.java +++ b/src/main/java/com/alibaba/excel/enums/CellDataTypeEnum.java @@ -16,10 +16,6 @@ public enum CellDataTypeEnum { * string */ STRING, - /** - * inlineString - */ - INLINE_STRING, /** * number */ @@ -40,7 +36,7 @@ public enum CellDataTypeEnum { private static final Map TYPE_ROUTING_MAP = new HashMap(8); static { TYPE_ROUTING_MAP.put("s", STRING); - TYPE_ROUTING_MAP.put("inlineStr", INLINE_STRING); + TYPE_ROUTING_MAP.put("inlineStr", STRING); TYPE_ROUTING_MAP.put("e", ERROR); TYPE_ROUTING_MAP.put("b", BOOLEAN); } diff --git a/src/main/java/com/alibaba/excel/event/ModelBuildEventListener.java b/src/main/java/com/alibaba/excel/event/ModelBuildEventListener.java index 8a4c8358..ed167135 100644 --- a/src/main/java/com/alibaba/excel/event/ModelBuildEventListener.java +++ b/src/main/java/com/alibaba/excel/event/ModelBuildEventListener.java @@ -11,8 +11,8 @@ import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.exception.ExcelDataConvertException; import com.alibaba.excel.exception.ExcelGenerateException; import com.alibaba.excel.metadata.CellData; -import com.alibaba.excel.metadata.ExcelColumnProperty; -import com.alibaba.excel.metadata.ExcelHeadProperty; +import com.alibaba.excel.metadata.property.ExcelContentProperty; +import com.alibaba.excel.metadata.property.ExcelHeadProperty; import net.sf.cglib.beans.BeanMap; @@ -21,10 +21,11 @@ import net.sf.cglib.beans.BeanMap; */ public class ModelBuildEventListener extends AnalysisEventListener { private final Map converters; + public ModelBuildEventListener(Map converters) { this.converters = converters; } - + @Override public void invoke(Object object, AnalysisContext context) { if (context.getExcelHeadProperty() != null && context.getExcelHeadProperty().getHeadClazz() != null) { @@ -42,20 +43,17 @@ public class ModelBuildEventListener extends AnalysisEventListener { private Object buildUserModel(AnalysisContext context, List cellDataList) throws Exception { ExcelHeadProperty excelHeadProperty = context.getExcelHeadProperty(); Object resultModel = excelHeadProperty.getHeadClazz().newInstance(); - if (excelHeadProperty == null) { - return resultModel; - } - Map map = new HashMap(); + Map map = new HashMap(); for (int i = 0; i < cellDataList.size(); i++) { - ExcelColumnProperty columnProperty = excelHeadProperty.getExcelColumnProperty(i); - if (columnProperty != null) { + ExcelContentProperty contentProperty = excelHeadProperty.getContentPropertyMap().get(i); + if (contentProperty != null) { CellData cellData = cellDataList.get(i); if (cellData.getType() == CellDataTypeEnum.EMPTY) { continue; } - Object value = convertValue(cellDataList.get(i), columnProperty.getField().getClass(), columnProperty); + Object value = convertValue(cellDataList.get(i), contentProperty.getField().getClass(), contentProperty); if (value != null) { - map.put(columnProperty.getField().getName(), value); + map.put(contentProperty.getField().getName(), value); } } } @@ -63,14 +61,14 @@ public class ModelBuildEventListener extends AnalysisEventListener { return resultModel; } - private Object convertValue(CellData cellData, Class clazz, ExcelColumnProperty columnProperty) { + private Object convertValue(CellData cellData, Class clazz, ExcelContentProperty contentProperty) { Converter converter = converters.get(ConverterKey.buildConverterKey(clazz, cellData.getType())); if (converter == null) { throw new ExcelDataConvertException( - "Converter not found, converte " + cellData.getType() + " to " + clazz.getName()); + "Converter not found, convert " + cellData.getType() + " to " + clazz.getName()); } try { - return converter.convertToJavaData(cellData, columnProperty); + return converter.convertToJavaData(cellData, contentProperty); } catch (Exception e) { throw new ExcelDataConvertException("Convert data " + cellData + " to " + clazz + " error ", e); } diff --git a/src/main/java/com/alibaba/excel/metadata/CellStyle.java b/src/main/java/com/alibaba/excel/metadata/CellStyle.java index 0d119aad..4a11f300 100644 --- a/src/main/java/com/alibaba/excel/metadata/CellStyle.java +++ b/src/main/java/com/alibaba/excel/metadata/CellStyle.java @@ -17,6 +17,19 @@ public class CellStyle { */ private Font font; + public CellStyle() { + + } + + public CellStyle(String fontName, Short fontHeightInPoints, Boolean bold, IndexedColors indexedColors) { + Font font = new Font(); + font.setFontName(fontName); + font.setFontHeightInPoints(fontHeightInPoints); + font.setBold(bold); + this.font = font; + this.indexedColors = indexedColors; + } + public IndexedColors getIndexedColors() { return indexedColors; } diff --git a/src/main/java/com/alibaba/excel/metadata/ExcelColumnProperty.java b/src/main/java/com/alibaba/excel/metadata/ExcelColumnProperty.java deleted file mode 100644 index 3e1fb4bd..00000000 --- a/src/main/java/com/alibaba/excel/metadata/ExcelColumnProperty.java +++ /dev/null @@ -1,105 +0,0 @@ -package com.alibaba.excel.metadata; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.List; -import java.util.TimeZone; - -/** - * @author jipengfei - */ -public class ExcelColumnProperty implements Comparable { - - /** - */ - private Field field; - - /** - */ - private int index = 99999; - - /** - */ - private List head = new ArrayList(); - - /** - * - */ - private String format; - - private Boolean use1904windowing; - - private TimeZone timeZone; - private int scale; - private int roundingMode; - - public int getScale() { - return scale; - } - - public void setScale(int scale) { - this.scale = scale; - } - - public int getRoundingMode() { - return roundingMode; - } - - public void setRoundingMode(int roundingMode) { - this.roundingMode = roundingMode; - } - - public Boolean getUse1904windowing() { - return use1904windowing; - } - - public void setUse1904windowing(Boolean use1904windowing) { - this.use1904windowing = use1904windowing; - } - - public TimeZone getTimeZone() { - return timeZone; - } - - public void setTimeZone(TimeZone timeZone) { - this.timeZone = timeZone; - } - - public String getFormat() { - return format; - } - - public void setFormat(String format) { - this.format = format; - } - - public Field getField() { - return field; - } - - public void setField(Field field) { - this.field = field; - } - - public int getIndex() { - return index; - } - - public void setIndex(int index) { - this.index = index; - } - - public List getHead() { - return head; - } - - public void setHead(List head) { - this.head = head; - } - - public int compareTo(ExcelColumnProperty o) { - int x = this.index; - int y = o.getIndex(); - return (x < y) ? -1 : ((x == y) ? 0 : 1); - } -} diff --git a/src/main/java/com/alibaba/excel/metadata/ExcelHeadProperty.java b/src/main/java/com/alibaba/excel/metadata/ExcelHeadProperty.java deleted file mode 100644 index 96181896..00000000 --- a/src/main/java/com/alibaba/excel/metadata/ExcelHeadProperty.java +++ /dev/null @@ -1,287 +0,0 @@ -package com.alibaba.excel.metadata; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.alibaba.excel.annotation.ExcelColumnNum; -import com.alibaba.excel.annotation.ExcelProperty; -import com.alibaba.excel.enums.HeadKindEnum; - -/** - * Define the header attribute of excel - * - * @author jipengfei - */ -public class ExcelHeadProperty { - - /** - * Custom class - */ - private Class headClazz; - - /** - * A two-dimensional array describing the header - */ - private List headList; - - /** - * Attributes described by the header - */ - private List columnPropertyList = new ArrayList(); - - /** - * Attributes described by the header - */ - private Map excelColumnPropertyMap1 = new HashMap(); - /** - * The types of head - */ - private HeadKindEnum headKind; - /** - * The number of rows in the line with the most rows - */ - private int headRowNumber; - - public ExcelHeadProperty(Class headClazz, List> head) { - this.headClazz = headClazz; - headList = new ArrayList(); - headKind = HeadKindEnum.NONE; - headRowNumber = 0; - if (head != null && !head.isEmpty()) { - int index = 0; - for (List headData : head) { - headList.add(new Head(index++, null, headData)); - } - headKind = HeadKindEnum.STRING; - } else { - // convert headClazz to head - initColumnProperties(); - } - initHeadRowNumber(); - } - - public static ExcelHeadProperty buildExcelHeadProperty(ExcelHeadProperty excelHeadProperty, Class clazz, - List headOneRow) { - if (excelHeadProperty == null) { - return new ExcelHeadProperty(clazz, new ArrayList>()); - } - if (headOneRow != null) { - excelHeadProperty.appendOneRow(headOneRow); - } - return excelHeadProperty; - } - - private void initHeadRowNumber() { - headRowNumber = 0; - for (Head head : headList) { - List list = head.getHeadNameList(); - if (list != null && list.size() > headRowNumber) { - headRowNumber = list.size(); - } - } - } - - /** - */ - private void initColumnProperties() { - if (this.headClazz != null) { - List fieldList = new ArrayList(); - Class tempClass = this.headClazz; - // When the parent class is null, it indicates that the parent class (Object class) has reached the top - // level. - while (tempClass != null) { - fieldList.addAll(Arrays.asList(tempClass.getDeclaredFields())); - // Get the parent class and give it to yourself - tempClass = tempClass.getSuperclass(); - } - for (Field f : fieldList) { - initOneColumnProperty(f); - } - // 对列排序 - Collections.sort(columnPropertyList); - - int index = 0; - for (ExcelColumnProperty excelColumnProperty : columnPropertyList) { - if (excelColumnProperty.getHead() != null && excelColumnProperty.getHead().size() > headRowNumber) { - headRowNumber = excelColumnProperty.getHead().size(); - } - headList - .add(new Head(index++, excelColumnProperty.getField().getName(), excelColumnProperty.getHead())); - } - headKind = HeadKindEnum.CLASS; - } - } - - /** - * @param f - */ - private void initOneColumnProperty(Field f) { - ExcelProperty p = f.getAnnotation(ExcelProperty.class); - ExcelColumnProperty excelHeadProperty = null; - if (p != null) { - excelHeadProperty = new ExcelColumnProperty(); - excelHeadProperty.setField(f); - excelHeadProperty.setHead(Arrays.asList(p.value())); - excelHeadProperty.setIndex(p.index()); - excelHeadProperty.setFormat(p.format()); - excelColumnPropertyMap1.put(p.index(), excelHeadProperty); - } else { - ExcelColumnNum columnNum = f.getAnnotation(ExcelColumnNum.class); - if (columnNum != null) { - excelHeadProperty = new ExcelColumnProperty(); - excelHeadProperty.setField(f); - excelHeadProperty.setIndex(columnNum.value()); - excelHeadProperty.setFormat(columnNum.format()); - excelColumnPropertyMap1.put(columnNum.value(), excelHeadProperty); - } - } - if (excelHeadProperty != null) { - this.columnPropertyList.add(excelHeadProperty); - } - - } - - /** - * Add one more head under the last head - */ - public void appendOneRow(List row) { - int headSize = headList.size(); - for (int i = 0; i < row.size(); i++) { - String rowData = row.get(i); - // join - if (i <= headSize) { - headList.get(i).getHeadNameList().add(rowData); - } else { - // create and join - headList.add(new Head(i, null, rowData)); - } - } - initHeadRowNumber(); - } - - /** - * @param columnNum - * @return - */ - public ExcelColumnProperty getExcelColumnProperty(int columnNum) { - return excelColumnPropertyMap1.get(columnNum); - } - - public Class getHeadClazz() { - return headClazz; - } - - public void setHeadClazz(Class headClazz) { - this.headClazz = headClazz; - } - - public List getColumnPropertyList() { - return columnPropertyList; - } - - public void setColumnPropertyList(List columnPropertyList) { - this.columnPropertyList = columnPropertyList; - } - - public List getHeadList() { - return headList; - } - - public void setHeadList(List headList) { - this.headList = headList; - } - - public HeadKindEnum getHeadKind() { - return headKind; - } - - public void setHeadKind(HeadKindEnum headKind) { - this.headKind = headKind; - } - - public boolean hasHead() { - return headKind != HeadKindEnum.NONE; - } - - public int getHeadRowNumber() { - return headRowNumber; - } - - public void setHeadRowNumber(int headRowNumber) { - this.headRowNumber = headRowNumber; - } - - /** - * Calculate all cells that need to be merged - * - * @return cells that need to be merged - */ - public List getCellRangeModels() { - List cellRanges = new ArrayList(); - for (int i = 0; i < headList.size(); i++) { - List columnValues = headList.get(i).getHeadNameList(); - for (int j = 0; j < columnValues.size(); j++) { - int lastRow = getLastRangNum(j, columnValues.get(j), columnValues); - int lastColumn = getLastRangNum(i, columnValues.get(j), getHeadByRowNum(j)); - if ((lastRow > j || lastColumn > i) && lastRow >= 0 && lastColumn >= 0) { - cellRanges.add(new CellRange(j, lastRow, i, lastColumn)); - } - } - } - return cellRanges; - } - - public List getHeadByRowNum(int rowNum) { - List l = new ArrayList(headList.size()); - for (Head head : headList) { - List list = head.getHeadNameList(); - if (list.size() > rowNum) { - l.add(list.get(rowNum)); - } else { - l.add(list.get(list.size() - 1)); - } - } - return l; - } - - /** - * Get the last consecutive string position - * - * @param j - * current value position - * @param value - * value content - * @param values - * values - * @return the last consecutive string position - */ - private int getLastRangNum(int j, String value, List values) { - if (value == null) { - return -1; - } - if (j > 0) { - String preValue = values.get(j - 1); - if (value.equals(preValue)) { - return -1; - } - } - int last = j; - for (int i = last + 1; i < values.size(); i++) { - String current = values.get(i); - if (value.equals(current)) { - last = i; - } else { - // if i>j && !value.equals(current) Indicates that the continuous range is exceeded - if (i > j) { - break; - } - } - } - return last; - } -} diff --git a/src/main/java/com/alibaba/excel/metadata/Head.java b/src/main/java/com/alibaba/excel/metadata/Head.java index 5c10e752..370bd11d 100644 --- a/src/main/java/com/alibaba/excel/metadata/Head.java +++ b/src/main/java/com/alibaba/excel/metadata/Head.java @@ -3,6 +3,9 @@ package com.alibaba.excel.metadata; import java.util.ArrayList; import java.util.List; +import com.alibaba.excel.metadata.property.CellStyleProperty; +import com.alibaba.excel.metadata.property.ColumnWidthProperty; + /** * excel head * @@ -22,6 +25,15 @@ public class Head { */ private List headNameList; + /** + * Cell style property + */ + private CellStyleProperty cellStyleProperty; + /** + * column with + */ + private ColumnWidthProperty columnWidthProperty; + public Head(Integer columnIndex, String fieldName, String headName) { this.columnIndex = columnIndex; this.fieldName = fieldName; @@ -62,26 +74,19 @@ public class Head { this.headNameList = headNameList; } - @Override - public String toString() { - return "Head{" + "columnIndex=" + columnIndex + ", fieldName='" + fieldName + '\'' + ", headNameList=" - + headNameList + '}'; + public CellStyleProperty getCellStyleProperty() { + return cellStyleProperty; } - /** - * Get head name with index - * - * @param index - * @return - */ - public String getHeadName(int index) { - if (headNameList == null || headNameList.isEmpty()) { - return null; - } - if (index >= headNameList.size()) { - return headNameList.get(headNameList.size() - 1); - } else { - return headNameList.get(index); - } + public void setCellStyleProperty(CellStyleProperty cellStyleProperty) { + this.cellStyleProperty = cellStyleProperty; + } + + public ColumnWidthProperty getColumnWidthProperty() { + return columnWidthProperty; + } + + public void setColumnWidthProperty(ColumnWidthProperty columnWidthProperty) { + this.columnWidthProperty = columnWidthProperty; } } diff --git a/src/main/java/com/alibaba/excel/metadata/Workbook.java b/src/main/java/com/alibaba/excel/metadata/Workbook.java index 155f6aef..920a7b06 100644 --- a/src/main/java/com/alibaba/excel/metadata/Workbook.java +++ b/src/main/java/com/alibaba/excel/metadata/Workbook.java @@ -28,6 +28,14 @@ public class Workbook extends BasicParameter { * Default true */ private Boolean autoCloseStream; + /** + * The default is all excel objects.if true , you can use {@link com.alibaba.excel.annotation.ExcelIgnore} ignore a + * field. if false , you must use {@link com.alibaba.excel.annotation.ExcelProperty} to use a filed. + * + * @deprecated Just to be compatible with historical data, The default is always going to be convert all filed. + */ + @Deprecated + private Boolean convertAllFiled; /** * Write handler * @@ -75,4 +83,12 @@ public class Workbook extends BasicParameter { public void setAutoCloseStream(Boolean autoCloseStream) { this.autoCloseStream = autoCloseStream; } + + public Boolean getConvertAllFiled() { + return convertAllFiled; + } + + public void setConvertAllFiled(Boolean convertAllFiled) { + this.convertAllFiled = convertAllFiled; + } } diff --git a/src/main/java/com/alibaba/excel/metadata/holder/AbstractConfigurationSelector.java b/src/main/java/com/alibaba/excel/metadata/holder/AbstractConfigurationSelector.java index 22abb7c8..48697da9 100644 --- a/src/main/java/com/alibaba/excel/metadata/holder/AbstractConfigurationSelector.java +++ b/src/main/java/com/alibaba/excel/metadata/holder/AbstractConfigurationSelector.java @@ -8,15 +8,27 @@ import java.util.Map; import java.util.Set; import java.util.TreeMap; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Sheet; + import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.enums.HeadKindEnum; import com.alibaba.excel.event.NotRepeatExecutor; import com.alibaba.excel.event.Order; -import com.alibaba.excel.metadata.ExcelHeadProperty; +import com.alibaba.excel.metadata.CellStyle; +import com.alibaba.excel.metadata.Head; +import com.alibaba.excel.metadata.property.CellStyleProperty; +import com.alibaba.excel.metadata.property.ExcelContentProperty; +import com.alibaba.excel.metadata.property.ExcelHeadProperty; +import com.alibaba.excel.metadata.property.RowHeightProperty; import com.alibaba.excel.write.handler.CellWriteHandler; import com.alibaba.excel.write.handler.RowWriteHandler; import com.alibaba.excel.write.handler.SheetWriteHandler; import com.alibaba.excel.write.handler.WorkbookWriteHandler; import com.alibaba.excel.write.handler.WriteHandler; +import com.alibaba.excel.write.style.AbstractColumnCellStyleStrategy; +import com.alibaba.excel.write.style.column.AbstractColumnWidthStyleStrategy; +import com.alibaba.excel.write.style.row.SimpleRowHeightStyleStrategy; /** * sheet holder @@ -191,6 +203,99 @@ public abstract class AbstractConfigurationSelector implements ConfigurationSele return result; } + protected void initAnnotationConfig(List handlerList) { + if (!HeadKindEnum.CLASS.equals(getExcelHeadProperty().getHeadKind())) { + return; + } + Map headMap = getExcelHeadProperty().getHeadMap(); + Map contentPropertyMap = getExcelHeadProperty().getContentPropertyMap(); + + boolean hasCellStyle = false; + boolean hasColumnWidth = false; + for (Map.Entry entry : headMap.entrySet()) { + if (entry.getValue().getCellStyleProperty() != null) { + hasCellStyle = true; + } + if (entry.getValue().getColumnWidthProperty() != null) { + hasColumnWidth = true; + } + ExcelContentProperty excelContentProperty = contentPropertyMap.get(entry.getKey()); + if (excelContentProperty.getCellStyleProperty() != null) { + hasCellStyle = true; + } + } + + if (hasCellStyle) { + dealCellStyle(handlerList, contentPropertyMap); + } + if (hasColumnWidth) { + dealColumnWidth(handlerList); + } + dealRowHigh(handlerList, contentPropertyMap); + } + + private void dealRowHigh(List handlerList, Map contentPropertyMap) { + RowHeightProperty headRowHeightProperty = excelHeadProperty.getHeadRowHeightProperty(); + RowHeightProperty contentRowHeightProperty = excelHeadProperty.getContentRowHeightProperty(); + if (headRowHeightProperty == null && contentRowHeightProperty == null) { + return; + } + Short headRowHeight = null; + if (headRowHeightProperty != null) { + headRowHeight = headRowHeightProperty.getHeight(); + } + Short contentRowHeight = null; + if (contentRowHeightProperty != null) { + contentRowHeight = contentRowHeightProperty.getHeight(); + } + handlerList.add(new SimpleRowHeightStyleStrategy(headRowHeight, contentRowHeight)); + } + + private void dealColumnWidth(List handlerList) { + WriteHandler columnWidthStyleStrategy = new AbstractColumnWidthStyleStrategy() { + @Override + protected void setColumnWidth(Sheet sheet, Cell cell, Head head) { + if (head == null) { + return; + } + if (head.getColumnWidthProperty() != null) { + sheet.setColumnWidth(head.getColumnIndex(), head.getColumnWidthProperty().getWidth()); + } + } + }; + handlerList.add(columnWidthStyleStrategy); + } + + private void dealCellStyle(List handlerList, + final Map contentPropertyMap) { + WriteHandler columnCellStyleStrategy = new AbstractColumnCellStyleStrategy() { + @Override + protected CellStyle headCellStyle(Head head) { + if (head == null || head.getCellStyleProperty() == null) { + return null; + } + CellStyleProperty cellStyleProperty = head.getCellStyleProperty(); + return new CellStyle(cellStyleProperty.getFontName(), cellStyleProperty.getFontHeightInPoints(), + cellStyleProperty.getBold(), cellStyleProperty.getIndexedColors()); + } + + @Override + protected CellStyle contentCellStyle(Head head) { + if (head == null) { + return null; + } + ExcelContentProperty excelContentProperty = contentPropertyMap.get(head.getColumnIndex()); + if (excelContentProperty == null || excelContentProperty.getCellStyleProperty() == null) { + return null; + } + CellStyleProperty cellStyleProperty = excelContentProperty.getCellStyleProperty(); + return new CellStyle(cellStyleProperty.getFontName(), cellStyleProperty.getFontHeightInPoints(), + cellStyleProperty.getBold(), cellStyleProperty.getIndexedColors()); + } + }; + handlerList.add(columnCellStyleStrategy); + } + @Override public Map, List> writeHandlerMap() { return getWriteHandlerMap(); diff --git a/src/main/java/com/alibaba/excel/metadata/holder/ConfigurationSelector.java b/src/main/java/com/alibaba/excel/metadata/holder/ConfigurationSelector.java index 1ae33843..fe930264 100644 --- a/src/main/java/com/alibaba/excel/metadata/holder/ConfigurationSelector.java +++ b/src/main/java/com/alibaba/excel/metadata/holder/ConfigurationSelector.java @@ -4,7 +4,7 @@ import java.util.List; import java.util.Map; import com.alibaba.excel.converters.Converter; -import com.alibaba.excel.metadata.ExcelHeadProperty; +import com.alibaba.excel.metadata.property.ExcelHeadProperty; import com.alibaba.excel.write.handler.WriteHandler; /** diff --git a/src/main/java/com/alibaba/excel/metadata/holder/SheetHolder.java b/src/main/java/com/alibaba/excel/metadata/holder/SheetHolder.java index a5f52506..51b3381f 100644 --- a/src/main/java/com/alibaba/excel/metadata/holder/SheetHolder.java +++ b/src/main/java/com/alibaba/excel/metadata/holder/SheetHolder.java @@ -11,6 +11,7 @@ import com.alibaba.excel.converters.Converter; import com.alibaba.excel.metadata.CellStyle; import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.TableStyle; +import com.alibaba.excel.metadata.property.ExcelHeadProperty; import com.alibaba.excel.write.handler.WriteHandler; import com.alibaba.excel.write.style.RowCellStyleStrategy; import com.alibaba.excel.write.style.column.AbstractHeadColumnWidthStyleStrategy; @@ -21,6 +22,7 @@ import com.alibaba.excel.write.style.column.AbstractHeadColumnWidthStyleStrategy * @author zhuangjiaju */ public class SheetHolder extends AbstractConfigurationSelector { + /*** * poi sheet */ @@ -59,6 +61,9 @@ public class SheetHolder extends AbstractConfigurationSelector { setHead(sheet.getHead()); setClazz(sheet.getClazz()); } + // Initialization property + setExcelHeadProperty(new ExcelHeadProperty(getClazz(), getHead(), workbookHolder.getConvertAllFiled())); + setNewInitialization(Boolean.TRUE); if (sheet.getNeedHead() == null) { setNeedHead(workbookHolder.needHead()); @@ -76,6 +81,9 @@ public class SheetHolder extends AbstractConfigurationSelector { if (sheet.getCustomWriteHandlerList() != null && !sheet.getCustomWriteHandlerList().isEmpty()) { handlerList.addAll(sheet.getCustomWriteHandlerList()); } + // Initialization Annotation + initAnnotationConfig(handlerList); + setWriteHandlerMap(sortAndClearUpHandler(handlerList, workbookHolder.getWriteHandlerMap())); Map converterMap = new HashMap(workbookHolder.converterMap()); if (sheet.getCustomConverterMap() != null && !sheet.getCustomConverterMap().isEmpty()) { @@ -97,7 +105,7 @@ public class SheetHolder extends AbstractConfigurationSelector { } sheet.getCustomWriteHandlerList().add(new AbstractHeadColumnWidthStyleStrategy() { @Override - protected int columnWidth(Head head) { + protected Integer columnWidth(Head head) { if (columnWidthMap.containsKey(head.getColumnIndex())) { columnWidthMap.get(head.getColumnIndex()); } diff --git a/src/main/java/com/alibaba/excel/metadata/holder/TableHolder.java b/src/main/java/com/alibaba/excel/metadata/holder/TableHolder.java index 6ffb84e8..dcc1f598 100644 --- a/src/main/java/com/alibaba/excel/metadata/holder/TableHolder.java +++ b/src/main/java/com/alibaba/excel/metadata/holder/TableHolder.java @@ -9,6 +9,7 @@ import com.alibaba.excel.converters.Converter; import com.alibaba.excel.metadata.CellStyle; import com.alibaba.excel.metadata.Table; import com.alibaba.excel.metadata.TableStyle; +import com.alibaba.excel.metadata.property.ExcelHeadProperty; import com.alibaba.excel.write.handler.WriteHandler; import com.alibaba.excel.write.style.RowCellStyleStrategy; @@ -31,7 +32,7 @@ public class TableHolder extends AbstractConfigurationSelector { */ private com.alibaba.excel.metadata.Table tableParam; - public TableHolder(com.alibaba.excel.metadata.Table table, SheetHolder sheetHolder) { + public TableHolder(com.alibaba.excel.metadata.Table table, SheetHolder sheetHolder, WorkbookHolder workbookHolder) { super(); this.tableParam = table; this.parentSheet = sheetHolder; @@ -46,6 +47,9 @@ public class TableHolder extends AbstractConfigurationSelector { setClazz(table.getClazz()); } setNewInitialization(Boolean.TRUE); + // Initialization property + setExcelHeadProperty(new ExcelHeadProperty(getClazz(), getHead(), workbookHolder.getConvertAllFiled())); + if (table.getNeedHead() == null) { setNeedHead(sheetHolder.needHead()); } else { @@ -62,6 +66,9 @@ public class TableHolder extends AbstractConfigurationSelector { if (table.getCustomWriteHandlerList() != null && !table.getCustomWriteHandlerList().isEmpty()) { handlerList.addAll(table.getCustomWriteHandlerList()); } + // Initialization Annotation + initAnnotationConfig(handlerList); + setWriteHandlerMap(sortAndClearUpHandler(handlerList, sheetHolder.getWriteHandlerMap())); Map converterMap = new HashMap(sheetHolder.converterMap()); if (table.getCustomConverterMap() != null && !table.getCustomConverterMap().isEmpty()) { diff --git a/src/main/java/com/alibaba/excel/metadata/holder/WorkbookHolder.java b/src/main/java/com/alibaba/excel/metadata/holder/WorkbookHolder.java index 433d238c..6b8c8ed4 100644 --- a/src/main/java/com/alibaba/excel/metadata/holder/WorkbookHolder.java +++ b/src/main/java/com/alibaba/excel/metadata/holder/WorkbookHolder.java @@ -10,8 +10,8 @@ import java.util.Map; import org.apache.poi.ss.usermodel.Workbook; import com.alibaba.excel.converters.Converter; -import com.alibaba.excel.converters.DefaultConverterBuilder; -import com.alibaba.excel.write.handler.DefaultWriteHandlerBuilder; +import com.alibaba.excel.converters.DefaultConverterLoader; +import com.alibaba.excel.write.handler.DefaultWriteHandlerLoader; import com.alibaba.excel.write.handler.WriteHandler; /** @@ -45,6 +45,15 @@ public class WorkbookHolder extends AbstractConfigurationSelector { */ private Boolean autoCloseStream; + /** + * The default is all excel objects.if true , you can use {@link com.alibaba.excel.annotation.ExcelIgnore} ignore a + * field. if false , you must use {@link com.alibaba.excel.annotation.ExcelProperty} to use a filed. + * + * @deprecated Just to be compatible with historical data, The default is always going to be convert all filed. + */ + @Deprecated + private Boolean convertAllFiled; + /** * Write handler * @@ -62,6 +71,11 @@ public class WorkbookHolder extends AbstractConfigurationSelector { setHead(workbook.getHead()); setClazz(workbook.getClazz()); setNewInitialization(Boolean.TRUE); + if (workbook.getConvertAllFiled() == null) { + this.convertAllFiled = Boolean.TRUE; + } else { + this.convertAllFiled = workbook.getConvertAllFiled(); + } if (workbook.getAutoCloseStream() == null) { setAutoCloseStream(Boolean.TRUE); } else { @@ -81,9 +95,12 @@ public class WorkbookHolder extends AbstractConfigurationSelector { if (workbook.getCustomWriteHandlerList() != null && !workbook.getCustomWriteHandlerList().isEmpty()) { handlerList.addAll(workbook.getCustomWriteHandlerList()); } - handlerList.addAll(DefaultWriteHandlerBuilder.loadDefaultHandler()); + // Initialization Annotation + initAnnotationConfig(handlerList); + + handlerList.addAll(DefaultWriteHandlerLoader.loadDefaultHandler()); setWriteHandlerMap(sortAndClearUpHandler(handlerList, null)); - Map converterMap = DefaultConverterBuilder.loadDefaultWriteConverter(); + Map converterMap = DefaultConverterLoader.loadDefaultWriteConverter(); if (workbook.getCustomConverterMap() != null && !workbook.getCustomConverterMap().isEmpty()) { converterMap.putAll(workbook.getCustomConverterMap()); } @@ -146,4 +163,12 @@ public class WorkbookHolder extends AbstractConfigurationSelector { public void setAutoCloseStream(Boolean autoCloseStream) { this.autoCloseStream = autoCloseStream; } + + public Boolean getConvertAllFiled() { + return convertAllFiled; + } + + public void setConvertAllFiled(Boolean convertAllFiled) { + this.convertAllFiled = convertAllFiled; + } } diff --git a/src/main/java/com/alibaba/excel/metadata/property/CellStyleProperty.java b/src/main/java/com/alibaba/excel/metadata/property/CellStyleProperty.java new file mode 100644 index 00000000..12596796 --- /dev/null +++ b/src/main/java/com/alibaba/excel/metadata/property/CellStyleProperty.java @@ -0,0 +1,84 @@ +package com.alibaba.excel.metadata.property; + +import org.apache.poi.ss.usermodel.IndexedColors; + +import com.alibaba.excel.annotation.write.style.ContentStyle; +import com.alibaba.excel.annotation.write.style.HeadStyle; + +/** + * Configuration from annotations + * + * @author zhuangjiaju + */ +public class CellStyleProperty { + private String fontName; + private Short fontHeightInPoints; + private Boolean bold; + private IndexedColors indexedColors; + + public CellStyleProperty(String fontName, Short fontHeightInPoints, Boolean bold, IndexedColors indexedColors) { + this.fontName = fontName; + this.fontHeightInPoints = fontHeightInPoints; + this.bold = bold; + this.indexedColors = indexedColors; + } + + public static CellStyleProperty build(HeadStyle headStyle) { + if (headStyle == null) { + return null; + } + boolean isDefault = "宋体".equals(headStyle.fontName()) && headStyle.fontHeightInPoints() == 14 + && headStyle.bold() && IndexedColors.GREY_25_PERCENT.equals(headStyle.indexedColors()); + if (isDefault) { + return null; + } + return new CellStyleProperty(headStyle.fontName(), headStyle.fontHeightInPoints(), headStyle.bold(), + headStyle.indexedColors()); + } + + public static CellStyleProperty build(ContentStyle contentStyle) { + if (contentStyle == null) { + return null; + } + boolean isDefault = "宋体".equals(contentStyle.fontName()) && contentStyle.fontHeightInPoints() == 14 + && contentStyle.bold() && IndexedColors.WHITE1.equals(contentStyle.indexedColors()); + if (isDefault) { + return null; + } + return new CellStyleProperty(contentStyle.fontName(), contentStyle.fontHeightInPoints(), contentStyle.bold(), + contentStyle.indexedColors()); + } + + public String getFontName() { + return fontName; + } + + public void setFontName(String fontName) { + this.fontName = fontName; + } + + public Short getFontHeightInPoints() { + return fontHeightInPoints; + } + + public void setFontHeightInPoints(Short fontHeightInPoints) { + this.fontHeightInPoints = fontHeightInPoints; + } + + public Boolean getBold() { + return bold; + } + + public void setBold(Boolean bold) { + this.bold = bold; + } + + public IndexedColors getIndexedColors() { + return indexedColors; + } + + public void setIndexedColors(IndexedColors indexedColors) { + this.indexedColors = indexedColors; + } + +} diff --git a/src/main/java/com/alibaba/excel/metadata/property/ColumnWidthProperty.java b/src/main/java/com/alibaba/excel/metadata/property/ColumnWidthProperty.java new file mode 100644 index 00000000..2ffbfe80 --- /dev/null +++ b/src/main/java/com/alibaba/excel/metadata/property/ColumnWidthProperty.java @@ -0,0 +1,31 @@ +package com.alibaba.excel.metadata.property; + +import com.alibaba.excel.annotation.write.style.ColumnWidth; + +/** + * Configuration from annotations + * + * @author zhuangjiaju + */ +public class ColumnWidthProperty { + private Integer width; + + public ColumnWidthProperty(Integer width) { + this.width = width; + } + + public static ColumnWidthProperty build(ColumnWidth columnWidth) { + if (columnWidth == null || columnWidth.value() < 0) { + return null; + } + return new ColumnWidthProperty(columnWidth.value()); + } + + public Integer getWidth() { + return width; + } + + public void setWidth(Integer width) { + this.width = width; + } +} diff --git a/src/main/java/com/alibaba/excel/metadata/property/DateTimeFormatProperty.java b/src/main/java/com/alibaba/excel/metadata/property/DateTimeFormatProperty.java new file mode 100644 index 00000000..5330d51b --- /dev/null +++ b/src/main/java/com/alibaba/excel/metadata/property/DateTimeFormatProperty.java @@ -0,0 +1,41 @@ +package com.alibaba.excel.metadata.property; + +import com.alibaba.excel.annotation.format.DateTimeFormat; + +/** + * Configuration from annotations + * + * @author zhuangjiaju + */ +public class DateTimeFormatProperty { + private String format; + private Boolean use1904windowing; + + public DateTimeFormatProperty(String format, Boolean use1904windowing) { + this.format = format; + this.use1904windowing = use1904windowing; + } + + public static DateTimeFormatProperty build(DateTimeFormat dateTimeFormat) { + if (dateTimeFormat == null) { + return null; + } + return new DateTimeFormatProperty(dateTimeFormat.value(), dateTimeFormat.use1904windowing()); + } + + public String getFormat() { + return format; + } + + public void setFormat(String format) { + this.format = format; + } + + public Boolean getUse1904windowing() { + return use1904windowing; + } + + public void setUse1904windowing(Boolean use1904windowing) { + this.use1904windowing = use1904windowing; + } +} diff --git a/src/main/java/com/alibaba/excel/metadata/property/ExcelContentProperty.java b/src/main/java/com/alibaba/excel/metadata/property/ExcelContentProperty.java new file mode 100644 index 00000000..22f7b940 --- /dev/null +++ b/src/main/java/com/alibaba/excel/metadata/property/ExcelContentProperty.java @@ -0,0 +1,62 @@ +package com.alibaba.excel.metadata.property; + +import java.lang.reflect.Field; + +import com.alibaba.excel.metadata.Head; + +/** + * @author jipengfei + */ +public class ExcelContentProperty { + /** + * Java filed + */ + private Field field; + /** + * Excel head + */ + private Head head; + private CellStyleProperty cellStyleProperty; + private DateTimeFormatProperty dateTimeFormatProperty; + private NumberFormatProperty numberFormatProperty; + + public Field getField() { + return field; + } + + public void setField(Field field) { + this.field = field; + } + + public Head getHead() { + return head; + } + + public void setHead(Head head) { + this.head = head; + } + + public CellStyleProperty getCellStyleProperty() { + return cellStyleProperty; + } + + public void setCellStyleProperty(CellStyleProperty cellStyleProperty) { + this.cellStyleProperty = cellStyleProperty; + } + + public DateTimeFormatProperty getDateTimeFormatProperty() { + return dateTimeFormatProperty; + } + + public void setDateTimeFormatProperty(DateTimeFormatProperty dateTimeFormatProperty) { + this.dateTimeFormatProperty = dateTimeFormatProperty; + } + + public NumberFormatProperty getNumberFormatProperty() { + return numberFormatProperty; + } + + public void setNumberFormatProperty(NumberFormatProperty numberFormatProperty) { + this.numberFormatProperty = numberFormatProperty; + } +} diff --git a/src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java b/src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java new file mode 100644 index 00000000..9b980646 --- /dev/null +++ b/src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java @@ -0,0 +1,350 @@ +package com.alibaba.excel.metadata.property; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.alibaba.excel.annotation.ExcelIgnore; +import com.alibaba.excel.annotation.ExcelProperty; +import com.alibaba.excel.annotation.format.DateTimeFormat; +import com.alibaba.excel.annotation.format.NumberFormat; +import com.alibaba.excel.annotation.write.style.ColumnWidth; +import com.alibaba.excel.annotation.write.style.ContentRowHeight; +import com.alibaba.excel.annotation.write.style.ContentStyle; +import com.alibaba.excel.annotation.write.style.HeadRowHeight; +import com.alibaba.excel.annotation.write.style.HeadStyle; +import com.alibaba.excel.enums.HeadKindEnum; +import com.alibaba.excel.exception.ExcelGenerateException; +import com.alibaba.excel.metadata.CellRange; +import com.alibaba.excel.metadata.Head; + +/** + * Define the header attribute of excel + * + * @author jipengfei + */ +public class ExcelHeadProperty { + + private static final Logger LOGGER = LoggerFactory.getLogger(ExcelHeadProperty.class); + /** + * Custom class + */ + private Class headClazz; + /** + * The types of head + */ + private HeadKindEnum headKind; + /** + * The number of rows in the line with the most rows + */ + private int headRowNumber; + + /** + * Configuration header information + */ + private Map headMap; + + /** + * Configuration column information + */ + private Map contentPropertyMap; + private RowHeightProperty headRowHeightProperty; + private RowHeightProperty contentRowHeightProperty; + + public ExcelHeadProperty(Class headClazz, List> head, Boolean convertAllFiled) { + this.headClazz = headClazz; + headMap = new TreeMap(); + contentPropertyMap = new TreeMap(); + headKind = HeadKindEnum.NONE; + headRowNumber = 0; + if (head != null && !head.isEmpty()) { + for (int i = 0; i < head.size(); i++) { + headMap.put(i, new Head(i, null, head.get(i))); + contentPropertyMap.put(i, null); + } + headKind = HeadKindEnum.STRING; + } else { + // convert headClazz to head + initColumnProperties(convertAllFiled); + } + initHeadRowNumber(); + LOGGER.info("The initialization sheet/table 'ExcelHeadProperty' is complete , head kind is {}", headKind); + } + + public static ExcelHeadProperty buildExcelHeadProperty(ExcelHeadProperty excelHeadProperty, Class clazz, + List headOneRow) { + if (excelHeadProperty == null) { + return new ExcelHeadProperty(clazz, new ArrayList>(), false); + } + if (headOneRow != null) { + excelHeadProperty.appendOneRow(headOneRow); + } + return excelHeadProperty; + } + + private void initHeadRowNumber() { + headRowNumber = 0; + for (Head head : headMap.values()) { + List list = head.getHeadNameList(); + if (list != null && list.size() > headRowNumber) { + headRowNumber = list.size(); + } + } + for (Head head : headMap.values()) { + List list = head.getHeadNameList(); + if (list != null && !list.isEmpty() && list.size() < headRowNumber) { + int lack = headRowNumber - list.size(); + int last = list.size() - 1; + for (int i = 0; i < lack; i++) { + list.add(list.get(last)); + } + } + } + } + + private void initColumnProperties(Boolean convertAllFiled) { + if (headClazz == null) { + return; + } + List fieldList = new ArrayList(); + Class tempClass = headClazz; + // When the parent class is null, it indicates that the parent class (Object class) has reached the top + // level. + while (tempClass != null) { + fieldList.addAll(Arrays.asList(tempClass.getDeclaredFields())); + // Get the parent class and give it to yourself + tempClass = tempClass.getSuperclass(); + } + + // Screening of field + List defaultFieldList = new ArrayList(); + Map customFiledMap = new TreeMap(); + for (Field field : fieldList) { + ExcelIgnore excelIgnore = field.getAnnotation(ExcelIgnore.class); + if (excelIgnore != null) { + continue; + } + ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class); + if (excelProperty == null && !convertAllFiled) { + continue; + } + if (excelProperty == null || excelProperty.index() < 0) { + defaultFieldList.add(field); + return; + } + if (customFiledMap.containsKey(excelProperty.index())) { + throw new ExcelGenerateException("The index of " + customFiledMap.get(excelProperty.index()).getName() + + " and " + field.getName() + " must be inconsistent"); + } + customFiledMap.put(excelProperty.index(), field); + } + + HeadStyle headStyle = (HeadStyle)headClazz.getAnnotation(HeadStyle.class); + ContentStyle contentStyle = (ContentStyle)headClazz.getAnnotation(ContentStyle.class); + ColumnWidth columnWidth = (ColumnWidth)headClazz.getAnnotation(ColumnWidth.class); + this.headRowHeightProperty = + RowHeightProperty.build((HeadRowHeight)headClazz.getAnnotation(HeadRowHeight.class)); + this.contentRowHeightProperty = + RowHeightProperty.build((ContentRowHeight)headClazz.getAnnotation(ContentRowHeight.class)); + + int index = 0; + for (Field field : defaultFieldList) { + while (customFiledMap.containsKey(index)) { + initOneColumnProperty(index, customFiledMap.get(index), headStyle, contentStyle, columnWidth); + customFiledMap.remove(index); + index++; + } + initOneColumnProperty(index, field, headStyle, contentStyle, columnWidth); + index++; + } + for (Map.Entry entry : customFiledMap.entrySet()) { + initOneColumnProperty(index, entry.getValue(), headStyle, contentStyle, columnWidth); + index++; + } + headKind = HeadKindEnum.CLASS; + } + + private void initOneColumnProperty(int index, Field field, HeadStyle parentHeadStyle, + ContentStyle parentContentStyle, ColumnWidth parentColumnWidth) { + + ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class); + List tmpHeadList = new ArrayList(); + if (excelProperty != null) { + tmpHeadList = Arrays.asList(excelProperty.value()); + } else { + tmpHeadList.add(field.getName()); + } + Head head = new Head(index, field.getName(), tmpHeadList); + HeadStyle headStyle = field.getAnnotation(HeadStyle.class); + if (headStyle == null) { + headStyle = parentHeadStyle; + } + head.setCellStyleProperty(CellStyleProperty.build(headStyle)); + + ColumnWidth columnWidth = field.getAnnotation(ColumnWidth.class); + if (columnWidth == null) { + columnWidth = parentColumnWidth; + } + head.setColumnWidthProperty(ColumnWidthProperty.build(columnWidth)); + + ExcelContentProperty excelContentProperty = new ExcelContentProperty(); + excelContentProperty.setHead(head); + ContentStyle contentStyle = field.getAnnotation(ContentStyle.class); + if (contentStyle == null) { + contentStyle = parentContentStyle; + } + excelContentProperty.setCellStyleProperty(CellStyleProperty.build(contentStyle)); + + excelContentProperty + .setDateTimeFormatProperty(DateTimeFormatProperty.build(field.getAnnotation(DateTimeFormat.class))); + + excelContentProperty + .setNumberFormatProperty(NumberFormatProperty.build(field.getAnnotation(NumberFormat.class))); + headMap.put(index, head); + contentPropertyMap.put(index, excelContentProperty); + } + + /** + * Add one more head under the last head + */ + public void appendOneRow(List row) { + for (int i = 0; i < row.size(); i++) { + String rowData = row.get(i); + // join + if (headMap.containsKey(i)) { + headMap.get(i).getHeadNameList().add(rowData); + } else { + // create and join + int index = ((TreeMap)headMap).lastKey() + 1; + headMap.put(index, new Head(i, null, rowData)); + } + } + initHeadRowNumber(); + } + + public Class getHeadClazz() { + return headClazz; + } + + public void setHeadClazz(Class headClazz) { + this.headClazz = headClazz; + } + + public HeadKindEnum getHeadKind() { + return headKind; + } + + public void setHeadKind(HeadKindEnum headKind) { + this.headKind = headKind; + } + + public boolean hasHead() { + return headKind != HeadKindEnum.NONE; + } + + public int getHeadRowNumber() { + return headRowNumber; + } + + public void setHeadRowNumber(int headRowNumber) { + this.headRowNumber = headRowNumber; + } + + public Map getHeadMap() { + return headMap; + } + + public void setHeadMap(Map headMap) { + this.headMap = headMap; + } + + public Map getContentPropertyMap() { + return contentPropertyMap; + } + + public void setContentPropertyMap(Map contentPropertyMap) { + this.contentPropertyMap = contentPropertyMap; + } + + public RowHeightProperty getHeadRowHeightProperty() { + return headRowHeightProperty; + } + + public void setHeadRowHeightProperty(RowHeightProperty headRowHeightProperty) { + this.headRowHeightProperty = headRowHeightProperty; + } + + public RowHeightProperty getContentRowHeightProperty() { + return contentRowHeightProperty; + } + + public void setContentRowHeightProperty(RowHeightProperty contentRowHeightProperty) { + this.contentRowHeightProperty = contentRowHeightProperty; + } + + /** + * Calculate all cells that need to be merged + * + * @return cells that need to be merged + */ + public List headCellRangeList() { + List cellRangeList = new ArrayList(); + int i = 0; + for (Map.Entry entry : headMap.entrySet()) { + Head head = entry.getValue(); + List columnValues = head.getHeadNameList(); + for (int j = 0; j < columnValues.size(); j++) { + int lastRow = getLastRangNum(j, columnValues.get(j), columnValues); + int lastColumn = getLastRangNum(i, columnValues.get(j), head.getHeadNameList()); + if ((lastRow > j || lastColumn > i) && lastRow >= 0 && lastColumn >= 0) { + cellRangeList.add(new CellRange(j, lastRow, i, lastColumn)); + } + } + i++; + } + return cellRangeList; + } + + /** + * Get the last consecutive string position + * + * @param j + * current value position + * @param value + * value content + * @param values + * values + * @return the last consecutive string position + */ + private int getLastRangNum(int j, String value, List values) { + if (value == null) { + return -1; + } + if (j > 0) { + String preValue = values.get(j - 1); + if (value.equals(preValue)) { + return -1; + } + } + int last = j; + for (int i = last + 1; i < values.size(); i++) { + String current = values.get(i); + if (value.equals(current)) { + last = i; + } else { + // if i>j && !value.equals(current) Indicates that the continuous range is exceeded + if (i > j) { + break; + } + } + } + return last; + } + +} diff --git a/src/main/java/com/alibaba/excel/metadata/property/NumberFormatProperty.java b/src/main/java/com/alibaba/excel/metadata/property/NumberFormatProperty.java new file mode 100644 index 00000000..ffdab195 --- /dev/null +++ b/src/main/java/com/alibaba/excel/metadata/property/NumberFormatProperty.java @@ -0,0 +1,43 @@ +package com.alibaba.excel.metadata.property; + +import java.math.RoundingMode; + +import com.alibaba.excel.annotation.format.NumberFormat; + +/** + * Configuration from annotations + * + * @author zhuangjiaju + */ +public class NumberFormatProperty { + private String format; + private RoundingMode roundingMode; + + public NumberFormatProperty(String format, RoundingMode roundingMode) { + this.format = format; + this.roundingMode = roundingMode; + } + + public static NumberFormatProperty build(NumberFormat numberFormat) { + if (numberFormat == null) { + return null; + } + return new NumberFormatProperty(numberFormat.value(), numberFormat.roundingMode()); + } + + public String getFormat() { + return format; + } + + public void setFormat(String format) { + this.format = format; + } + + public RoundingMode getRoundingMode() { + return roundingMode; + } + + public void setRoundingMode(RoundingMode roundingMode) { + this.roundingMode = roundingMode; + } +} diff --git a/src/main/java/com/alibaba/excel/metadata/property/RowHeightProperty.java b/src/main/java/com/alibaba/excel/metadata/property/RowHeightProperty.java new file mode 100644 index 00000000..9ea71f46 --- /dev/null +++ b/src/main/java/com/alibaba/excel/metadata/property/RowHeightProperty.java @@ -0,0 +1,39 @@ +package com.alibaba.excel.metadata.property; + +import com.alibaba.excel.annotation.write.style.ContentRowHeight; +import com.alibaba.excel.annotation.write.style.HeadRowHeight; + +/** + * Configuration from annotations + * + * @author zhuangjiaju + */ +public class RowHeightProperty { + private Short height; + + public RowHeightProperty(Short height) { + this.height = height; + } + + public static RowHeightProperty build(HeadRowHeight headRowHeight) { + if (headRowHeight == null || headRowHeight.value() < 0) { + return null; + } + return new RowHeightProperty(headRowHeight.value()); + } + + public static RowHeightProperty build(ContentRowHeight contentRowHeight) { + if (contentRowHeight == null || contentRowHeight.value() < 0) { + return null; + } + return new RowHeightProperty(contentRowHeight.value()); + } + + public Short getHeight() { + return height; + } + + public void setHeight(Short height) { + this.height = height; + } +} diff --git a/src/main/java/com/alibaba/excel/util/StringUtils.java b/src/main/java/com/alibaba/excel/util/StringUtils.java index 83ddd18e..cf583883 100644 --- a/src/main/java/com/alibaba/excel/util/StringUtils.java +++ b/src/main/java/com/alibaba/excel/util/StringUtils.java @@ -32,6 +32,8 @@ import java.util.Set; import java.util.StringTokenizer; import java.util.TimeZone; +import org.apache.commons.codec.binary.CharSequenceUtils; + /** * Miscellaneous {@link String} utility methods. * @@ -1218,4 +1220,96 @@ public abstract class StringUtils { return arrayToDelimitedString(arr, ","); } + /** + *

    Compares two CharSequences, returning {@code true} if they represent + * equal sequences of characters.

    + * + *

    {@code null}s are handled without exceptions. Two {@code null} + * references are considered to be equal. The comparison is case sensitive.

    + * + *
    +     * StringUtils.equals(null, null)   = true
    +     * StringUtils.equals(null, "abc")  = false
    +     * StringUtils.equals("abc", null)  = false
    +     * StringUtils.equals("abc", "abc") = true
    +     * StringUtils.equals("abc", "ABC") = false
    +     * 
    + * + * @see Object#equals(Object) + * @param cs1 the first CharSequence, may be {@code null} + * @param cs2 the second CharSequence, may be {@code null} + * @return {@code true} if the CharSequences are equal (case-sensitive), or both {@code null} + * @since 3.0 Changed signature from equals(String, String) to equals(CharSequence, CharSequence) + */ + public static boolean equals(final CharSequence cs1, final CharSequence cs2) { + if (cs1 == cs2) { + return true; + } + if (cs1 == null || cs2 == null) { + return false; + } + if (cs1.length() != cs2.length()) { + return false; + } + if (cs1 instanceof String && cs2 instanceof String) { + return cs1.equals(cs2); + } + return regionMatches(cs1, false, 0, cs2, 0, cs1.length()); + } + + /** + * Green implementation of regionMatches. + * + * @param cs the {@code CharSequence} to be processed + * @param ignoreCase whether or not to be case insensitive + * @param thisStart the index to start on the {@code cs} CharSequence + * @param substring the {@code CharSequence} to be looked for + * @param start the index to start on the {@code substring} CharSequence + * @param length character length of the region + * @return whether the region matched + */ + static boolean regionMatches(final CharSequence cs, final boolean ignoreCase, final int thisStart, + final CharSequence substring, final int start, final int length) { + if (cs instanceof String && substring instanceof String) { + return ((String) cs).regionMatches(ignoreCase, thisStart, (String) substring, start, length); + } + int index1 = thisStart; + int index2 = start; + int tmpLen = length; + + // Extract these first so we detect NPEs the same as the java.lang.String version + final int srcLen = cs.length() - thisStart; + final int otherLen = substring.length() - start; + + // Check for invalid parameters + if (thisStart < 0 || start < 0 || length < 0) { + return false; + } + + // Check that the regions are long enough + if (srcLen < length || otherLen < length) { + return false; + } + + while (tmpLen-- > 0) { + final char c1 = cs.charAt(index1++); + final char c2 = substring.charAt(index2++); + + if (c1 == c2) { + continue; + } + + if (!ignoreCase) { + return false; + } + + // The same check as in String.regionMatches(): + if (Character.toUpperCase(c1) != Character.toUpperCase(c2) + && Character.toLowerCase(c1) != Character.toLowerCase(c2)) { + return false; + } + } + + return true; + } } diff --git a/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java b/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java index 9d558c56..fe0f0540 100644 --- a/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java +++ b/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java @@ -1,6 +1,7 @@ package com.alibaba.excel.write; import java.util.List; +import java.util.Map; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; @@ -11,11 +12,11 @@ import com.alibaba.excel.context.WriteContextImpl; import com.alibaba.excel.converters.Converter; import com.alibaba.excel.exception.ExcelDataConvertException; import com.alibaba.excel.metadata.CellData; -import com.alibaba.excel.metadata.ExcelColumnProperty; import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.Sheet; import com.alibaba.excel.metadata.Table; import com.alibaba.excel.metadata.holder.ConfigurationSelector; +import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.util.CollectionUtils; import com.alibaba.excel.util.POITempFile; import com.alibaba.excel.util.WorkBookUtil; @@ -122,33 +123,83 @@ public class ExcelBuilderImpl implements ExcelBuilder { if (CollectionUtils.isEmpty(oneRowData)) { return; } - List headList = context.currentConfigurationSelector().excelHeadProperty().getHeadList(); - for (int i = 0; i < oneRowData.size(); i++) { - Head head = i <= headList.size() ? headList.get(i) : null; - beforeCellCreate(row, head, relativeRowIndex); - Cell cell = WorkBookUtil.createCell(row, i); - Object value = oneRowData.get(i); - converterAndSet(context.currentConfigurationSelector(), value.getClass(), cell, value, null); - afterCellCreate(head, cell, relativeRowIndex); + Map headMap = context.currentConfigurationSelector().excelHeadProperty().getHeadMap(); + int dataIndex = 0; + int cellIndex = 0; + for (Map.Entry entry : headMap.entrySet()) { + if (dataIndex >= oneRowData.size()) { + return; + } + cellIndex = entry.getKey(); + Head head = entry.getValue(); + doAddBasicTypeToExcel(oneRowData, head, row, relativeRowIndex, dataIndex++, cellIndex); + } + // Finish + if (dataIndex >= oneRowData.size()) { + return; + } + if (cellIndex != 0) { + cellIndex++; + } + for (int i = 0; i < oneRowData.size() - dataIndex; i++) { + doAddBasicTypeToExcel(oneRowData, null, row, relativeRowIndex, dataIndex++, cellIndex++); } } + private void doAddBasicTypeToExcel(List oneRowData, Head head, Row row, int relativeRowIndex, int dataIndex, + int cellIndex) { + beforeCellCreate(row, head, relativeRowIndex); + Cell cell = WorkBookUtil.createCell(row, cellIndex); + Object value = oneRowData.get(dataIndex); + converterAndSet(context.currentConfigurationSelector(), value.getClass(), cell, value, null); + afterCellCreate(head, cell, relativeRowIndex); + } + private void addJavaObjectToExcel(Object oneRowData, Row row, int relativeRowIndex) { ConfigurationSelector currentConfigurationSelector = context.currentConfigurationSelector(); - int i = 0; BeanMap beanMap = BeanMap.create(oneRowData); - List headList = context.currentConfigurationSelector().excelHeadProperty().getHeadList(); - for (ExcelColumnProperty excelHeadProperty : currentConfigurationSelector.excelHeadProperty() - .getColumnPropertyList()) { - Head head = i <= headList.size() ? headList.get(i) : null; + Map headMap = context.currentConfigurationSelector().excelHeadProperty().getHeadMap(); + Map contentPropertyMap = + context.currentConfigurationSelector().excelHeadProperty().getContentPropertyMap(); + int cellIndex = 0; + for (Map.Entry entry : contentPropertyMap.entrySet()) { + cellIndex = entry.getKey(); + ExcelContentProperty excelContentProperty = entry.getValue(); + String name = excelContentProperty.getField().getName(); + if (!beanMap.containsKey(name)) { + continue; + } + Head head = headMap.get(cellIndex); beforeCellCreate(row, head, relativeRowIndex); - Cell cell = WorkBookUtil.createCell(row, i); - Object value = beanMap.get(excelHeadProperty.getField().getName()); - converterAndSet(currentConfigurationSelector, excelHeadProperty.getField().getType(), cell, value, - excelHeadProperty); + Cell cell = WorkBookUtil.createCell(row, cellIndex); + Object value = beanMap.get(name); + converterAndSet(currentConfigurationSelector, excelContentProperty.getField().getType(), cell, value, + excelContentProperty); afterCellCreate(head, cell, relativeRowIndex); - i++; + beanMap.remove(name); + } + // Finish + if (beanMap.isEmpty()) { + return; } + if (cellIndex != 0) { + cellIndex++; + } + for (Object value : beanMap.values()) { + beforeCellCreate(row, null, relativeRowIndex); + Cell cell = WorkBookUtil.createCell(row, cellIndex++); + converterAndSet(currentConfigurationSelector, value.getClass(), cell, value, null); + afterCellCreate(null, cell, relativeRowIndex); + } + } + + private void doAddJavaObjectToExcel(List oneRowData, Head head, Row row, int relativeRowIndex, + int dataIndex, int cellIndex) { + beforeCellCreate(row, head, relativeRowIndex); + Cell cell = WorkBookUtil.createCell(row, cellIndex); + Object value = oneRowData.get(dataIndex); + converterAndSet(context.currentConfigurationSelector(), value.getClass(), cell, value, null); + afterCellCreate(head, cell, relativeRowIndex); } private void beforeCellCreate(Row row, Head head, int relativeRowIndex) { @@ -184,11 +235,11 @@ public class ExcelBuilderImpl implements ExcelBuilder { } private void converterAndSet(ConfigurationSelector currentConfigurationSelector, Class clazz, Cell cell, - Object value, ExcelColumnProperty excelHeadProperty) { + Object value, ExcelContentProperty excelContentProperty) { if (value == null) { return; } - Converter converter = currentConfigurationSelector.converterMap().get(excelHeadProperty.getField().getType()); + Converter converter = currentConfigurationSelector.converterMap().get(clazz); if (converter == null) { throw new ExcelDataConvertException( "Can not find 'Converter' support class " + clazz.getSimpleName() + "."); @@ -196,7 +247,7 @@ public class ExcelBuilderImpl implements ExcelBuilder { CellData cellData; try { - cellData = converter.convertToExcelData(value, excelHeadProperty); + cellData = converter.convertToExcelData(value, excelContentProperty); } catch (Exception e) { throw new ExcelDataConvertException("Convert data:" + value + " error,at row:" + cell.getRow().getRowNum(), e); diff --git a/src/main/java/com/alibaba/excel/write/builder/ExcelWriterBuilder.java b/src/main/java/com/alibaba/excel/write/builder/ExcelWriterBuilder.java index 8e7cf64a..6bbab002 100644 --- a/src/main/java/com/alibaba/excel/write/builder/ExcelWriterBuilder.java +++ b/src/main/java/com/alibaba/excel/write/builder/ExcelWriterBuilder.java @@ -60,8 +60,7 @@ public class ExcelWriterBuilder { } /** - * You can only choose one of the {@link ExcelWriterBuilder#head(List)} and - * {@link ExcelWriterBuilder#head(Class)} + * You can only choose one of the {@link ExcelWriterBuilder#head(List)} and {@link ExcelWriterBuilder#head(Class)} * * @param head * @return @@ -72,8 +71,7 @@ public class ExcelWriterBuilder { } /** - * You can only choose one of the {@link ExcelWriterBuilder#head(List)} and - * {@link ExcelWriterBuilder#head(Class)} + * You can only choose one of the {@link ExcelWriterBuilder#head(List)} and {@link ExcelWriterBuilder#head(Class)} * * @param clazz * @return @@ -102,6 +100,22 @@ public class ExcelWriterBuilder { return this; } + /** + * The default is all excel objects.if true , you can use {@link com.alibaba.excel.annotation.ExcelIgnore} ignore a + * field. if false , you must use {@link com.alibaba.excel.annotation.ExcelProperty} to use a filed. + *

    + * Default true + * + * @param convertAllFiled + * @return + * @deprecated Just to be compatible with historical data, The default is always going to be convert all filed. + */ + @Deprecated + public ExcelWriterBuilder convertAllFiled(Boolean convertAllFiled) { + workbook.setConvertAllFiled(convertAllFiled); + return this; + } + /** * Custom type conversions override the default. * 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 e02e7604..770320b9 100644 --- a/src/main/java/com/alibaba/excel/write/handler/CellWriteHandler.java +++ b/src/main/java/com/alibaba/excel/write/handler/CellWriteHandler.java @@ -18,15 +18,25 @@ public interface CellWriteHandler extends WriteHandler { /** * called before create the cell * - * @param writeContext + * @param sheetHolder + * @param tableHolder + * @param row + * @param head + * @param relativeRowIndex + * @param isHead */ void beforeCellCreate(SheetHolder sheetHolder, @Nullable TableHolder tableHolder, Row row, Head head, int relativeRowIndex, boolean isHead); /** * called after the cell is created - * - * @param writeContext + * + * @param sheetHolder + * @param tableHolder + * @param cell + * @param head + * @param relativeRowIndex + * @param isHead */ void afterCellCreate(SheetHolder sheetHolder, @Nullable TableHolder tableHolder, Cell cell, Head head, int relativeRowIndex, boolean isHead); diff --git a/src/main/java/com/alibaba/excel/write/handler/DefaultWriteHandlerBuilder.java b/src/main/java/com/alibaba/excel/write/handler/DefaultWriteHandlerLoader.java similarity index 93% rename from src/main/java/com/alibaba/excel/write/handler/DefaultWriteHandlerBuilder.java rename to src/main/java/com/alibaba/excel/write/handler/DefaultWriteHandlerLoader.java index 6d00d862..49a8126e 100644 --- a/src/main/java/com/alibaba/excel/write/handler/DefaultWriteHandlerBuilder.java +++ b/src/main/java/com/alibaba/excel/write/handler/DefaultWriteHandlerLoader.java @@ -10,11 +10,11 @@ import com.alibaba.excel.metadata.Font; import com.alibaba.excel.write.style.RowCellStyleStrategy; /** - * Build default handler + * Load default handler * * @author zhuangjiaju */ -public class DefaultWriteHandlerBuilder { +public class DefaultWriteHandlerLoader { /** * Load default handler diff --git a/src/main/java/com/alibaba/excel/write/handler/RowWriteHandler.java b/src/main/java/com/alibaba/excel/write/handler/RowWriteHandler.java index db7ed3db..7a08e18b 100644 --- a/src/main/java/com/alibaba/excel/write/handler/RowWriteHandler.java +++ b/src/main/java/com/alibaba/excel/write/handler/RowWriteHandler.java @@ -16,15 +16,23 @@ public interface RowWriteHandler extends WriteHandler { /** * called before create the row * - * @param writeContext + * @param sheetHolder + * @param tableHolder + * @param rowIndex + * @param relativeRowIndex + * @param isHead */ void beforeRowCreate(SheetHolder sheetHolder, @Nullable TableHolder tableHolder, int rowIndex, int relativeRowIndex, boolean isHead); /** * called after the row is created - * - * @param writeContext + * + * @param sheetHolder + * @param tableHolder + * @param row + * @param relativeRowIndex + * @param isHead */ void afterRowCreate(SheetHolder sheetHolder, @Nullable TableHolder tableHolder, Row row, int relativeRowIndex, boolean isHead); diff --git a/src/main/java/com/alibaba/excel/write/handler/SheetWriteHandler.java b/src/main/java/com/alibaba/excel/write/handler/SheetWriteHandler.java index d6342384..5290c3b4 100644 --- a/src/main/java/com/alibaba/excel/write/handler/SheetWriteHandler.java +++ b/src/main/java/com/alibaba/excel/write/handler/SheetWriteHandler.java @@ -13,14 +13,16 @@ public interface SheetWriteHandler extends WriteHandler { /** * called before create the sheet * - * @param writeContext + * @param workbookHolder + * @param sheetHolder */ void beforeSheetCreate(WorkbookHolder workbookHolder, SheetHolder sheetHolder); /** * called after the sheet is created - * - * @param writeContext + * + * @param workbookHolder + * @param sheetHolder */ void afterSheetCreate(WorkbookHolder workbookHolder, SheetHolder sheetHolder); } diff --git a/src/main/java/com/alibaba/excel/write/handler/WorkbookWriteHandler.java b/src/main/java/com/alibaba/excel/write/handler/WorkbookWriteHandler.java index 9edb0182..2b6a9e0b 100644 --- a/src/main/java/com/alibaba/excel/write/handler/WorkbookWriteHandler.java +++ b/src/main/java/com/alibaba/excel/write/handler/WorkbookWriteHandler.java @@ -11,15 +11,13 @@ public interface WorkbookWriteHandler extends WriteHandler { /** * called before create the sheet - * - * @param writeContext */ void beforeWorkbookCreate(); /** * called after the sheet is created - * - * @param writeContext + * + * @param workbookHolder */ void afterWorkbookCreate(WorkbookHolder workbookHolder); } 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 3a93698c..b9b8adc7 100644 --- a/src/main/java/com/alibaba/excel/write/merge/AbstractMergeStrategy.java +++ b/src/main/java/com/alibaba/excel/write/merge/AbstractMergeStrategy.java @@ -9,6 +9,11 @@ import com.alibaba.excel.metadata.holder.SheetHolder; import com.alibaba.excel.metadata.holder.TableHolder; import com.alibaba.excel.write.handler.CellWriteHandler; +/** + * Merge strategy + * + * @author zhuangjiaju + */ public abstract class AbstractMergeStrategy implements CellWriteHandler { @Override @@ -24,5 +29,13 @@ public abstract class AbstractMergeStrategy implements CellWriteHandler { merge(sheetHolder.getSheet(), cell, head, relativeRowIndex); } + /** + * merge + * + * @param sheet + * @param cell + * @param head + * @param relativeRowIndex + */ protected abstract void merge(Sheet sheet, Cell cell, Head head, int relativeRowIndex); } 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 6a1fe82d..887def2b 100644 --- a/src/main/java/com/alibaba/excel/write/style/AbstractCellStyleStrategy.java +++ b/src/main/java/com/alibaba/excel/write/style/AbstractCellStyleStrategy.java @@ -12,6 +12,11 @@ import com.alibaba.excel.metadata.holder.WorkbookHolder; import com.alibaba.excel.write.handler.CellWriteHandler; import com.alibaba.excel.write.handler.WorkbookWriteHandler; +/** + * Cell style strategy + * + * @author zhuangjiaju + */ public abstract class AbstractCellStyleStrategy implements CellWriteHandler, WorkbookWriteHandler, NotRepeatExecutor { @Override public String uniqueValue() { @@ -41,10 +46,29 @@ public abstract class AbstractCellStyleStrategy implements CellWriteHandler, Wor } + /** + * Initialization cell style + * + * @param workbook + */ protected abstract void initCellStyle(Workbook workbook); + /** + * Sets the cell style of header + * + * @param cell + * @param head + * @param relativeRowIndex + */ protected abstract void setHeadCellStyle(Cell cell, Head head, int relativeRowIndex); + /** + * Sets the cell style of content + * + * @param cell + * @param head + * @param relativeRowIndex + */ protected abstract void setContentCellStyle(Cell cell, Head head, int relativeRowIndex); } diff --git a/src/main/java/com/alibaba/excel/write/style/AbstractColumnCellStyleStrategy.java b/src/main/java/com/alibaba/excel/write/style/AbstractColumnCellStyleStrategy.java index 5a842660..cb43f073 100644 --- a/src/main/java/com/alibaba/excel/write/style/AbstractColumnCellStyleStrategy.java +++ b/src/main/java/com/alibaba/excel/write/style/AbstractColumnCellStyleStrategy.java @@ -9,6 +9,7 @@ import org.apache.poi.ss.usermodel.Workbook; import com.alibaba.excel.metadata.Head; import com.alibaba.excel.util.StyleUtil; +import com.sun.istack.internal.Nullable; /** * @@ -31,22 +32,40 @@ public abstract class AbstractColumnCellStyleStrategy extends AbstractCellStyleS protected void setHeadCellStyle(Cell cell, Head head, int relativeRowIndex) { int columnIndex = head.getColumnIndex(); if (headCellStyleCache.containsKey(columnIndex)) { - cell.setCellStyle(headCellStyleCache.get(columnIndex)); + CellStyle cellStyle = headCellStyleCache.get(columnIndex); + if (cellStyle != null) { + cell.setCellStyle(cellStyle); + } + return; + } + com.alibaba.excel.metadata.CellStyle headCellStyle = headCellStyle(head); + if (headCellStyle == null) { + headCellStyleCache.put(columnIndex, null); + } else { + CellStyle cellStyle = StyleUtil.buildHeadCellStyle(workbook, headCellStyle(head)); + headCellStyleCache.put(columnIndex, cellStyle); + cell.setCellStyle(cellStyle); } - CellStyle cellStyle = StyleUtil.buildHeadCellStyle(workbook, headCellStyle(head)); - headCellStyleCache.put(columnIndex, cellStyle); - cell.setCellStyle(cellStyle); } @Override protected void setContentCellStyle(Cell cell, Head head, int relativeRowIndex) { int columnIndex = head.getColumnIndex(); if (contentCellStyleCache.containsKey(columnIndex)) { - cell.setCellStyle(contentCellStyleCache.get(columnIndex)); + CellStyle cellStyle = contentCellStyleCache.get(columnIndex); + if (cellStyle != null) { + cell.setCellStyle(cellStyle); + } + return; + } + com.alibaba.excel.metadata.CellStyle contentCellStyle = contentCellStyle(head); + if (contentCellStyle == null) { + contentCellStyleCache.put(columnIndex, null); + } else { + CellStyle cellStyle = StyleUtil.buildContentCellStyle(workbook, contentCellStyle(head)); + contentCellStyleCache.put(columnIndex, cellStyle); + cell.setCellStyle(cellStyle); } - CellStyle cellStyle = StyleUtil.buildContentCellStyle(workbook, contentCellStyle(head)); - contentCellStyleCache.put(columnIndex, cellStyle); - cell.setCellStyle(cellStyle); } /** @@ -55,7 +74,7 @@ public abstract class AbstractColumnCellStyleStrategy extends AbstractCellStyleS * @param head * @return */ - protected abstract com.alibaba.excel.metadata.CellStyle headCellStyle(Head head); + protected abstract com.alibaba.excel.metadata.CellStyle headCellStyle(@Nullable Head head); /** * Returns the column width corresponding to each column head @@ -63,6 +82,6 @@ public abstract class AbstractColumnCellStyleStrategy extends AbstractCellStyleS * @param head * @return */ - protected abstract com.alibaba.excel.metadata.CellStyle contentCellStyle(Head head); + protected abstract com.alibaba.excel.metadata.CellStyle contentCellStyle(@Nullable Head head); } 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 0f469801..610aa026 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 @@ -9,6 +9,7 @@ import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.holder.SheetHolder; import com.alibaba.excel.metadata.holder.TableHolder; import com.alibaba.excel.write.handler.CellWriteHandler; +import com.sun.istack.internal.Nullable; /** * Column width style strategy @@ -29,7 +30,7 @@ public abstract class AbstractColumnWidthStyleStrategy implements CellWriteHandl @Override public void afterCellCreate(SheetHolder sheetHolder, TableHolder tableHolder, Cell cell, Head head, int relativeRowIndex, boolean isHead) { - if (!isHead) { + if (!isHead && relativeRowIndex != 0) { return; } setColumnWidth(sheetHolder.getSheet(), cell, head); @@ -42,6 +43,6 @@ public abstract class AbstractColumnWidthStyleStrategy implements CellWriteHandl * @param cell * @param head */ - protected abstract void setColumnWidth(Sheet sheet, Cell cell, Head head); + protected abstract void setColumnWidth(Sheet sheet, Cell cell, @Nullable Head head); } 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 88ac289b..d51724d2 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 @@ -4,6 +4,7 @@ import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Sheet; import com.alibaba.excel.metadata.Head; +import com.sun.istack.internal.Nullable; /** * Returns the column width according to each column header @@ -13,17 +14,21 @@ import com.alibaba.excel.metadata.Head; public abstract class AbstractHeadColumnWidthStyleStrategy extends AbstractColumnWidthStyleStrategy { @Override protected void setColumnWidth(Sheet sheet, Cell cell, Head head) { - sheet.setColumnWidth(cell.getColumnIndex(), columnWidth(head)); + Integer width = columnWidth(head); + if (width != null) { + sheet.setColumnWidth(cell.getColumnIndex(), columnWidth(head)); + } } /** * Returns the column width corresponding to each column head. - * + * + *

  • if return null,ignore * * @param head * @return the width in units of 1/256th of a character width . Using the Calibri font as an example, the maximum * digit width of 11 point font size is 7 pixels (at 96 dpi). If you set a column width to be eight * characters wide, e.g. you need return 8*256 */ - protected abstract int columnWidth(Head head); + protected abstract Integer columnWidth(@Nullable Head head); } diff --git a/src/main/java/com/alibaba/excel/write/style/column/SimpleColumnWidthStyleStrategy.java b/src/main/java/com/alibaba/excel/write/style/column/SimpleColumnWidthStyleStrategy.java index 969c08bf..70ba0a57 100644 --- a/src/main/java/com/alibaba/excel/write/style/column/SimpleColumnWidthStyleStrategy.java +++ b/src/main/java/com/alibaba/excel/write/style/column/SimpleColumnWidthStyleStrategy.java @@ -11,7 +11,7 @@ import com.alibaba.excel.metadata.Head; * @author zhuangjiaju */ public class SimpleColumnWidthStyleStrategy extends AbstractColumnWidthStyleStrategy { - private int columnWidth; + private Integer columnWidth; /** * Using the Calibri font as an example, the maximum digit width of 11 point font size is 7 pixels (at 96 dpi). * If @@ -20,12 +20,14 @@ public class SimpleColumnWidthStyleStrategy extends AbstractColumnWidthStyleStra * @param columnWidth * the width in units of 1/256th of a character width */ - public SimpleColumnWidthStyleStrategy(int columnWidth) { + public SimpleColumnWidthStyleStrategy(Integer columnWidth) { this.columnWidth = columnWidth; } @Override protected void setColumnWidth(Sheet sheet, Cell cell, Head head) { - sheet.setColumnWidth(cell.getColumnIndex(), columnWidth); + if (columnWidth != null) { + sheet.setColumnWidth(cell.getColumnIndex(), columnWidth); + } } } diff --git a/src/main/java/com/alibaba/excel/write/style/row/AbstractRowHighStyleStrategy.java b/src/main/java/com/alibaba/excel/write/style/row/AbstractRowHeightStyleStrategy.java similarity index 54% rename from src/main/java/com/alibaba/excel/write/style/row/AbstractRowHighStyleStrategy.java rename to src/main/java/com/alibaba/excel/write/style/row/AbstractRowHeightStyleStrategy.java index aeb4c68f..9961c705 100644 --- a/src/main/java/com/alibaba/excel/write/style/row/AbstractRowHighStyleStrategy.java +++ b/src/main/java/com/alibaba/excel/write/style/row/AbstractRowHeightStyleStrategy.java @@ -7,7 +7,12 @@ import com.alibaba.excel.metadata.holder.SheetHolder; import com.alibaba.excel.metadata.holder.TableHolder; import com.alibaba.excel.write.handler.RowWriteHandler; -public abstract class AbstractRowHighStyleStrategy implements RowWriteHandler, NotRepeatExecutor { +/** + * Set the row height strategy + * + * @author zhuangjiaju + */ +public abstract class AbstractRowHeightStyleStrategy implements RowWriteHandler, NotRepeatExecutor { @Override public String uniqueValue() { @@ -24,14 +29,26 @@ public abstract class AbstractRowHighStyleStrategy implements RowWriteHandler, N public void afterRowCreate(SheetHolder sheetHolder, TableHolder tableHolder, Row row, int relativeRowIndex, boolean isHead) { if (isHead) { - setHeadColumnHigh(row, relativeRowIndex); + setHeadColumnHeight(row, relativeRowIndex); } else { - setContentColumnHigh(row, relativeRowIndex); + setContentColumnHeight(row, relativeRowIndex); } } - protected abstract void setHeadColumnHigh(Row row, int relativeRowIndex); - - protected abstract void setContentColumnHigh(Row row, int relativeRowIndex); + /** + * Sets the height of header + * + * @param row + * @param relativeRowIndex + */ + protected abstract void setHeadColumnHeight(Row row, int relativeRowIndex); + + /** + * Sets the height of content + * + * @param row + * @param relativeRowIndex + */ + protected abstract void setContentColumnHeight(Row row, int relativeRowIndex); } diff --git a/src/main/java/com/alibaba/excel/write/style/row/SimpleRowHeightStyleStrategy.java b/src/main/java/com/alibaba/excel/write/style/row/SimpleRowHeightStyleStrategy.java new file mode 100644 index 00000000..a35a785d --- /dev/null +++ b/src/main/java/com/alibaba/excel/write/style/row/SimpleRowHeightStyleStrategy.java @@ -0,0 +1,33 @@ +package com.alibaba.excel.write.style.row; + +import org.apache.poi.ss.usermodel.Row; + +/** + * Set the head column high and content column high + * + * @author zhuangjiaju + */ +public class SimpleRowHeightStyleStrategy extends AbstractRowHeightStyleStrategy { + private Short headRowHeight; + private Short contentRowHeight; + + public SimpleRowHeightStyleStrategy(Short headRowHeight, Short contentRowHeight) { + this.headRowHeight = headRowHeight; + this.contentRowHeight = contentRowHeight; + } + + @Override + protected void setHeadColumnHeight(Row row, int relativeRowIndex) { + if (headRowHeight != null) { + row.setHeight(headRowHeight); + } + } + + @Override + protected void setContentColumnHeight(Row row, int relativeRowIndex) { + if (contentRowHeight != null) { + row.setHeight(contentRowHeight); + } + } + +} diff --git a/src/main/java/com/alibaba/excel/write/style/row/SimpleRowHighStyleStrategy.java b/src/main/java/com/alibaba/excel/write/style/row/SimpleRowHighStyleStrategy.java deleted file mode 100644 index f49b6183..00000000 --- a/src/main/java/com/alibaba/excel/write/style/row/SimpleRowHighStyleStrategy.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.alibaba.excel.write.style.row; - -import org.apache.poi.ss.usermodel.Row; - -/** - * Set the head column high and content column high - * - * @author zhuangjiaju - */ -public class SimpleRowHighStyleStrategy extends AbstractRowHighStyleStrategy { - private short headColumnHigh; - private short contentColumnHigh; - - public SimpleRowHighStyleStrategy(short headColumnHigh, short contentColumnHigh) { - this.headColumnHigh = headColumnHigh; - this.contentColumnHigh = contentColumnHigh; - } - - @Override - protected void setHeadColumnHigh(Row row, int relativeRowIndex) { - row.setHeight(headColumnHigh); - } - - @Override - protected void setContentColumnHigh(Row row, int relativeRowIndex) { - row.setHeight(contentColumnHigh); - } - -} diff --git a/src/test/java/com/alibaba/easyexcel/test/wirte/nohead/NoHeadData07Test.java b/src/test/java/com/alibaba/easyexcel/test/wirte/nohead/NoHeadData07Test.java new file mode 100644 index 00000000..8d17226f --- /dev/null +++ b/src/test/java/com/alibaba/easyexcel/test/wirte/nohead/NoHeadData07Test.java @@ -0,0 +1,40 @@ +package com.alibaba.easyexcel.test.wirte.nohead; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import com.alibaba.easyexcel.test.util.FileUtil; +import com.alibaba.easyexcel.test.wirte.order.OrderData; +import com.alibaba.excel.EasyExcelFactory; +import com.alibaba.excel.ExcelWriter; +import com.alibaba.excel.metadata.Sheet; + +/** + * Order data test + * + * @author zhuangjiaju + */ +public class NoHeadData07Test { + + @Test + public void simple() { + ExcelWriter writer = EasyExcelFactory.writerBuilder().outputFile(FileUtil.createNewWriteFile("order07.xlsx")) + .head(OrderData.class).build(); + Sheet sheet = EasyExcelFactory.writerSheetBuilder().sheetNo(0).sheetName("order").build(); + writer.write(createData(10000 * 100), sheet); + writer.finish(); + } + + private List createData(int count) { + List list = new ArrayList(); + for (int i = 0; i < count; i++) { + OrderData orderData = new OrderData(); + orderData.setIndex1("排序1:" + i); + orderData.setIndex10("排序10:" + i); + list.add(orderData); + } + return list; + } +}