You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

220 lines
6.5 KiB

package com.alibaba.excel.metadata;
import com.alibaba.excel.annotation.ExcelColumnNum;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.util.StringUtils;
import java.lang.reflect.Field;
import java.util.*;
/**
* Define the header attribute of excel
*
* @author jipengfei
* @date 2017/05/31
*/
public class ExcelHeadProperty {
/**
* Custom class
*/
private Class<? extends BaseRowModel> headClazz;
/**
* A two-dimensional array describing the header
*/
private List<List<String>> head = new ArrayList<List<String>>();
/**
* 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>();
public ExcelHeadProperty(Class<? extends BaseRowModel> headClazz, List<List<String>> head) {
this.headClazz = headClazz;
this.head = head;
initColumnProperties();
}
/**
*/
private void initColumnProperties() {
if (this.headClazz != null) {
Field[] fields = this.headClazz.getDeclaredFields();
List<List<String>> headList = new ArrayList<List<String>>();
for (Field f : fields) {
initOneColumnProperty(f);
}
//对列排序
Collections.sort(columnPropertyList);
if (head == null || head.size() == 0) {
for (ExcelColumnProperty excelColumnProperty : columnPropertyList) {
headList.add(excelColumnProperty.getHead());
}
this.head = headList;
}
}
}
/**
* @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);
}
}
/**
*
*/
public void appendOneRow(List<String> row) {
for (int i = 0; i < row.size(); i++) {
List<String> list;
if (head.size() <= i) {
list = new ArrayList<String>();
head.add(list);
} else {
list = head.get(0);
}
list.add(row.get(i));
}
}
/**
* @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<List<String>> getHead() {
return this.head;
}
public void setHead(List<List<String>> head) {
this.head = head;
}
public List<ExcelColumnProperty> getColumnPropertyList() {
return columnPropertyList;
}
public void setColumnPropertyList(List<ExcelColumnProperty> columnPropertyList) {
this.columnPropertyList = columnPropertyList;
}
/**
* 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 < head.size(); i++) {
List<String> columnValues = head.get(i);
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>(head.size());
for (List<String> list : head) {
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) {
int lastRow = -1;
if (StringUtils.isEmpty(value)) {
return -1;
}
for (int i = 0; i < values.size(); i++) {
String current = values.get(i);
if (value.equals(current)) {
if (i >= j) {
lastRow = i;
} else {
//if i<j && value.equals(current) Indicates that a merger has occurred
return -1;
}
} else {
// if i>j && !value.equals(current) Indicates that the continuous range is exceeded
if (i > j) {
break;
}
}
}
return lastRow;
}
public int getRowNum() {
int headRowNum = 0;
for (List<String> list : head) {
if (list != null && list.size() > 0) {
if (list.size() > headRowNum) {
headRowNum = list.size();
}
}
}
return headRowNum;
}
}