Browse Source

加入写excel支持注解

pull/507/head
zhuangjiaju 5 years ago
parent
commit
058df4d77e
  1. 9
      src/main/java/com/alibaba/excel/EasyExcelFactory.java
  2. 10
      src/main/java/com/alibaba/excel/analysis/BaseSaxAnalyser.java
  3. 15
      src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java
  4. 34
      src/main/java/com/alibaba/excel/annotation/ExcelColumnNum.java
  5. 17
      src/main/java/com/alibaba/excel/annotation/ExcelIgnore.java
  6. 44
      src/main/java/com/alibaba/excel/annotation/ExcelProperty.java
  7. 36
      src/main/java/com/alibaba/excel/annotation/format/DateTimeFormat.java
  8. 37
      src/main/java/com/alibaba/excel/annotation/format/NumberFormat.java
  9. 26
      src/main/java/com/alibaba/excel/annotation/write/style/ColumnWidth.java
  10. 27
      src/main/java/com/alibaba/excel/annotation/write/style/ContentRowHeight.java
  11. 31
      src/main/java/com/alibaba/excel/annotation/write/style/ContentStyle.java
  12. 26
      src/main/java/com/alibaba/excel/annotation/write/style/HeadRowHeight.java
  13. 27
      src/main/java/com/alibaba/excel/annotation/write/style/HeadStyle.java
  14. 8
      src/main/java/com/alibaba/excel/constant/ExcelXmlConstants.java
  15. 2
      src/main/java/com/alibaba/excel/context/AnalysisContext.java
  16. 2
      src/main/java/com/alibaba/excel/context/AnalysisContextImpl.java
  17. 27
      src/main/java/com/alibaba/excel/context/WriteContextImpl.java
  18. 10
      src/main/java/com/alibaba/excel/converters/Converter.java
  19. 6
      src/main/java/com/alibaba/excel/converters/DefaultConverterLoader.java
  20. 6
      src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalBooleanConverter.java
  21. 6
      src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalNumberConverter.java
  22. 19
      src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalStringConverter.java
  23. 6
      src/main/java/com/alibaba/excel/converters/booleanconverter/BooleanBooleanConverter.java
  24. 6
      src/main/java/com/alibaba/excel/converters/booleanconverter/BooleanNumberConverter.java
  25. 6
      src/main/java/com/alibaba/excel/converters/booleanconverter/BooleanStringConverter.java
  26. 6
      src/main/java/com/alibaba/excel/converters/byteconverter/ByteBooleanConverter.java
  27. 6
      src/main/java/com/alibaba/excel/converters/byteconverter/ByteNumberConverter.java
  28. 6
      src/main/java/com/alibaba/excel/converters/byteconverter/ByteStringConverter.java
  29. 14
      src/main/java/com/alibaba/excel/converters/date/DateNumberConverter.java
  30. 19
      src/main/java/com/alibaba/excel/converters/date/DateStringConverter.java
  31. 6
      src/main/java/com/alibaba/excel/converters/doubleconverter/ByteBooleanConverter.java
  32. 35
      src/main/java/com/alibaba/excel/converters/doubleconverter/ByteNumberConverter.java
  33. 35
      src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleNumberConverter.java
  34. 6
      src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleStringConverter.java
  35. 6
      src/main/java/com/alibaba/excel/converters/string/StringStringConverter.java
  36. 6
      src/main/java/com/alibaba/excel/enums/CellDataTypeEnum.java
  37. 26
      src/main/java/com/alibaba/excel/event/ModelBuildEventListener.java
  38. 13
      src/main/java/com/alibaba/excel/metadata/CellStyle.java
  39. 105
      src/main/java/com/alibaba/excel/metadata/ExcelColumnProperty.java
  40. 287
      src/main/java/com/alibaba/excel/metadata/ExcelHeadProperty.java
  41. 43
      src/main/java/com/alibaba/excel/metadata/Head.java
  42. 16
      src/main/java/com/alibaba/excel/metadata/Workbook.java
  43. 107
      src/main/java/com/alibaba/excel/metadata/holder/AbstractConfigurationSelector.java
  44. 2
      src/main/java/com/alibaba/excel/metadata/holder/ConfigurationSelector.java
  45. 10
      src/main/java/com/alibaba/excel/metadata/holder/SheetHolder.java
  46. 9
      src/main/java/com/alibaba/excel/metadata/holder/TableHolder.java
  47. 33
      src/main/java/com/alibaba/excel/metadata/holder/WorkbookHolder.java
  48. 84
      src/main/java/com/alibaba/excel/metadata/property/CellStyleProperty.java
  49. 31
      src/main/java/com/alibaba/excel/metadata/property/ColumnWidthProperty.java
  50. 41
      src/main/java/com/alibaba/excel/metadata/property/DateTimeFormatProperty.java
  51. 62
      src/main/java/com/alibaba/excel/metadata/property/ExcelContentProperty.java
  52. 350
      src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java
  53. 43
      src/main/java/com/alibaba/excel/metadata/property/NumberFormatProperty.java
  54. 39
      src/main/java/com/alibaba/excel/metadata/property/RowHeightProperty.java
  55. 94
      src/main/java/com/alibaba/excel/util/StringUtils.java
  56. 95
      src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java
  57. 22
      src/main/java/com/alibaba/excel/write/builder/ExcelWriterBuilder.java
  58. 16
      src/main/java/com/alibaba/excel/write/handler/CellWriteHandler.java
  59. 4
      src/main/java/com/alibaba/excel/write/handler/DefaultWriteHandlerLoader.java
  60. 14
      src/main/java/com/alibaba/excel/write/handler/RowWriteHandler.java
  61. 8
      src/main/java/com/alibaba/excel/write/handler/SheetWriteHandler.java
  62. 6
      src/main/java/com/alibaba/excel/write/handler/WorkbookWriteHandler.java
  63. 13
      src/main/java/com/alibaba/excel/write/merge/AbstractMergeStrategy.java
  64. 24
      src/main/java/com/alibaba/excel/write/style/AbstractCellStyleStrategy.java
  65. 39
      src/main/java/com/alibaba/excel/write/style/AbstractColumnCellStyleStrategy.java
  66. 5
      src/main/java/com/alibaba/excel/write/style/column/AbstractColumnWidthStyleStrategy.java
  67. 11
      src/main/java/com/alibaba/excel/write/style/column/AbstractHeadColumnWidthStyleStrategy.java
  68. 8
      src/main/java/com/alibaba/excel/write/style/column/SimpleColumnWidthStyleStrategy.java
  69. 29
      src/main/java/com/alibaba/excel/write/style/row/AbstractRowHeightStyleStrategy.java
  70. 33
      src/main/java/com/alibaba/excel/write/style/row/SimpleRowHeightStyleStrategy.java
  71. 29
      src/main/java/com/alibaba/excel/write/style/row/SimpleRowHighStyleStrategy.java
  72. 40
      src/test/java/com/alibaba/easyexcel/test/wirte/nohead/NoHeadData07Test.java

9
src/main/java/com/alibaba/excel/EasyExcelFactory.java

@ -81,7 +81,8 @@ public class EasyExcelFactory {
*/ */
@Deprecated @Deprecated
public static ExcelWriter getWriter(OutputStream outputStream) { 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 @Deprecated
public static ExcelWriter getWriter(OutputStream outputStream, ExcelTypeEnum typeEnum, boolean needHead) { public static ExcelWriter getWriter(OutputStream outputStream, ExcelTypeEnum typeEnum, boolean needHead) {
return writerBuilder().outputFile(outputStream).excelType(typeEnum).needHead(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, public static ExcelWriter getWriterWithTemp(InputStream temp, OutputStream outputStream, ExcelTypeEnum typeEnum,
boolean needHead) { boolean needHead) {
return writerBuilder().withTemplate(temp).outputFile(outputStream).excelType(typeEnum).needHead(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, public static ExcelWriter getWriterWithTempAndHandler(InputStream temp, OutputStream outputStream,
ExcelTypeEnum typeEnum, boolean needHead, WriteHandler handler) { ExcelTypeEnum typeEnum, boolean needHead, WriteHandler handler) {
return writerBuilder().withTemplate(temp).outputFile(outputStream).excelType(typeEnum).needHead(needHead) 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() { public static ExcelWriterBuilder writerBuilder() {

10
src/main/java/com/alibaba/excel/analysis/BaseSaxAnalyser.java

@ -1,6 +1,5 @@
package com.alibaba.excel.analysis; package com.alibaba.excel.analysis;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; 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.Converter;
import com.alibaba.excel.converters.ConverterKey; import com.alibaba.excel.converters.ConverterKey;
import com.alibaba.excel.converters.ConverterRegistryCenter; import com.alibaba.excel.converters.ConverterRegistryCenter;
import com.alibaba.excel.converters.DefaultConverterBuilder; import com.alibaba.excel.converters.DefaultConverterLoader;
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.event.AnalysisEventListener; import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.event.AnalysisEventRegistryCenter; import com.alibaba.excel.event.AnalysisEventRegistryCenter;
import com.alibaba.excel.event.AnalysisFinishEvent; 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; import com.alibaba.excel.metadata.Sheet;
/** /**
@ -56,7 +52,7 @@ public abstract class BaseSaxAnalyser implements ConverterRegistryCenter, Analys
} }
private void registerDefaultConverters() { private void registerDefaultConverters() {
converters.putAll(DefaultConverterBuilder.loadDefaultReadConverter()); converters.putAll(DefaultConverterLoader.loadDefaultReadConverter());
} }
@Override @Override

15
src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java

@ -1,15 +1,16 @@
package com.alibaba.excel.analysis.v07.handlers; 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_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_TAG;
import static com.alibaba.excel.constant.ExcelXmlConstants.CELL_VALUE_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 static com.alibaba.excel.constant.ExcelXmlConstants.CELL_VALUE_TYPE_TAG;
import java.util.Arrays; import java.util.Arrays;
import org.apache.poi.ss.usermodel.RichTextString; import org.apache.poi.ss.usermodel.RichTextString;
import org.apache.poi.xssf.model.SharedStringsTable; import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.xml.sax.Attributes; import org.xml.sax.Attributes;
import com.alibaba.excel.analysis.v07.XlsxCellHandler; import com.alibaba.excel.analysis.v07.XlsxCellHandler;
@ -48,7 +49,7 @@ public class DefaultCellHandler implements XlsxCellHandler, XlsxRowResultHolder
@Override @Override
public boolean support(String name) { 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); || CELL_TAG.equals(name);
} }
@ -61,13 +62,14 @@ public class DefaultCellHandler implements XlsxCellHandler, XlsxRowResultHolder
int nextRow = PositionUtils.getRow(currentCellIndex); int nextRow = PositionUtils.getRow(currentCellIndex);
if (nextRow > curRow) { if (nextRow > curRow) {
curRow = nextRow; curRow = nextRow;
// endRow(ROW_TAG);
} }
analysisContext.setCurrentRowNum(curRow); analysisContext.setCurrentRowNum(curRow);
curCol = PositionUtils.getCol(currentCellIndex); curCol = PositionUtils.getCol(currentCellIndex);
// t="s" ,it's means String // t="s" ,it's means String
// t="inlineStr" ,it's means String
// t="b" ,it's means Boolean // t="b" ,it's means Boolean
// t="e" ,it's means Error
// t is null ,it's means Empty or Number // t is null ,it's means Empty or Number
CellDataTypeEnum type = CellDataTypeEnum.buildFromCellType(attributes.getValue(CELL_VALUE_TYPE_TAG)); CellDataTypeEnum type = CellDataTypeEnum.buildFromCellType(attributes.getValue(CELL_VALUE_TYPE_TAG));
currentCellData = new CellData(type); currentCellData = new CellData(type);
@ -89,6 +91,13 @@ public class DefaultCellHandler implements XlsxCellHandler, XlsxRowResultHolder
} }
curRowContent[curCol] = currentCellData; 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() { private void ensureSize() {

34
src/main/java/com/alibaba/excel/annotation/ExcelColumnNum.java

@ -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 "";
}

17
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 {}

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

@ -14,20 +14,32 @@ import java.lang.annotation.Target;
@Inherited @Inherited
public @interface ExcelProperty { public @interface ExcelProperty {
/** /**
* @return * The name of the sheet header.
*/ *
String[] value() default {""}; * <li>write: It automatically merges when you have more than one head
/** * <li>read: When you have multiple heads, take the first one
* @return *
*/ * @return
int index() default 99999; */
/** String[] value() default {""};
*
* default @see com.alibaba.excel.util.TypeUtil /**
* if default is not meet you can set format * Index of column
* *
* @return * Read or write it on the index of column,If it's equal to -1, it's sorted by Java class
*/ *
String format() default ""; * @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 "";
} }

36
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.
*
* <li>write: It can be used on classes {@link java.util.Date}
* <li>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;
}

37
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.
*
* <li>write: It can be used on classes that inherit {@link Number}
* <li>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;
}

26
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. <code>8*256</code>
*
* <p>
* -1 mean the auto set width
*/
int value() default -1;
}

27
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
* <p>
* -1 mean the auto set height
*
* @return
*/
short value() default -1;
}

31
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.
*
* <li>write: It can be used on classes that inherit {@link Number}
* <li>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;
}

26
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
* <p>
* -1 mean the auto set height
*
* @return
*/
short value() default -1;
}

27
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;
}

8
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 ROW_TAG = "row";
public static final String CELL_TAG = "c"; 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_FORMULA_TAG = "f";
public static final String CELL_VALUE_TAG = "v"; public static final String CELL_VALUE_TAG = "v";
public static final String CELL_VALUE_TYPE_TAG = "t"; /**
* When the data is "inlineStr" his tag is "t"
public static final String CELL_VALUE_TAG_1 = "t"; */
public static final String CELL_INLINE_STRING_VALUE_TAG = "t";
} }

2
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.converters.ConverterRegistryCenter;
import com.alibaba.excel.event.AnalysisEventListener; 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.metadata.Sheet;
import com.alibaba.excel.support.ExcelTypeEnum; import com.alibaba.excel.support.ExcelTypeEnum;

2
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.converters.ConverterRegistryCenter;
import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelAnalysisException; 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.metadata.Sheet;
import com.alibaba.excel.support.ExcelTypeEnum; import com.alibaba.excel.support.ExcelTypeEnum;

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

@ -2,6 +2,7 @@ package com.alibaba.excel.context;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.Map;
import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Row;
@ -11,13 +12,13 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.alibaba.excel.exception.ExcelGenerateException; import com.alibaba.excel.exception.ExcelGenerateException;
import com.alibaba.excel.metadata.ExcelHeadProperty;
import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.Table; import com.alibaba.excel.metadata.Table;
import com.alibaba.excel.metadata.holder.ConfigurationSelector; import com.alibaba.excel.metadata.holder.ConfigurationSelector;
import com.alibaba.excel.metadata.holder.SheetHolder; import com.alibaba.excel.metadata.holder.SheetHolder;
import com.alibaba.excel.metadata.holder.TableHolder; import com.alibaba.excel.metadata.holder.TableHolder;
import com.alibaba.excel.metadata.holder.WorkbookHolder; import com.alibaba.excel.metadata.holder.WorkbookHolder;
import com.alibaba.excel.metadata.property.ExcelHeadProperty;
import com.alibaba.excel.util.WorkBookUtil; import com.alibaba.excel.util.WorkBookUtil;
import com.alibaba.excel.write.handler.CellWriteHandler; import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.handler.RowWriteHandler; import com.alibaba.excel.write.handler.RowWriteHandler;
@ -184,9 +185,6 @@ public class WriteContextImpl implements WriteContext {
} }
currentSheetHolder.setSheet(currentSheet); currentSheetHolder.setSheet(currentSheet);
// Initialization head // Initialization head
currentSheetHolder
.setExcelHeadProperty(new ExcelHeadProperty(currentSheetHolder.getClazz(), currentSheetHolder.getHead()));
// Initialization head
initHead(currentSheetHolder.getExcelHeadProperty()); initHead(currentSheetHolder.getExcelHeadProperty());
} }
@ -203,7 +201,7 @@ public class WriteContextImpl implements WriteContext {
beforeRowCreate(rowIndex, relativeRowIndex); beforeRowCreate(rowIndex, relativeRowIndex);
Row row = WorkBookUtil.createRow(currentSheetHolder.getSheet(), i); Row row = WorkBookUtil.createRow(currentSheetHolder.getSheet(), i);
afterRowCreate(row, relativeRowIndex); 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) { 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, currentSheetHolder.getSheet().addMergedRegion(new CellRangeAddress(cellRangeModel.getFirstRow() + rowIndex,
cellRangeModel.getLastRow() + rowIndex, cellRangeModel.getFirstCol(), cellRangeModel.getLastCol())); cellRangeModel.getLastRow() + rowIndex, cellRangeModel.getFirstCol(), cellRangeModel.getLastCol()));
} }
} }
private void addOneRowOfHeadDataToExcel(Row row, List<Head> headList, int relativeRowIndex) { private void addOneRowOfHeadDataToExcel(Row row, Map<Integer, Head> headMap, int relativeRowIndex) {
for (int i = 0; i < headList.size(); i++) { for (Map.Entry<Integer, Head> entry : headMap.entrySet()) {
Head head = headList.get(i); Head head = entry.getValue();
beforeCellCreate(row, headList.get(i), relativeRowIndex); beforeCellCreate(row, head, relativeRowIndex);
Cell cell = WorkBookUtil.createCell(row, i, head.getHeadName(i)); Cell cell = WorkBookUtil.createCell(row, entry.getKey(), head.getHeadNameList().get(relativeRowIndex));
afterCellCreate(headList.get(i), cell, relativeRowIndex); afterCellCreate(head, cell, relativeRowIndex);
} }
} }
@ -302,14 +300,11 @@ public class WriteContextImpl implements WriteContext {
return; return;
} }
initCurrentTableHolder(table); initCurrentTableHolder(table);
// Initialization head
currentTableHolder
.setExcelHeadProperty(new ExcelHeadProperty(currentTableHolder.getClazz(), currentTableHolder.getHead()));
initHead(currentTableHolder.getExcelHeadProperty()); initHead(currentTableHolder.getExcelHeadProperty());
} }
private void initCurrentTableHolder(com.alibaba.excel.metadata.Table table) { 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); currentSheetHolder.getHasBeenInitializedTable().put(table.getTableNo(), currentTableHolder);
currentConfigurationSelector = currentTableHolder; currentConfigurationSelector = currentTableHolder;
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {

10
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.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData; 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.NotNull;
import com.sun.istack.internal.Nullable; import com.sun.istack.internal.Nullable;
@ -32,19 +32,19 @@ public interface Converter<T> {
* Convert excel objects to Java objects * Convert excel objects to Java objects
* *
* @param cellData * @param cellData
* @param columnProperty * @param contentProperty
* @return * @return
* @throws Exception * @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 * Convert Java objects to excel objects
* *
* @param value * @param value
* @param columnProperty * @param contentProperty
* @return * @return
* @throws Exception * @throws Exception
*/ */
CellData convertToExcelData(@NotNull T value, @Nullable ExcelColumnProperty columnProperty) throws Exception; CellData convertToExcelData(@NotNull T value, @Nullable ExcelContentProperty contentProperty) throws Exception;
} }

6
src/main/java/com/alibaba/excel/converters/DefaultConverterBuilder.java → 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; import com.alibaba.excel.converters.string.StringStringConverter;
/** /**
* Build default handler * Load default handler
* *
* @author zhuangjiaju * @author zhuangjiaju
*/ */
public class DefaultConverterBuilder { public class DefaultConverterLoader {
/** /**
* Load default wirte converter * Load default write converter
* *
* @return * @return
*/ */

6
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.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.ExcelColumnProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
/** /**
* BigDecimal and boolean converter * BigDecimal and boolean converter
@ -25,7 +25,7 @@ public class BigDecimalBooleanConverter implements Converter<BigDecimal> {
} }
@Override @Override
public BigDecimal convertToJavaData(CellData cellData, ExcelColumnProperty columnProperty) { public BigDecimal convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) {
if (cellData.getBooleanValue()) { if (cellData.getBooleanValue()) {
return BigDecimal.ONE; return BigDecimal.ONE;
} }
@ -33,7 +33,7 @@ public class BigDecimalBooleanConverter implements Converter<BigDecimal> {
} }
@Override @Override
public CellData convertToExcelData(BigDecimal value, ExcelColumnProperty columnProperty) { public CellData convertToExcelData(BigDecimal value, ExcelContentProperty contentProperty) {
if (BigDecimal.ONE.equals(value)) { if (BigDecimal.ONE.equals(value)) {
return new CellData(Boolean.TRUE); return new CellData(Boolean.TRUE);
} }

6
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.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.ExcelColumnProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
/** /**
* BigDecimal and number converter * BigDecimal and number converter
@ -25,12 +25,12 @@ public class BigDecimalNumberConverter implements Converter<BigDecimal> {
} }
@Override @Override
public BigDecimal convertToJavaData(CellData cellData, ExcelColumnProperty columnProperty) { public BigDecimal convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) {
return new BigDecimal(cellData.getDoubleValue()); return new BigDecimal(cellData.getDoubleValue());
} }
@Override @Override
public CellData convertToExcelData(BigDecimal value, ExcelColumnProperty columnProperty) { public CellData convertToExcelData(BigDecimal value, ExcelContentProperty contentProperty) {
return new CellData(value.doubleValue()); return new CellData(value.doubleValue());
} }
} }

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

@ -1,12 +1,13 @@
package com.alibaba.excel.converters.bigdecimal; package com.alibaba.excel.converters.bigdecimal;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.ExcelColumnProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.util.StringUtils; import com.alibaba.excel.util.StringUtils;
/** /**
@ -27,15 +28,23 @@ public class BigDecimalStringConverter implements Converter<BigDecimal> {
} }
@Override @Override
public BigDecimal convertToJavaData(CellData cellData, ExcelColumnProperty columnProperty) { public BigDecimal convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) {
return new BigDecimal(cellData.getStringValue()); return new BigDecimal(cellData.getStringValue());
} }
@Override @Override
public CellData convertToExcelData(BigDecimal value, ExcelColumnProperty columnProperty) { public CellData convertToExcelData(BigDecimal value, ExcelContentProperty contentProperty) {
if (StringUtils.isEmpty(columnProperty.getFormat())) { 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(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));
} }
} }

6
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.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.ExcelColumnProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
/** /**
* Boolean and boolean converter * Boolean and boolean converter
@ -23,12 +23,12 @@ public class BooleanBooleanConverter implements Converter<Boolean> {
} }
@Override @Override
public Boolean convertToJavaData(CellData cellData, ExcelColumnProperty columnProperty) { public Boolean convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) {
return cellData.getBooleanValue(); return cellData.getBooleanValue();
} }
@Override @Override
public CellData convertToExcelData(Boolean value, ExcelColumnProperty columnProperty) { public CellData convertToExcelData(Boolean value, ExcelContentProperty contentProperty) {
return new CellData(value); return new CellData(value);
} }

6
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.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.ExcelColumnProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
/** /**
* Boolean and number converter * Boolean and number converter
@ -26,7 +26,7 @@ public class BooleanNumberConverter implements Converter<Boolean> {
} }
@Override @Override
public Boolean convertToJavaData(CellData cellData, ExcelColumnProperty columnProperty) { public Boolean convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) {
if (ONE.equals(cellData.getDoubleValue())) { if (ONE.equals(cellData.getDoubleValue())) {
return Boolean.TRUE; return Boolean.TRUE;
} }
@ -34,7 +34,7 @@ public class BooleanNumberConverter implements Converter<Boolean> {
} }
@Override @Override
public CellData convertToExcelData(Boolean value, ExcelColumnProperty columnProperty) { public CellData convertToExcelData(Boolean value, ExcelContentProperty contentProperty) {
if (value) { if (value) {
return new CellData(ONE); return new CellData(ONE);
} }

6
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.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.ExcelColumnProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
/** /**
* Boolean and string converter * Boolean and string converter
@ -23,12 +23,12 @@ public class BooleanStringConverter implements Converter<Boolean> {
} }
@Override @Override
public Boolean convertToJavaData(CellData cellData, ExcelColumnProperty columnProperty) { public Boolean convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) {
return Boolean.valueOf(cellData.getStringValue()); return Boolean.valueOf(cellData.getStringValue());
} }
@Override @Override
public CellData convertToExcelData(Boolean value, ExcelColumnProperty columnProperty) { public CellData convertToExcelData(Boolean value, ExcelContentProperty contentProperty) {
return new CellData(value.toString()); return new CellData(value.toString());
} }

6
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.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.ExcelColumnProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
/** /**
* Byte and boolean converter * Byte and boolean converter
@ -25,7 +25,7 @@ public class ByteBooleanConverter implements Converter<Byte> {
} }
@Override @Override
public Byte convertToJavaData(CellData cellData, ExcelColumnProperty columnProperty) { public Byte convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) {
if (cellData.getBooleanValue()) { if (cellData.getBooleanValue()) {
return ONE; return ONE;
} }
@ -33,7 +33,7 @@ public class ByteBooleanConverter implements Converter<Byte> {
} }
@Override @Override
public CellData convertToExcelData(Byte value, ExcelColumnProperty columnProperty) { public CellData convertToExcelData(Byte value, ExcelContentProperty contentProperty) {
if (ONE.equals(value)) { if (ONE.equals(value)) {
return new CellData(Boolean.TRUE); return new CellData(Boolean.TRUE);
} }

6
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.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.ExcelColumnProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
/** /**
* Byte and number converter * Byte and number converter
@ -23,12 +23,12 @@ public class ByteNumberConverter implements Converter<Byte> {
} }
@Override @Override
public Byte convertToJavaData(CellData cellData, ExcelColumnProperty columnProperty) { public Byte convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) {
return cellData.getDoubleValue().byteValue(); return cellData.getDoubleValue().byteValue();
} }
@Override @Override
public CellData convertToExcelData(Byte value, ExcelColumnProperty columnProperty) { public CellData convertToExcelData(Byte value, ExcelContentProperty contentProperty) {
return new CellData((double)value); return new CellData((double)value);
} }

6
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.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.ExcelColumnProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
/** /**
* Byte and string converter * Byte and string converter
@ -23,12 +23,12 @@ public class ByteStringConverter implements Converter<Byte> {
} }
@Override @Override
public Byte convertToJavaData(CellData cellData, ExcelColumnProperty columnProperty) { public Byte convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) {
return Byte.valueOf(cellData.getStringValue()); return Byte.valueOf(cellData.getStringValue());
} }
@Override @Override
public CellData convertToExcelData(Byte value, ExcelColumnProperty columnProperty) { public CellData convertToExcelData(Byte value, ExcelContentProperty contentProperty) {
return new CellData(value.toString()); return new CellData(value.toString());
} }

14
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.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.ExcelColumnProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
/** /**
* Date and number converter * Date and number converter
@ -27,13 +27,17 @@ public class DateNumberConverter implements Converter<Date> {
} }
@Override @Override
public Date convertToJavaData(CellData cellData, ExcelColumnProperty columnProperty) { public Date convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) {
return HSSFDateUtil.getJavaDate(cellData.getDoubleValue(), columnProperty.getUse1904windowing(), if (contentProperty.getDateTimeFormatProperty() == null) {
columnProperty.getTimeZone()); return HSSFDateUtil.getJavaDate(cellData.getDoubleValue(), false, null);
} else {
return HSSFDateUtil.getJavaDate(cellData.getDoubleValue(),
contentProperty.getDateTimeFormatProperty().getUse1904windowing(), null);
}
} }
@Override @Override
public CellData convertToExcelData(Date value, ExcelColumnProperty columnProperty) { public CellData convertToExcelData(Date value, ExcelContentProperty contentProperty) {
return new CellData((double)(value.getTime())); return new CellData((double)(value.getTime()));
} }
} }

19
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.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.ExcelColumnProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.util.DateUtils; import com.alibaba.excel.util.DateUtils;
/** /**
@ -26,12 +26,21 @@ public class DateStringConverter implements Converter<Date> {
} }
@Override @Override
public Date convertToJavaData(CellData cellData, ExcelColumnProperty columnProperty) throws ParseException { public Date convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) throws ParseException {
return DateUtils.parseDate(cellData.getStringValue(), columnProperty.getFormat()); if (contentProperty.getDateTimeFormatProperty() == null) {
return DateUtils.parseDate(cellData.getStringValue(), null);
} else {
return DateUtils.parseDate(cellData.getStringValue(),
contentProperty.getDateTimeFormatProperty().getFormat());
}
} }
@Override @Override
public CellData convertToExcelData(Date value, ExcelColumnProperty columnProperty) { public CellData convertToExcelData(Date value, ExcelContentProperty contentProperty) {
return new CellData(DateUtils.format(value, columnProperty.getFormat())); if (contentProperty.getDateTimeFormatProperty() == null) {
return new CellData(DateUtils.format(value, null));
} else {
return new CellData(DateUtils.format(value, contentProperty.getDateTimeFormatProperty().getFormat()));
}
} }
} }

6
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.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.ExcelColumnProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
/** /**
* Byte and boolean converter * Byte and boolean converter
@ -25,7 +25,7 @@ public class ByteBooleanConverter implements Converter<Byte> {
} }
@Override @Override
public Byte convertToJavaData(CellData cellData, ExcelColumnProperty columnProperty) { public Byte convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) {
if (cellData.getBooleanValue()) { if (cellData.getBooleanValue()) {
return ONE; return ONE;
} }
@ -33,7 +33,7 @@ public class ByteBooleanConverter implements Converter<Byte> {
} }
@Override @Override
public CellData convertToExcelData(Byte value, ExcelColumnProperty columnProperty) { public CellData convertToExcelData(Byte value, ExcelContentProperty contentProperty) {
if (ONE.equals(value)) { if (ONE.equals(value)) {
return new CellData(Boolean.TRUE); return new CellData(Boolean.TRUE);
} }

35
src/main/java/com/alibaba/excel/converters/doubleconverter/ByteNumberConverter.java

@ -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<Byte> {
@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);
}
}

35
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<Double> {
@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);
}
}

6
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.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.ExcelColumnProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
/** /**
* Double and string converter * Double and string converter
@ -23,12 +23,12 @@ public class DoubleStringConverter implements Converter<Double> {
} }
@Override @Override
public Double convertToJavaData(CellData cellData, ExcelColumnProperty columnProperty) { public Double convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) {
return Double.valueOf(cellData.getStringValue()); return Double.valueOf(cellData.getStringValue());
} }
@Override @Override
public CellData convertToExcelData(Double value, ExcelColumnProperty columnProperty) { public CellData convertToExcelData(Double value, ExcelContentProperty contentProperty) {
return new CellData(value.toString()); return new CellData(value.toString());
} }
} }

6
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.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.ExcelColumnProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
/** /**
* String and string converter * String and string converter
@ -22,12 +22,12 @@ public class StringStringConverter implements Converter<String> {
} }
@Override @Override
public String convertToJavaData(CellData cellData, ExcelColumnProperty columnProperty) { public String convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) {
return cellData.getStringValue(); return cellData.getStringValue();
} }
@Override @Override
public CellData convertToExcelData(String value, ExcelColumnProperty columnProperty) { public CellData convertToExcelData(String value, ExcelContentProperty contentProperty) {
return new CellData(value); return new CellData(value);
} }

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

@ -16,10 +16,6 @@ public enum CellDataTypeEnum {
* string * string
*/ */
STRING, STRING,
/**
* inlineString
*/
INLINE_STRING,
/** /**
* number * number
*/ */
@ -40,7 +36,7 @@ public enum CellDataTypeEnum {
private static final Map<String, CellDataTypeEnum> TYPE_ROUTING_MAP = new HashMap<String, CellDataTypeEnum>(8); private static final Map<String, CellDataTypeEnum> TYPE_ROUTING_MAP = new HashMap<String, CellDataTypeEnum>(8);
static { static {
TYPE_ROUTING_MAP.put("s", STRING); 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("e", ERROR);
TYPE_ROUTING_MAP.put("b", BOOLEAN); TYPE_ROUTING_MAP.put("b", BOOLEAN);
} }

26
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.ExcelDataConvertException;
import com.alibaba.excel.exception.ExcelGenerateException; import com.alibaba.excel.exception.ExcelGenerateException;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.ExcelColumnProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.metadata.ExcelHeadProperty; import com.alibaba.excel.metadata.property.ExcelHeadProperty;
import net.sf.cglib.beans.BeanMap; import net.sf.cglib.beans.BeanMap;
@ -21,10 +21,11 @@ import net.sf.cglib.beans.BeanMap;
*/ */
public class ModelBuildEventListener extends AnalysisEventListener<Object> { public class ModelBuildEventListener extends AnalysisEventListener<Object> {
private final Map<ConverterKey, Converter> converters; private final Map<ConverterKey, Converter> converters;
public ModelBuildEventListener(Map<ConverterKey, Converter> converters) { public ModelBuildEventListener(Map<ConverterKey, Converter> converters) {
this.converters = converters; this.converters = converters;
} }
@Override @Override
public void invoke(Object object, AnalysisContext context) { public void invoke(Object object, AnalysisContext context) {
if (context.getExcelHeadProperty() != null && context.getExcelHeadProperty().getHeadClazz() != null) { if (context.getExcelHeadProperty() != null && context.getExcelHeadProperty().getHeadClazz() != null) {
@ -42,20 +43,17 @@ public class ModelBuildEventListener extends AnalysisEventListener<Object> {
private Object buildUserModel(AnalysisContext context, List<CellData> cellDataList) throws Exception { private Object buildUserModel(AnalysisContext context, List<CellData> cellDataList) throws Exception {
ExcelHeadProperty excelHeadProperty = context.getExcelHeadProperty(); ExcelHeadProperty excelHeadProperty = context.getExcelHeadProperty();
Object resultModel = excelHeadProperty.getHeadClazz().newInstance(); Object resultModel = excelHeadProperty.getHeadClazz().newInstance();
if (excelHeadProperty == null) { Map<String,Object> map = new HashMap<String,Object>();
return resultModel;
}
Map map = new HashMap();
for (int i = 0; i < cellDataList.size(); i++) { for (int i = 0; i < cellDataList.size(); i++) {
ExcelColumnProperty columnProperty = excelHeadProperty.getExcelColumnProperty(i); ExcelContentProperty contentProperty = excelHeadProperty.getContentPropertyMap().get(i);
if (columnProperty != null) { if (contentProperty != null) {
CellData cellData = cellDataList.get(i); CellData cellData = cellDataList.get(i);
if (cellData.getType() == CellDataTypeEnum.EMPTY) { if (cellData.getType() == CellDataTypeEnum.EMPTY) {
continue; continue;
} }
Object value = convertValue(cellDataList.get(i), columnProperty.getField().getClass(), columnProperty); Object value = convertValue(cellDataList.get(i), contentProperty.getField().getClass(), contentProperty);
if (value != null) { if (value != null) {
map.put(columnProperty.getField().getName(), value); map.put(contentProperty.getField().getName(), value);
} }
} }
} }
@ -63,14 +61,14 @@ public class ModelBuildEventListener extends AnalysisEventListener<Object> {
return resultModel; 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())); Converter converter = converters.get(ConverterKey.buildConverterKey(clazz, cellData.getType()));
if (converter == null) { if (converter == null) {
throw new ExcelDataConvertException( throw new ExcelDataConvertException(
"Converter not found, converte " + cellData.getType() + " to " + clazz.getName()); "Converter not found, convert " + cellData.getType() + " to " + clazz.getName());
} }
try { try {
return converter.convertToJavaData(cellData, columnProperty); return converter.convertToJavaData(cellData, contentProperty);
} catch (Exception e) { } catch (Exception e) {
throw new ExcelDataConvertException("Convert data " + cellData + " to " + clazz + " error ", e); throw new ExcelDataConvertException("Convert data " + cellData + " to " + clazz + " error ", e);
} }

13
src/main/java/com/alibaba/excel/metadata/CellStyle.java

@ -17,6 +17,19 @@ public class CellStyle {
*/ */
private Font font; 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() { public IndexedColors getIndexedColors() {
return indexedColors; return indexedColors;
} }

105
src/main/java/com/alibaba/excel/metadata/ExcelColumnProperty.java

@ -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<ExcelColumnProperty> {
/**
*/
private Field field;
/**
*/
private int index = 99999;
/**
*/
private List<String> head = new ArrayList<String>();
/**
*
*/
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<String> getHead() {
return head;
}
public void setHead(List<String> 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);
}
}

287
src/main/java/com/alibaba/excel/metadata/ExcelHeadProperty.java

@ -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<Head> headList;
/**
* Attributes described by the header
*/
private List<ExcelColumnProperty> columnPropertyList = new ArrayList<ExcelColumnProperty>();
/**
* Attributes described by the header
*/
private Map<Integer, ExcelColumnProperty> excelColumnPropertyMap1 = new HashMap<Integer, ExcelColumnProperty>();
/**
* 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<List<String>> head) {
this.headClazz = headClazz;
headList = new ArrayList<Head>();
headKind = HeadKindEnum.NONE;
headRowNumber = 0;
if (head != null && !head.isEmpty()) {
int index = 0;
for (List<String> 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<String> headOneRow) {
if (excelHeadProperty == null) {
return new ExcelHeadProperty(clazz, new ArrayList<List<String>>());
}
if (headOneRow != null) {
excelHeadProperty.appendOneRow(headOneRow);
}
return excelHeadProperty;
}
private void initHeadRowNumber() {
headRowNumber = 0;
for (Head head : headList) {
List<String> list = head.getHeadNameList();
if (list != null && list.size() > headRowNumber) {
headRowNumber = list.size();
}
}
}
/**
*/
private void initColumnProperties() {
if (this.headClazz != null) {
List<Field> fieldList = new ArrayList<Field>();
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<String> 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<ExcelColumnProperty> getColumnPropertyList() {
return columnPropertyList;
}
public void setColumnPropertyList(List<ExcelColumnProperty> columnPropertyList) {
this.columnPropertyList = columnPropertyList;
}
public List<Head> getHeadList() {
return headList;
}
public void setHeadList(List<Head> 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<CellRange> getCellRangeModels() {
List<CellRange> cellRanges = new ArrayList<CellRange>();
for (int i = 0; i < headList.size(); i++) {
List<String> 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<String> getHeadByRowNum(int rowNum) {
List<String> l = new ArrayList<String>(headList.size());
for (Head head : headList) {
List<String> 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<String> 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;
}
}

43
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.ArrayList;
import java.util.List; import java.util.List;
import com.alibaba.excel.metadata.property.CellStyleProperty;
import com.alibaba.excel.metadata.property.ColumnWidthProperty;
/** /**
* excel head * excel head
* *
@ -22,6 +25,15 @@ public class Head {
*/ */
private List<String> headNameList; private List<String> headNameList;
/**
* Cell style property
*/
private CellStyleProperty cellStyleProperty;
/**
* column with
*/
private ColumnWidthProperty columnWidthProperty;
public Head(Integer columnIndex, String fieldName, String headName) { public Head(Integer columnIndex, String fieldName, String headName) {
this.columnIndex = columnIndex; this.columnIndex = columnIndex;
this.fieldName = fieldName; this.fieldName = fieldName;
@ -62,26 +74,19 @@ public class Head {
this.headNameList = headNameList; this.headNameList = headNameList;
} }
@Override public CellStyleProperty getCellStyleProperty() {
public String toString() { return cellStyleProperty;
return "Head{" + "columnIndex=" + columnIndex + ", fieldName='" + fieldName + '\'' + ", headNameList="
+ headNameList + '}';
} }
/** public void setCellStyleProperty(CellStyleProperty cellStyleProperty) {
* Get head name with index this.cellStyleProperty = cellStyleProperty;
* }
* @param index
* @return public ColumnWidthProperty getColumnWidthProperty() {
*/ return columnWidthProperty;
public String getHeadName(int index) { }
if (headNameList == null || headNameList.isEmpty()) {
return null; public void setColumnWidthProperty(ColumnWidthProperty columnWidthProperty) {
} this.columnWidthProperty = columnWidthProperty;
if (index >= headNameList.size()) {
return headNameList.get(headNameList.size() - 1);
} else {
return headNameList.get(index);
}
} }
} }

16
src/main/java/com/alibaba/excel/metadata/Workbook.java

@ -28,6 +28,14 @@ public class Workbook extends BasicParameter {
* Default true * Default true
*/ */
private Boolean autoCloseStream; 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 * Write handler
* *
@ -75,4 +83,12 @@ public class Workbook extends BasicParameter {
public void setAutoCloseStream(Boolean autoCloseStream) { public void setAutoCloseStream(Boolean autoCloseStream) {
this.autoCloseStream = autoCloseStream; this.autoCloseStream = autoCloseStream;
} }
public Boolean getConvertAllFiled() {
return convertAllFiled;
}
public void setConvertAllFiled(Boolean convertAllFiled) {
this.convertAllFiled = convertAllFiled;
}
} }

107
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.Set;
import java.util.TreeMap; 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.converters.Converter;
import com.alibaba.excel.enums.HeadKindEnum;
import com.alibaba.excel.event.NotRepeatExecutor; import com.alibaba.excel.event.NotRepeatExecutor;
import com.alibaba.excel.event.Order; 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.CellWriteHandler;
import com.alibaba.excel.write.handler.RowWriteHandler; import com.alibaba.excel.write.handler.RowWriteHandler;
import com.alibaba.excel.write.handler.SheetWriteHandler; import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.handler.WorkbookWriteHandler; import com.alibaba.excel.write.handler.WorkbookWriteHandler;
import com.alibaba.excel.write.handler.WriteHandler; import com.alibaba.excel.write.handler.WriteHandler;
import com.alibaba.excel.write.style.AbstractColumnCellStyleStrategy;
import com.alibaba.excel.write.style.column.AbstractColumnWidthStyleStrategy;
import com.alibaba.excel.write.style.row.SimpleRowHeightStyleStrategy;
/** /**
* sheet holder * sheet holder
@ -191,6 +203,99 @@ public abstract class AbstractConfigurationSelector implements ConfigurationSele
return result; return result;
} }
protected void initAnnotationConfig(List<WriteHandler> handlerList) {
if (!HeadKindEnum.CLASS.equals(getExcelHeadProperty().getHeadKind())) {
return;
}
Map<Integer, Head> headMap = getExcelHeadProperty().getHeadMap();
Map<Integer, ExcelContentProperty> contentPropertyMap = getExcelHeadProperty().getContentPropertyMap();
boolean hasCellStyle = false;
boolean hasColumnWidth = false;
for (Map.Entry<Integer, Head> 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<WriteHandler> handlerList, Map<Integer, ExcelContentProperty> 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<WriteHandler> 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<WriteHandler> handlerList,
final Map<Integer, ExcelContentProperty> 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 @Override
public Map<Class<? extends WriteHandler>, List<WriteHandler>> writeHandlerMap() { public Map<Class<? extends WriteHandler>, List<WriteHandler>> writeHandlerMap() {
return getWriteHandlerMap(); return getWriteHandlerMap();

2
src/main/java/com/alibaba/excel/metadata/holder/ConfigurationSelector.java

@ -4,7 +4,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import com.alibaba.excel.converters.Converter; 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; import com.alibaba.excel.write.handler.WriteHandler;
/** /**

10
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.CellStyle;
import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.TableStyle; 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.handler.WriteHandler;
import com.alibaba.excel.write.style.RowCellStyleStrategy; import com.alibaba.excel.write.style.RowCellStyleStrategy;
import com.alibaba.excel.write.style.column.AbstractHeadColumnWidthStyleStrategy; import com.alibaba.excel.write.style.column.AbstractHeadColumnWidthStyleStrategy;
@ -21,6 +22,7 @@ import com.alibaba.excel.write.style.column.AbstractHeadColumnWidthStyleStrategy
* @author zhuangjiaju * @author zhuangjiaju
*/ */
public class SheetHolder extends AbstractConfigurationSelector { public class SheetHolder extends AbstractConfigurationSelector {
/*** /***
* poi sheet * poi sheet
*/ */
@ -59,6 +61,9 @@ public class SheetHolder extends AbstractConfigurationSelector {
setHead(sheet.getHead()); setHead(sheet.getHead());
setClazz(sheet.getClazz()); setClazz(sheet.getClazz());
} }
// Initialization property
setExcelHeadProperty(new ExcelHeadProperty(getClazz(), getHead(), workbookHolder.getConvertAllFiled()));
setNewInitialization(Boolean.TRUE); setNewInitialization(Boolean.TRUE);
if (sheet.getNeedHead() == null) { if (sheet.getNeedHead() == null) {
setNeedHead(workbookHolder.needHead()); setNeedHead(workbookHolder.needHead());
@ -76,6 +81,9 @@ public class SheetHolder extends AbstractConfigurationSelector {
if (sheet.getCustomWriteHandlerList() != null && !sheet.getCustomWriteHandlerList().isEmpty()) { if (sheet.getCustomWriteHandlerList() != null && !sheet.getCustomWriteHandlerList().isEmpty()) {
handlerList.addAll(sheet.getCustomWriteHandlerList()); handlerList.addAll(sheet.getCustomWriteHandlerList());
} }
// Initialization Annotation
initAnnotationConfig(handlerList);
setWriteHandlerMap(sortAndClearUpHandler(handlerList, workbookHolder.getWriteHandlerMap())); setWriteHandlerMap(sortAndClearUpHandler(handlerList, workbookHolder.getWriteHandlerMap()));
Map<Class, Converter> converterMap = new HashMap<Class, Converter>(workbookHolder.converterMap()); Map<Class, Converter> converterMap = new HashMap<Class, Converter>(workbookHolder.converterMap());
if (sheet.getCustomConverterMap() != null && !sheet.getCustomConverterMap().isEmpty()) { if (sheet.getCustomConverterMap() != null && !sheet.getCustomConverterMap().isEmpty()) {
@ -97,7 +105,7 @@ public class SheetHolder extends AbstractConfigurationSelector {
} }
sheet.getCustomWriteHandlerList().add(new AbstractHeadColumnWidthStyleStrategy() { sheet.getCustomWriteHandlerList().add(new AbstractHeadColumnWidthStyleStrategy() {
@Override @Override
protected int columnWidth(Head head) { protected Integer columnWidth(Head head) {
if (columnWidthMap.containsKey(head.getColumnIndex())) { if (columnWidthMap.containsKey(head.getColumnIndex())) {
columnWidthMap.get(head.getColumnIndex()); columnWidthMap.get(head.getColumnIndex());
} }

9
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.CellStyle;
import com.alibaba.excel.metadata.Table; import com.alibaba.excel.metadata.Table;
import com.alibaba.excel.metadata.TableStyle; 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.handler.WriteHandler;
import com.alibaba.excel.write.style.RowCellStyleStrategy; import com.alibaba.excel.write.style.RowCellStyleStrategy;
@ -31,7 +32,7 @@ public class TableHolder extends AbstractConfigurationSelector {
*/ */
private com.alibaba.excel.metadata.Table tableParam; 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(); super();
this.tableParam = table; this.tableParam = table;
this.parentSheet = sheetHolder; this.parentSheet = sheetHolder;
@ -46,6 +47,9 @@ public class TableHolder extends AbstractConfigurationSelector {
setClazz(table.getClazz()); setClazz(table.getClazz());
} }
setNewInitialization(Boolean.TRUE); setNewInitialization(Boolean.TRUE);
// Initialization property
setExcelHeadProperty(new ExcelHeadProperty(getClazz(), getHead(), workbookHolder.getConvertAllFiled()));
if (table.getNeedHead() == null) { if (table.getNeedHead() == null) {
setNeedHead(sheetHolder.needHead()); setNeedHead(sheetHolder.needHead());
} else { } else {
@ -62,6 +66,9 @@ public class TableHolder extends AbstractConfigurationSelector {
if (table.getCustomWriteHandlerList() != null && !table.getCustomWriteHandlerList().isEmpty()) { if (table.getCustomWriteHandlerList() != null && !table.getCustomWriteHandlerList().isEmpty()) {
handlerList.addAll(table.getCustomWriteHandlerList()); handlerList.addAll(table.getCustomWriteHandlerList());
} }
// Initialization Annotation
initAnnotationConfig(handlerList);
setWriteHandlerMap(sortAndClearUpHandler(handlerList, sheetHolder.getWriteHandlerMap())); setWriteHandlerMap(sortAndClearUpHandler(handlerList, sheetHolder.getWriteHandlerMap()));
Map<Class, Converter> converterMap = new HashMap<Class, Converter>(sheetHolder.converterMap()); Map<Class, Converter> converterMap = new HashMap<Class, Converter>(sheetHolder.converterMap());
if (table.getCustomConverterMap() != null && !table.getCustomConverterMap().isEmpty()) { if (table.getCustomConverterMap() != null && !table.getCustomConverterMap().isEmpty()) {

33
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 org.apache.poi.ss.usermodel.Workbook;
import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.converters.DefaultConverterBuilder; import com.alibaba.excel.converters.DefaultConverterLoader;
import com.alibaba.excel.write.handler.DefaultWriteHandlerBuilder; import com.alibaba.excel.write.handler.DefaultWriteHandlerLoader;
import com.alibaba.excel.write.handler.WriteHandler; import com.alibaba.excel.write.handler.WriteHandler;
/** /**
@ -45,6 +45,15 @@ public class WorkbookHolder extends AbstractConfigurationSelector {
*/ */
private Boolean autoCloseStream; 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 * Write handler
* *
@ -62,6 +71,11 @@ public class WorkbookHolder extends AbstractConfigurationSelector {
setHead(workbook.getHead()); setHead(workbook.getHead());
setClazz(workbook.getClazz()); setClazz(workbook.getClazz());
setNewInitialization(Boolean.TRUE); setNewInitialization(Boolean.TRUE);
if (workbook.getConvertAllFiled() == null) {
this.convertAllFiled = Boolean.TRUE;
} else {
this.convertAllFiled = workbook.getConvertAllFiled();
}
if (workbook.getAutoCloseStream() == null) { if (workbook.getAutoCloseStream() == null) {
setAutoCloseStream(Boolean.TRUE); setAutoCloseStream(Boolean.TRUE);
} else { } else {
@ -81,9 +95,12 @@ public class WorkbookHolder extends AbstractConfigurationSelector {
if (workbook.getCustomWriteHandlerList() != null && !workbook.getCustomWriteHandlerList().isEmpty()) { if (workbook.getCustomWriteHandlerList() != null && !workbook.getCustomWriteHandlerList().isEmpty()) {
handlerList.addAll(workbook.getCustomWriteHandlerList()); handlerList.addAll(workbook.getCustomWriteHandlerList());
} }
handlerList.addAll(DefaultWriteHandlerBuilder.loadDefaultHandler()); // Initialization Annotation
initAnnotationConfig(handlerList);
handlerList.addAll(DefaultWriteHandlerLoader.loadDefaultHandler());
setWriteHandlerMap(sortAndClearUpHandler(handlerList, null)); setWriteHandlerMap(sortAndClearUpHandler(handlerList, null));
Map<Class, Converter> converterMap = DefaultConverterBuilder.loadDefaultWriteConverter(); Map<Class, Converter> converterMap = DefaultConverterLoader.loadDefaultWriteConverter();
if (workbook.getCustomConverterMap() != null && !workbook.getCustomConverterMap().isEmpty()) { if (workbook.getCustomConverterMap() != null && !workbook.getCustomConverterMap().isEmpty()) {
converterMap.putAll(workbook.getCustomConverterMap()); converterMap.putAll(workbook.getCustomConverterMap());
} }
@ -146,4 +163,12 @@ public class WorkbookHolder extends AbstractConfigurationSelector {
public void setAutoCloseStream(Boolean autoCloseStream) { public void setAutoCloseStream(Boolean autoCloseStream) {
this.autoCloseStream = autoCloseStream; this.autoCloseStream = autoCloseStream;
} }
public Boolean getConvertAllFiled() {
return convertAllFiled;
}
public void setConvertAllFiled(Boolean convertAllFiled) {
this.convertAllFiled = convertAllFiled;
}
} }

84
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;
}
}

31
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;
}
}

41
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;
}
}

62
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;
}
}

350
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<Integer, Head> headMap;
/**
* Configuration column information
*/
private Map<Integer, ExcelContentProperty> contentPropertyMap;
private RowHeightProperty headRowHeightProperty;
private RowHeightProperty contentRowHeightProperty;
public ExcelHeadProperty(Class headClazz, List<List<String>> head, Boolean convertAllFiled) {
this.headClazz = headClazz;
headMap = new TreeMap<Integer, Head>();
contentPropertyMap = new TreeMap<Integer, ExcelContentProperty>();
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<String> headOneRow) {
if (excelHeadProperty == null) {
return new ExcelHeadProperty(clazz, new ArrayList<List<String>>(), false);
}
if (headOneRow != null) {
excelHeadProperty.appendOneRow(headOneRow);
}
return excelHeadProperty;
}
private void initHeadRowNumber() {
headRowNumber = 0;
for (Head head : headMap.values()) {
List<String> list = head.getHeadNameList();
if (list != null && list.size() > headRowNumber) {
headRowNumber = list.size();
}
}
for (Head head : headMap.values()) {
List<String> 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<Field> fieldList = new ArrayList<Field>();
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<Field> defaultFieldList = new ArrayList<Field>();
Map<Integer, Field> customFiledMap = new TreeMap<Integer, Field>();
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<Integer, Field> 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<String> tmpHeadList = new ArrayList<String>();
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<String> 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<Integer, Head>)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<Integer, Head> getHeadMap() {
return headMap;
}
public void setHeadMap(Map<Integer, Head> headMap) {
this.headMap = headMap;
}
public Map<Integer, ExcelContentProperty> getContentPropertyMap() {
return contentPropertyMap;
}
public void setContentPropertyMap(Map<Integer, ExcelContentProperty> 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<CellRange> headCellRangeList() {
List<CellRange> cellRangeList = new ArrayList<CellRange>();
int i = 0;
for (Map.Entry<Integer, Head> entry : headMap.entrySet()) {
Head head = entry.getValue();
List<String> 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<String> 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;
}
}

43
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;
}
}

39
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;
}
}

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

@ -32,6 +32,8 @@ import java.util.Set;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import java.util.TimeZone; import java.util.TimeZone;
import org.apache.commons.codec.binary.CharSequenceUtils;
/** /**
* Miscellaneous {@link String} utility methods. * Miscellaneous {@link String} utility methods.
* *
@ -1218,4 +1220,96 @@ public abstract class StringUtils {
return arrayToDelimitedString(arr, ","); return arrayToDelimitedString(arr, ",");
} }
/**
* <p>Compares two CharSequences, returning {@code true} if they represent
* equal sequences of characters.</p>
*
* <p>{@code null}s are handled without exceptions. Two {@code null}
* references are considered to be equal. The comparison is case sensitive.</p>
*
* <pre>
* 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
* </pre>
*
* @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;
}
} }

95
src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java

@ -1,6 +1,7 @@
package com.alibaba.excel.write; package com.alibaba.excel.write;
import java.util.List; import java.util.List;
import java.util.Map;
import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row; 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.converters.Converter;
import com.alibaba.excel.exception.ExcelDataConvertException; import com.alibaba.excel.exception.ExcelDataConvertException;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.ExcelColumnProperty;
import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.Sheet; import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.metadata.Table; import com.alibaba.excel.metadata.Table;
import com.alibaba.excel.metadata.holder.ConfigurationSelector; 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.CollectionUtils;
import com.alibaba.excel.util.POITempFile; import com.alibaba.excel.util.POITempFile;
import com.alibaba.excel.util.WorkBookUtil; import com.alibaba.excel.util.WorkBookUtil;
@ -122,33 +123,83 @@ public class ExcelBuilderImpl implements ExcelBuilder {
if (CollectionUtils.isEmpty(oneRowData)) { if (CollectionUtils.isEmpty(oneRowData)) {
return; return;
} }
List<Head> headList = context.currentConfigurationSelector().excelHeadProperty().getHeadList(); Map<Integer, Head> headMap = context.currentConfigurationSelector().excelHeadProperty().getHeadMap();
for (int i = 0; i < oneRowData.size(); i++) { int dataIndex = 0;
Head head = i <= headList.size() ? headList.get(i) : null; int cellIndex = 0;
beforeCellCreate(row, head, relativeRowIndex); for (Map.Entry<Integer, Head> entry : headMap.entrySet()) {
Cell cell = WorkBookUtil.createCell(row, i); if (dataIndex >= oneRowData.size()) {
Object value = oneRowData.get(i); return;
converterAndSet(context.currentConfigurationSelector(), value.getClass(), cell, value, null); }
afterCellCreate(head, cell, relativeRowIndex); 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<Object> 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) { private void addJavaObjectToExcel(Object oneRowData, Row row, int relativeRowIndex) {
ConfigurationSelector currentConfigurationSelector = context.currentConfigurationSelector(); ConfigurationSelector currentConfigurationSelector = context.currentConfigurationSelector();
int i = 0;
BeanMap beanMap = BeanMap.create(oneRowData); BeanMap beanMap = BeanMap.create(oneRowData);
List<Head> headList = context.currentConfigurationSelector().excelHeadProperty().getHeadList(); Map<Integer, Head> headMap = context.currentConfigurationSelector().excelHeadProperty().getHeadMap();
for (ExcelColumnProperty excelHeadProperty : currentConfigurationSelector.excelHeadProperty() Map<Integer, ExcelContentProperty> contentPropertyMap =
.getColumnPropertyList()) { context.currentConfigurationSelector().excelHeadProperty().getContentPropertyMap();
Head head = i <= headList.size() ? headList.get(i) : null; int cellIndex = 0;
for (Map.Entry<Integer, ExcelContentProperty> 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); beforeCellCreate(row, head, relativeRowIndex);
Cell cell = WorkBookUtil.createCell(row, i); Cell cell = WorkBookUtil.createCell(row, cellIndex);
Object value = beanMap.get(excelHeadProperty.getField().getName()); Object value = beanMap.get(name);
converterAndSet(currentConfigurationSelector, excelHeadProperty.getField().getType(), cell, value, converterAndSet(currentConfigurationSelector, excelContentProperty.getField().getType(), cell, value,
excelHeadProperty); excelContentProperty);
afterCellCreate(head, cell, relativeRowIndex); 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<Object> 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) { 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, private void converterAndSet(ConfigurationSelector currentConfigurationSelector, Class clazz, Cell cell,
Object value, ExcelColumnProperty excelHeadProperty) { Object value, ExcelContentProperty excelContentProperty) {
if (value == null) { if (value == null) {
return; return;
} }
Converter converter = currentConfigurationSelector.converterMap().get(excelHeadProperty.getField().getType()); Converter converter = currentConfigurationSelector.converterMap().get(clazz);
if (converter == null) { if (converter == null) {
throw new ExcelDataConvertException( throw new ExcelDataConvertException(
"Can not find 'Converter' support class " + clazz.getSimpleName() + "."); "Can not find 'Converter' support class " + clazz.getSimpleName() + ".");
@ -196,7 +247,7 @@ public class ExcelBuilderImpl implements ExcelBuilder {
CellData cellData; CellData cellData;
try { try {
cellData = converter.convertToExcelData(value, excelHeadProperty); cellData = converter.convertToExcelData(value, excelContentProperty);
} catch (Exception e) { } catch (Exception e) {
throw new ExcelDataConvertException("Convert data:" + value + " error,at row:" + cell.getRow().getRowNum(), throw new ExcelDataConvertException("Convert data:" + value + " error,at row:" + cell.getRow().getRowNum(),
e); e);

22
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 * You can only choose one of the {@link ExcelWriterBuilder#head(List)} and {@link ExcelWriterBuilder#head(Class)}
* {@link ExcelWriterBuilder#head(Class)}
* *
* @param head * @param head
* @return * @return
@ -72,8 +71,7 @@ public class ExcelWriterBuilder {
} }
/** /**
* You can only choose one of the {@link ExcelWriterBuilder#head(List)} and * You can only choose one of the {@link ExcelWriterBuilder#head(List)} and {@link ExcelWriterBuilder#head(Class)}
* {@link ExcelWriterBuilder#head(Class)}
* *
* @param clazz * @param clazz
* @return * @return
@ -102,6 +100,22 @@ public class ExcelWriterBuilder {
return this; 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.
* <p>
* 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. * Custom type conversions override the default.
* *

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

@ -18,15 +18,25 @@ public interface CellWriteHandler extends WriteHandler {
/** /**
* called before create the cell * 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, void beforeCellCreate(SheetHolder sheetHolder, @Nullable TableHolder tableHolder, Row row, Head head,
int relativeRowIndex, boolean isHead); int relativeRowIndex, boolean isHead);
/** /**
* called after the cell is created * 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, void afterCellCreate(SheetHolder sheetHolder, @Nullable TableHolder tableHolder, Cell cell, Head head,
int relativeRowIndex, boolean isHead); int relativeRowIndex, boolean isHead);

4
src/main/java/com/alibaba/excel/write/handler/DefaultWriteHandlerBuilder.java → 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; import com.alibaba.excel.write.style.RowCellStyleStrategy;
/** /**
* Build default handler * Load default handler
* *
* @author zhuangjiaju * @author zhuangjiaju
*/ */
public class DefaultWriteHandlerBuilder { public class DefaultWriteHandlerLoader {
/** /**
* Load default handler * Load default handler

14
src/main/java/com/alibaba/excel/write/handler/RowWriteHandler.java

@ -16,15 +16,23 @@ public interface RowWriteHandler extends WriteHandler {
/** /**
* called before create the row * 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, void beforeRowCreate(SheetHolder sheetHolder, @Nullable TableHolder tableHolder, int rowIndex, int relativeRowIndex,
boolean isHead); boolean isHead);
/** /**
* called after the row is created * 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, void afterRowCreate(SheetHolder sheetHolder, @Nullable TableHolder tableHolder, Row row, int relativeRowIndex,
boolean isHead); boolean isHead);

8
src/main/java/com/alibaba/excel/write/handler/SheetWriteHandler.java

@ -13,14 +13,16 @@ public interface SheetWriteHandler extends WriteHandler {
/** /**
* called before create the sheet * called before create the sheet
* *
* @param writeContext * @param workbookHolder
* @param sheetHolder
*/ */
void beforeSheetCreate(WorkbookHolder workbookHolder, SheetHolder sheetHolder); void beforeSheetCreate(WorkbookHolder workbookHolder, SheetHolder sheetHolder);
/** /**
* called after the sheet is created * called after the sheet is created
* *
* @param writeContext * @param workbookHolder
* @param sheetHolder
*/ */
void afterSheetCreate(WorkbookHolder workbookHolder, SheetHolder sheetHolder); void afterSheetCreate(WorkbookHolder workbookHolder, SheetHolder sheetHolder);
} }

6
src/main/java/com/alibaba/excel/write/handler/WorkbookWriteHandler.java

@ -11,15 +11,13 @@ public interface WorkbookWriteHandler extends WriteHandler {
/** /**
* called before create the sheet * called before create the sheet
*
* @param writeContext
*/ */
void beforeWorkbookCreate(); void beforeWorkbookCreate();
/** /**
* called after the sheet is created * called after the sheet is created
* *
* @param writeContext * @param workbookHolder
*/ */
void afterWorkbookCreate(WorkbookHolder workbookHolder); void afterWorkbookCreate(WorkbookHolder workbookHolder);
} }

13
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.metadata.holder.TableHolder;
import com.alibaba.excel.write.handler.CellWriteHandler; import com.alibaba.excel.write.handler.CellWriteHandler;
/**
* Merge strategy
*
* @author zhuangjiaju
*/
public abstract class AbstractMergeStrategy implements CellWriteHandler { public abstract class AbstractMergeStrategy implements CellWriteHandler {
@Override @Override
@ -24,5 +29,13 @@ public abstract class AbstractMergeStrategy implements CellWriteHandler {
merge(sheetHolder.getSheet(), cell, head, relativeRowIndex); 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); protected abstract void merge(Sheet sheet, Cell cell, Head head, int relativeRowIndex);
} }

24
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.CellWriteHandler;
import com.alibaba.excel.write.handler.WorkbookWriteHandler; import com.alibaba.excel.write.handler.WorkbookWriteHandler;
/**
* Cell style strategy
*
* @author zhuangjiaju
*/
public abstract class AbstractCellStyleStrategy implements CellWriteHandler, WorkbookWriteHandler, NotRepeatExecutor { public abstract class AbstractCellStyleStrategy implements CellWriteHandler, WorkbookWriteHandler, NotRepeatExecutor {
@Override @Override
public String uniqueValue() { 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); 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); 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); protected abstract void setContentCellStyle(Cell cell, Head head, int relativeRowIndex);
} }

39
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.metadata.Head;
import com.alibaba.excel.util.StyleUtil; 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) { protected void setHeadCellStyle(Cell cell, Head head, int relativeRowIndex) {
int columnIndex = head.getColumnIndex(); int columnIndex = head.getColumnIndex();
if (headCellStyleCache.containsKey(columnIndex)) { 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 @Override
protected void setContentCellStyle(Cell cell, Head head, int relativeRowIndex) { protected void setContentCellStyle(Cell cell, Head head, int relativeRowIndex) {
int columnIndex = head.getColumnIndex(); int columnIndex = head.getColumnIndex();
if (contentCellStyleCache.containsKey(columnIndex)) { 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 * @param head
* @return * @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 * Returns the column width corresponding to each column head
@ -63,6 +82,6 @@ public abstract class AbstractColumnCellStyleStrategy extends AbstractCellStyleS
* @param head * @param head
* @return * @return
*/ */
protected abstract com.alibaba.excel.metadata.CellStyle contentCellStyle(Head head); protected abstract com.alibaba.excel.metadata.CellStyle contentCellStyle(@Nullable Head head);
} }

5
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.SheetHolder;
import com.alibaba.excel.metadata.holder.TableHolder; import com.alibaba.excel.metadata.holder.TableHolder;
import com.alibaba.excel.write.handler.CellWriteHandler; import com.alibaba.excel.write.handler.CellWriteHandler;
import com.sun.istack.internal.Nullable;
/** /**
* Column width style strategy * Column width style strategy
@ -29,7 +30,7 @@ public abstract class AbstractColumnWidthStyleStrategy implements CellWriteHandl
@Override @Override
public void afterCellCreate(SheetHolder sheetHolder, TableHolder tableHolder, Cell cell, Head head, public void afterCellCreate(SheetHolder sheetHolder, TableHolder tableHolder, Cell cell, Head head,
int relativeRowIndex, boolean isHead) { int relativeRowIndex, boolean isHead) {
if (!isHead) { if (!isHead && relativeRowIndex != 0) {
return; return;
} }
setColumnWidth(sheetHolder.getSheet(), cell, head); setColumnWidth(sheetHolder.getSheet(), cell, head);
@ -42,6 +43,6 @@ public abstract class AbstractColumnWidthStyleStrategy implements CellWriteHandl
* @param cell * @param cell
* @param head * @param head
*/ */
protected abstract void setColumnWidth(Sheet sheet, Cell cell, Head head); protected abstract void setColumnWidth(Sheet sheet, Cell cell, @Nullable Head head);
} }

11
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 org.apache.poi.ss.usermodel.Sheet;
import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.Head;
import com.sun.istack.internal.Nullable;
/** /**
* Returns the column width according to each column header * 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 { public abstract class AbstractHeadColumnWidthStyleStrategy extends AbstractColumnWidthStyleStrategy {
@Override @Override
protected void setColumnWidth(Sheet sheet, Cell cell, Head head) { 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. * Returns the column width corresponding to each column head.
* *
* <li>if return null,ignore
* *
* @param head * @param head
* @return the width in units of 1/256th of a character width . Using the Calibri font as an example, the maximum * @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 * 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 * characters wide, e.g. you need return 8*256
*/ */
protected abstract int columnWidth(Head head); protected abstract Integer columnWidth(@Nullable Head head);
} }

8
src/main/java/com/alibaba/excel/write/style/column/SimpleColumnWidthStyleStrategy.java

@ -11,7 +11,7 @@ import com.alibaba.excel.metadata.Head;
* @author zhuangjiaju * @author zhuangjiaju
*/ */
public class SimpleColumnWidthStyleStrategy extends AbstractColumnWidthStyleStrategy { 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 * 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 * @param columnWidth
* the width in units of 1/256th of a character width * the width in units of 1/256th of a character width
*/ */
public SimpleColumnWidthStyleStrategy(int columnWidth) { public SimpleColumnWidthStyleStrategy(Integer columnWidth) {
this.columnWidth = columnWidth; this.columnWidth = columnWidth;
} }
@Override @Override
protected void setColumnWidth(Sheet sheet, Cell cell, Head head) { protected void setColumnWidth(Sheet sheet, Cell cell, Head head) {
sheet.setColumnWidth(cell.getColumnIndex(), columnWidth); if (columnWidth != null) {
sheet.setColumnWidth(cell.getColumnIndex(), columnWidth);
}
} }
} }

29
src/main/java/com/alibaba/excel/write/style/row/AbstractRowHighStyleStrategy.java → 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.metadata.holder.TableHolder;
import com.alibaba.excel.write.handler.RowWriteHandler; 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 @Override
public String uniqueValue() { 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, public void afterRowCreate(SheetHolder sheetHolder, TableHolder tableHolder, Row row, int relativeRowIndex,
boolean isHead) { boolean isHead) {
if (isHead) { if (isHead) {
setHeadColumnHigh(row, relativeRowIndex); setHeadColumnHeight(row, relativeRowIndex);
} else { } else {
setContentColumnHigh(row, relativeRowIndex); setContentColumnHeight(row, relativeRowIndex);
} }
} }
protected abstract void setHeadColumnHigh(Row row, int relativeRowIndex); /**
* Sets the height of header
protected abstract void setContentColumnHigh(Row row, int relativeRowIndex); *
* @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);
} }

33
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);
}
}
}

29
src/main/java/com/alibaba/excel/write/style/row/SimpleRowHighStyleStrategy.java

@ -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);
}
}

40
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<OrderData> createData(int count) {
List<OrderData> list = new ArrayList<OrderData>();
for (int i = 0; i < count; i++) {
OrderData orderData = new OrderData();
orderData.setIndex1("排序1:" + i);
orderData.setIndex10("排序10:" + i);
list.add(orderData);
}
return list;
}
}
Loading…
Cancel
Save