mirror of https://github.com/alibaba/easyexcel
zhuangjiaju
5 years ago
72 changed files with 1671 additions and 708 deletions
@ -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 ""; |
|
||||||
} |
|
@ -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 {} |
@ -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; |
||||||
|
} |
@ -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; |
||||||
|
} |
@ -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; |
||||||
|
} |
@ -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; |
||||||
|
} |
@ -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; |
||||||
|
} |
@ -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; |
||||||
|
} |
@ -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; |
||||||
|
} |
@ -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); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -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); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -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); |
|
||||||
} |
|
||||||
} |
|
@ -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; |
|
||||||
} |
|
||||||
} |
|
@ -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; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
} |
@ -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); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -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); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -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…
Reference in new issue