Browse Source

`ExcelProperty`新增`order` 用于排序

developing
Jiaju Zhuang 4 years ago
parent
commit
ee4e5f5299
  1. 2
      pom.xml
  2. 13
      src/main/java/com/alibaba/excel/annotation/ExcelProperty.java
  3. 39
      src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java
  4. 146
      src/main/java/com/alibaba/excel/util/ClassUtils.java
  5. 52
      src/main/java/com/alibaba/excel/write/executor/ExcelWriteAddExecutor.java
  6. 6
      src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java
  7. 20
      src/test/java/com/alibaba/easyexcel/test/core/excludeorinclude/ExcludeOrIncludeData.java
  8. 161
      src/test/java/com/alibaba/easyexcel/test/core/excludeorinclude/ExcludeOrIncludeDataTest.java
  9. 23
      src/test/java/com/alibaba/easyexcel/test/core/sort/SortData.java
  10. 41
      src/test/java/com/alibaba/easyexcel/test/core/sort/SortDataListener.java
  11. 111
      src/test/java/com/alibaba/easyexcel/test/core/sort/SortDataTest.java
  12. 36
      src/test/java/com/alibaba/easyexcel/test/temp/large/NoModelLargeDataListener.java
  13. 11
      src/test/java/com/alibaba/easyexcel/test/temp/large/TempLargeDataTest.java
  14. 4
      update.md

2
pom.xml

@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.alibaba</groupId> <groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId> <artifactId>easyexcel</artifactId>
<version>2.2.4</version> <version>2.2.5</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>easyexcel</name> <name>easyexcel</name>

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

@ -32,12 +32,23 @@ public @interface ExcelProperty {
/** /**
* Index of column * Index of column
* *
* Read or write it on the index of column,If it's equal to -1, it's sorted by Java class * Read or write it on the index of column,If it's equal to -1, it's sorted by Java class.
*
* priority: index > order > default sort
* *
* @return Index of column * @return Index of column
*/ */
int index() default -1; int index() default -1;
/**
* Defines the sort order for an column.
*
* priority: index > order > default sort
*
* @return Order of column
*/
int order() default Integer.MAX_VALUE;
/** /**
* Force the current field to use this converter. * Force the current field to use this converter.
* *

39
src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java

@ -21,6 +21,7 @@ import com.alibaba.excel.exception.ExcelCommonException;
import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.Holder; import com.alibaba.excel.metadata.Holder;
import com.alibaba.excel.util.ClassUtils; import com.alibaba.excel.util.ClassUtils;
import com.alibaba.excel.util.CollectionUtils;
import com.alibaba.excel.util.StringUtils; import com.alibaba.excel.util.StringUtils;
import com.alibaba.excel.write.metadata.holder.AbstractWriteHolder; import com.alibaba.excel.write.metadata.holder.AbstractWriteHolder;
@ -117,24 +118,19 @@ public class ExcelHeadProperty {
return; return;
} }
// Declared fields // Declared fields
List<Field> defaultFieldList = new ArrayList<Field>(); Map<Integer, Field> sortedAllFiledMap = new TreeMap<Integer, Field>();
Map<Integer, Field> customFiledMap = new TreeMap<Integer, Field>(); Map<Integer, Field> indexFiledMap = new TreeMap<Integer, Field>();
ClassUtils.declaredFields(headClazz, defaultFieldList, customFiledMap, ignoreMap, convertAllFiled);
int index = 0; boolean needIgnore = (holder instanceof AbstractWriteHolder) && (
for (Field field : defaultFieldList) { !CollectionUtils.isEmpty(((AbstractWriteHolder) holder).getExcludeColumnFiledNames()) || !CollectionUtils
while (customFiledMap.containsKey(index)) { .isEmpty(((AbstractWriteHolder) holder).getExcludeColumnIndexes()) || !CollectionUtils
Field customFiled = customFiledMap.get(index); .isEmpty(((AbstractWriteHolder) holder).getIncludeColumnFiledNames()) || !CollectionUtils
customFiledMap.remove(index); .isEmpty(((AbstractWriteHolder) holder).getIncludeColumnIndexes()));
if (!initOneColumnProperty(holder, index, customFiled, Boolean.TRUE)) { ClassUtils.declaredFields(headClazz, sortedAllFiledMap, indexFiledMap, ignoreMap, convertAllFiled, needIgnore,
index++; holder);
}
} for (Map.Entry<Integer, Field> entry : sortedAllFiledMap.entrySet()) {
initOneColumnProperty(holder, index, field, Boolean.FALSE); initOneColumnProperty(entry.getKey(), entry.getValue(), indexFiledMap.containsKey(entry.getKey()));
index++;
}
for (Map.Entry<Integer, Field> entry : customFiledMap.entrySet()) {
initOneColumnProperty(holder, entry.getKey(), entry.getValue(), Boolean.TRUE);
} }
headKind = HeadKindEnum.CLASS; headKind = HeadKindEnum.CLASS;
} }
@ -142,18 +138,12 @@ public class ExcelHeadProperty {
/** /**
* Initialization column property * Initialization column property
* *
* @param holder
* @param index * @param index
* @param field * @param field
* @param forceIndex * @param forceIndex
* @return Ignore current field * @return Ignore current field
*/ */
private boolean initOneColumnProperty(Holder holder, int index, Field field, Boolean forceIndex) { private void initOneColumnProperty(int index, Field field, Boolean forceIndex) {
if (holder instanceof AbstractWriteHolder) {
if (((AbstractWriteHolder) holder).ignore(field.getName(), index)) {
return true;
}
}
ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class); ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
List<String> tmpHeadList = new ArrayList<String>(); List<String> tmpHeadList = new ArrayList<String>();
boolean notForceName = excelProperty == null || excelProperty.value().length <= 0 boolean notForceName = excelProperty == null || excelProperty.value().length <= 0
@ -189,7 +179,6 @@ public class ExcelHeadProperty {
headMap.put(index, head); headMap.put(index, head);
contentPropertyMap.put(index, excelContentProperty); contentPropertyMap.put(index, excelContentProperty);
fieldNameContentPropertyMap.put(field.getName(), excelContentProperty); fieldNameContentPropertyMap.put(field.getName(), excelContentProperty);
return false;
} }
public Class getHeadClazz() { public Class getHeadClazz() {

146
src/main/java/com/alibaba/excel/util/ClassUtils.java

@ -14,8 +14,12 @@ import java.util.concurrent.ConcurrentHashMap;
import com.alibaba.excel.annotation.ExcelIgnore; import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.event.Handler;
import com.alibaba.excel.exception.ExcelCommonException; import com.alibaba.excel.exception.ExcelCommonException;
import com.alibaba.excel.metadata.BaseRowModel; import com.alibaba.excel.metadata.BaseRowModel;
import com.alibaba.excel.metadata.Holder;
import com.alibaba.excel.write.handler.WriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteHolder;
/** /**
* Class utils * Class utils
@ -23,24 +27,52 @@ import com.alibaba.excel.metadata.BaseRowModel;
* @author Jiaju Zhuang * @author Jiaju Zhuang
**/ **/
public class ClassUtils { public class ClassUtils {
private static final Map<Class, SoftReference<FieldCache>> FIELD_CACHE = private static final Map<Class, SoftReference<FieldCache>> FIELD_CACHE =
new ConcurrentHashMap<Class, SoftReference<FieldCache>>(); new ConcurrentHashMap<Class, SoftReference<FieldCache>>();
public static void declaredFields(Class clazz, List<Field> defaultFieldList, Map<Integer, Field> customFiledMap, public static void declaredFields(Class clazz, Map<Integer, Field> sortedAllFiledMap,
Map<String, Field> ignoreMap, Boolean convertAllFiled) { Map<Integer, Field> indexFiledMap, Map<String, Field> ignoreMap, Boolean convertAllFiled,
Boolean needIgnore, Holder holder) {
FieldCache fieldCache = getFieldCache(clazz, convertAllFiled); FieldCache fieldCache = getFieldCache(clazz, convertAllFiled);
if (fieldCache != null) { if (fieldCache == null) {
defaultFieldList.addAll(fieldCache.getDefaultFieldList()); return;
customFiledMap.putAll(fieldCache.getCustomFiledMap()); }
if (ignoreMap != null) {
ignoreMap.putAll(fieldCache.getIgnoreMap()); ignoreMap.putAll(fieldCache.getIgnoreMap());
} }
Map<Integer, Field> tempIndexFildMap = indexFiledMap;
if (tempIndexFildMap == null) {
tempIndexFildMap = new TreeMap<Integer, Field>();
} }
tempIndexFildMap.putAll(fieldCache.getIndexFiledMap());
public static void declaredFields(Class clazz, List<Field> fieldList, Boolean convertAllFiled) { if (!needIgnore) {
FieldCache fieldCache = getFieldCache(clazz, convertAllFiled); sortedAllFiledMap.putAll(fieldCache.getSortedAllFiledMap());
if (fieldCache != null) { return;
fieldList.addAll(fieldCache.getAllFieldList()); }
int index = 0;
for (Map.Entry<Integer, Field> entry : fieldCache.getSortedAllFiledMap().entrySet()) {
Field field = entry.getValue();
if (((WriteHolder) holder).ignore(entry.getValue().getName(), entry.getKey())) {
if (ignoreMap != null) {
ignoreMap.put(field.getName(), field);
}
while (tempIndexFildMap.containsKey(index)) {
tempIndexFildMap.remove(index);
index++;
} }
} else {
sortedAllFiledMap.put(index, field);
index++;
}
}
}
public static void declaredFields(Class clazz, Map<Integer, Field> sortedAllFiledMap, Boolean convertAllFiled,
Boolean needIgnore, WriteHolder writeHolder) {
declaredFields(clazz, sortedAllFiledMap, null, null, convertAllFiled, needIgnore, writeHolder);
} }
private static FieldCache getFieldCache(Class clazz, Boolean convertAllFiled) { private static FieldCache getFieldCache(Class clazz, Boolean convertAllFiled) {
@ -72,80 +104,108 @@ public class ClassUtils {
tempClass = tempClass.getSuperclass(); tempClass = tempClass.getSuperclass();
} }
// Screening of field // Screening of field
List<Field> defaultFieldList = new ArrayList<Field>(); Map<Integer, List<Field>> orderFiledMap = new TreeMap<Integer, List<Field>>();
Map<Integer, Field> customFiledMap = new TreeMap<Integer, Field>(); Map<Integer, Field> indexFiledMap = new TreeMap<Integer, Field>();
List<Field> allFieldList = new ArrayList<Field>();
Map<String, Field> ignoreMap = new HashMap<String, Field>(16); Map<String, Field> ignoreMap = new HashMap<String, Field>(16);
ExcelIgnoreUnannotated excelIgnoreUnannotated = ExcelIgnoreUnannotated excelIgnoreUnannotated =
(ExcelIgnoreUnannotated) clazz.getAnnotation(ExcelIgnoreUnannotated.class); (ExcelIgnoreUnannotated) clazz.getAnnotation(ExcelIgnoreUnannotated.class);
for (Field field : tempFieldList) { for (Field field : tempFieldList) {
declaredOneField(field, orderFiledMap, indexFiledMap, ignoreMap, excelIgnoreUnannotated, convertAllFiled);
}
FIELD_CACHE.put(clazz, new SoftReference<FieldCache>(
new FieldCache(buildSortedAllFiledMap(orderFiledMap, indexFiledMap), indexFiledMap, ignoreMap)));
}
private static Map<Integer, Field> buildSortedAllFiledMap(Map<Integer, List<Field>> orderFiledMap,
Map<Integer, Field> indexFiledMap) {
Map<Integer, Field> sortedAllFiledMap = new HashMap<Integer, Field>(
(orderFiledMap.size() + indexFiledMap.size()) * 4 / 3 + 1);
Map<Integer, Field> tempIndexFiledMap = new HashMap<Integer, Field>(indexFiledMap);
int index = 0;
for (List<Field> fieldList : orderFiledMap.values()) {
for (Field field : fieldList) {
while (tempIndexFiledMap.containsKey(index)) {
sortedAllFiledMap.put(index, tempIndexFiledMap.get(index));
tempIndexFiledMap.remove(index);
index++;
}
sortedAllFiledMap.put(index, field);
index++;
}
}
sortedAllFiledMap.putAll(tempIndexFiledMap);
return sortedAllFiledMap;
}
private static void declaredOneField(Field field, Map<Integer, List<Field>> orderFiledMap,
Map<Integer, Field> indexFiledMap, Map<String, Field> ignoreMap, ExcelIgnoreUnannotated excelIgnoreUnannotated,
Boolean convertAllFiled) {
ExcelIgnore excelIgnore = field.getAnnotation(ExcelIgnore.class); ExcelIgnore excelIgnore = field.getAnnotation(ExcelIgnore.class);
if (excelIgnore != null) { if (excelIgnore != null) {
ignoreMap.put(field.getName(), field); ignoreMap.put(field.getName(), field);
continue; return;
} }
ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class); ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
boolean noExcelProperty = excelProperty == null boolean noExcelProperty = excelProperty == null
&& ((convertAllFiled != null && !convertAllFiled) || excelIgnoreUnannotated != null); && ((convertAllFiled != null && !convertAllFiled) || excelIgnoreUnannotated != null);
if (noExcelProperty) { if (noExcelProperty) {
ignoreMap.put(field.getName(), field); ignoreMap.put(field.getName(), field);
continue; return;
} }
boolean isStaticFinalOrTransient = boolean isStaticFinalOrTransient =
(Modifier.isStatic(field.getModifiers()) && Modifier.isFinal(field.getModifiers())) (Modifier.isStatic(field.getModifiers()) && Modifier.isFinal(field.getModifiers()))
|| Modifier.isTransient(field.getModifiers()); || Modifier.isTransient(field.getModifiers());
if (excelProperty == null && isStaticFinalOrTransient) { if (excelProperty == null && isStaticFinalOrTransient) {
ignoreMap.put(field.getName(), field); ignoreMap.put(field.getName(), field);
continue; return;
} }
if (excelProperty == null || excelProperty.index() < 0) { if (excelProperty != null && excelProperty.index() >= 0) {
defaultFieldList.add(field); if (indexFiledMap.containsKey(excelProperty.index())) {
allFieldList.add(field); throw new ExcelCommonException("The index of '" + indexFiledMap.get(excelProperty.index()).getName()
continue;
}
if (customFiledMap.containsKey(excelProperty.index())) {
throw new ExcelCommonException("The index of '" + customFiledMap.get(excelProperty.index()).getName()
+ "' and '" + field.getName() + "' must be inconsistent"); + "' and '" + field.getName() + "' must be inconsistent");
} }
customFiledMap.put(excelProperty.index(), field); indexFiledMap.put(excelProperty.index(), field);
return;
} }
List<Field> allWriteFieldList = new ArrayList<Field>(customFiledMap.values()); int order = Integer.MAX_VALUE;
allWriteFieldList.addAll(allFieldList); if (excelProperty != null) {
FIELD_CACHE.put(clazz, order = excelProperty.order();
new SoftReference<FieldCache>(new FieldCache(defaultFieldList, customFiledMap, allWriteFieldList, ignoreMap))); }
List<Field> orderFiledList = orderFiledMap.get(order);
if (orderFiledList == null) {
orderFiledList = new ArrayList<Field>();
orderFiledMap.put(order, orderFiledList);
}
orderFiledList.add(field);
} }
private static class FieldCache { private static class FieldCache {
private List<Field> defaultFieldList;
private Map<Integer, Field> customFiledMap; private Map<Integer, Field> sortedAllFiledMap;
private List<Field> allFieldList; private Map<Integer, Field> indexFiledMap;
private Map<String, Field> ignoreMap; private Map<String, Field> ignoreMap;
public FieldCache(List<Field> defaultFieldList, Map<Integer, Field> customFiledMap, List<Field> allFieldList, public FieldCache(Map<Integer, Field> sortedAllFiledMap, Map<Integer, Field> indexFiledMap,
Map<String, Field> ignoreMap) { Map<String, Field> ignoreMap) {
this.defaultFieldList = defaultFieldList; this.sortedAllFiledMap = sortedAllFiledMap;
this.customFiledMap = customFiledMap; this.indexFiledMap = indexFiledMap;
this.allFieldList = allFieldList;
this.ignoreMap = ignoreMap; this.ignoreMap = ignoreMap;
} }
public List<Field> getDefaultFieldList() { public Map<Integer, Field> getSortedAllFiledMap() {
return defaultFieldList; return sortedAllFiledMap;
} }
public Map<Integer, Field> getCustomFiledMap() { public Map<Integer, Field> getIndexFiledMap() {
return customFiledMap; return indexFiledMap;
}
public List<Field> getAllFieldList() {
return allFieldList;
} }
public Map<String, Field> getIgnoreMap() { public Map<String, Field> getIgnoreMap() {
return ignoreMap; return ignoreMap;
} }
} }
} }

52
src/main/java/com/alibaba/excel/write/executor/ExcelWriteAddExecutor.java

@ -6,6 +6,7 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.TreeMap;
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;
@ -19,8 +20,11 @@ import com.alibaba.excel.util.ClassUtils;
import com.alibaba.excel.util.CollectionUtils; import com.alibaba.excel.util.CollectionUtils;
import com.alibaba.excel.util.WorkBookUtil; import com.alibaba.excel.util.WorkBookUtil;
import com.alibaba.excel.util.WriteHandlerUtils; import com.alibaba.excel.util.WriteHandlerUtils;
import com.alibaba.excel.write.metadata.WriteWorkbook;
import com.alibaba.excel.write.metadata.holder.AbstractWriteHolder;
import com.alibaba.excel.write.metadata.holder.WriteHolder; import com.alibaba.excel.write.metadata.holder.WriteHolder;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import net.sf.cglib.beans.BeanMap; import net.sf.cglib.beans.BeanMap;
@ -44,17 +48,18 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor {
if (writeSheetHolder.isNew() && !writeSheetHolder.getExcelWriteHeadProperty().hasHead()) { if (writeSheetHolder.isNew() && !writeSheetHolder.getExcelWriteHeadProperty().hasHead()) {
newRowIndex += writeContext.currentWriteHolder().relativeHeadRowIndex(); newRowIndex += writeContext.currentWriteHolder().relativeHeadRowIndex();
} }
// BeanMap is out of order,so use fieldList // BeanMap is out of order,so use sortedAllFiledMap
List<Field> fieldList = new ArrayList<Field>(); Map<Integer, Field> sortedAllFiledMap = new TreeMap<Integer, Field>();
int relativeRowIndex = 0; int relativeRowIndex = 0;
for (Object oneRowData : data) { for (Object oneRowData : data) {
int n = relativeRowIndex + newRowIndex; int n = relativeRowIndex + newRowIndex;
addOneRowOfDataToExcel(oneRowData, n, relativeRowIndex, fieldList); addOneRowOfDataToExcel(oneRowData, n, relativeRowIndex, sortedAllFiledMap);
relativeRowIndex++; relativeRowIndex++;
} }
} }
private void addOneRowOfDataToExcel(Object oneRowData, int n, int relativeRowIndex, List<Field> fieldList) { private void addOneRowOfDataToExcel(Object oneRowData, int n, int relativeRowIndex,
Map<Integer, Field> sortedAllFiledMap) {
if (oneRowData == null) { if (oneRowData == null) {
return; return;
} }
@ -64,7 +69,7 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor {
if (oneRowData instanceof List) { if (oneRowData instanceof List) {
addBasicTypeToExcel((List) oneRowData, row, relativeRowIndex); addBasicTypeToExcel((List) oneRowData, row, relativeRowIndex);
} else { } else {
addJavaObjectToExcel(oneRowData, row, relativeRowIndex, fieldList); addJavaObjectToExcel(oneRowData, row, relativeRowIndex, sortedAllFiledMap);
} }
WriteHandlerUtils.afterRowDispose(writeContext, row, relativeRowIndex, Boolean.FALSE); WriteHandlerUtils.afterRowDispose(writeContext, row, relativeRowIndex, Boolean.FALSE);
} }
@ -99,9 +104,6 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor {
private void doAddBasicTypeToExcel(List<Object> oneRowData, Head head, Row row, int relativeRowIndex, int dataIndex, private void doAddBasicTypeToExcel(List<Object> oneRowData, Head head, Row row, int relativeRowIndex, int dataIndex,
int cellIndex) { int cellIndex) {
if (writeContext.currentWriteHolder().ignore(null, cellIndex)) {
return;
}
WriteHandlerUtils.beforeCellCreate(writeContext, row, head, cellIndex, relativeRowIndex, Boolean.FALSE); WriteHandlerUtils.beforeCellCreate(writeContext, row, head, cellIndex, relativeRowIndex, Boolean.FALSE);
Cell cell = WorkBookUtil.createCell(row, cellIndex); Cell cell = WorkBookUtil.createCell(row, cellIndex);
WriteHandlerUtils.afterCellCreate(writeContext, cell, head, relativeRowIndex, Boolean.FALSE); WriteHandlerUtils.afterCellCreate(writeContext, cell, head, relativeRowIndex, Boolean.FALSE);
@ -111,7 +113,8 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor {
WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, head, relativeRowIndex, Boolean.FALSE); WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, head, relativeRowIndex, Boolean.FALSE);
} }
private void addJavaObjectToExcel(Object oneRowData, Row row, int relativeRowIndex, List<Field> fieldList) { private void addJavaObjectToExcel(Object oneRowData, Row row, int relativeRowIndex,
Map<Integer, Field> sortedAllFiledMap) {
WriteHolder currentWriteHolder = writeContext.currentWriteHolder(); WriteHolder currentWriteHolder = writeContext.currentWriteHolder();
BeanMap beanMap = BeanMap.create(oneRowData); BeanMap beanMap = BeanMap.create(oneRowData);
Set<String> beanMapHandledSet = new HashSet<String>(); Set<String> beanMapHandledSet = new HashSet<String>();
@ -125,9 +128,6 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor {
cellIndex = entry.getKey(); cellIndex = entry.getKey();
ExcelContentProperty excelContentProperty = entry.getValue(); ExcelContentProperty excelContentProperty = entry.getValue();
String name = excelContentProperty.getField().getName(); String name = excelContentProperty.getField().getName();
if (writeContext.currentWriteHolder().ignore(name, cellIndex)) {
continue;
}
if (!beanMap.containsKey(name)) { if (!beanMap.containsKey(name)) {
continue; continue;
} }
@ -146,22 +146,20 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor {
if (beanMapHandledSet.size() == beanMap.size()) { if (beanMapHandledSet.size() == beanMap.size()) {
return; return;
} }
if (cellIndex != 0) {
cellIndex++;
}
Map<String, Field> ignoreMap = writeContext.currentWriteHolder().excelWriteHeadProperty().getIgnoreMap(); Map<String, Field> ignoreMap = writeContext.currentWriteHolder().excelWriteHeadProperty().getIgnoreMap();
initFieldList(oneRowData.getClass(), fieldList); initSortedAllFiledMapFieldList(oneRowData.getClass(), sortedAllFiledMap);
for (Field field : fieldList) { for (Map.Entry<Integer, Field> entry : sortedAllFiledMap.entrySet()) {
cellIndex = entry.getKey();
Field field = entry.getValue();
String filedName = field.getName(); String filedName = field.getName();
boolean uselessData = !beanMap.containsKey(filedName) || beanMapHandledSet.contains(filedName) boolean uselessData = !beanMap.containsKey(filedName) || beanMapHandledSet.contains(filedName)
|| ignoreMap.containsKey(filedName) || writeContext.currentWriteHolder().ignore(filedName, cellIndex); || ignoreMap.containsKey(filedName);
if (uselessData) { if (uselessData) {
cellIndex++;
continue; continue;
} }
Object value = beanMap.get(filedName); Object value = beanMap.get(filedName);
WriteHandlerUtils.beforeCellCreate(writeContext, row, null, cellIndex, relativeRowIndex, Boolean.FALSE); WriteHandlerUtils.beforeCellCreate(writeContext, row, null, cellIndex, relativeRowIndex, Boolean.FALSE);
Cell cell = WorkBookUtil.createCell(row, cellIndex++); Cell cell = WorkBookUtil.createCell(row, cellIndex);
WriteHandlerUtils.afterCellCreate(writeContext, cell, null, relativeRowIndex, Boolean.FALSE); WriteHandlerUtils.afterCellCreate(writeContext, cell, null, relativeRowIndex, Boolean.FALSE);
CellData cellData = converterAndSet(currentWriteHolder, value == null ? null : value.getClass(), cell, CellData cellData = converterAndSet(currentWriteHolder, value == null ? null : value.getClass(), cell,
value, null, null, relativeRowIndex); value, null, null, relativeRowIndex);
@ -169,12 +167,18 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor {
} }
} }
private void initFieldList(Class clazz, List<Field> fieldList) { private void initSortedAllFiledMapFieldList(Class clazz, Map<Integer, Field> sortedAllFiledMap) {
if (!fieldList.isEmpty()) { if (!sortedAllFiledMap.isEmpty()) {
return; return;
} }
ClassUtils.declaredFields(clazz, fieldList, WriteWorkbookHolder writeWorkbookHolder = writeContext.writeWorkbookHolder();
writeContext.writeWorkbookHolder().getWriteWorkbook().getConvertAllFiled()); boolean needIgnore =
!CollectionUtils.isEmpty(writeWorkbookHolder.getExcludeColumnFiledNames()) || !CollectionUtils
.isEmpty(writeWorkbookHolder.getExcludeColumnIndexes()) || !CollectionUtils
.isEmpty(writeWorkbookHolder.getIncludeColumnFiledNames()) || !CollectionUtils
.isEmpty(writeWorkbookHolder.getIncludeColumnIndexes());
ClassUtils.declaredFields(clazz, sortedAllFiledMap,
writeWorkbookHolder.getWriteWorkbook().getConvertAllFiled(), needIgnore, writeWorkbookHolder);
} }
} }

6
src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java

@ -192,9 +192,6 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
Cell cell = getOneCell(analysisCell, fillConfig); Cell cell = getOneCell(analysisCell, fillConfig);
if (analysisCell.getOnlyOneVariable()) { if (analysisCell.getOnlyOneVariable()) {
String variable = analysisCell.getVariableList().get(0); String variable = analysisCell.getVariableList().get(0);
if (writeContext.currentWriteHolder().ignore(variable, analysisCell.getColumnIndex())) {
continue;
}
if (!dataMap.containsKey(variable)) { if (!dataMap.containsKey(variable)) {
continue; continue;
} }
@ -208,9 +205,6 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
List<CellData> cellDataList = new ArrayList<CellData>(); List<CellData> cellDataList = new ArrayList<CellData>();
for (String variable : analysisCell.getVariableList()) { for (String variable : analysisCell.getVariableList()) {
cellValueBuild.append(analysisCell.getPrepareDataList().get(index++)); cellValueBuild.append(analysisCell.getPrepareDataList().get(index++));
if (writeContext.currentWriteHolder().ignore(variable, analysisCell.getColumnIndex())) {
continue;
}
if (!dataMap.containsKey(variable)) { if (!dataMap.containsKey(variable)) {
continue; continue;
} }

20
src/test/java/com/alibaba/easyexcel/test/core/excludeorinclude/ExcludeOrIncludeData.java

@ -0,0 +1,20 @@
package com.alibaba.easyexcel.test.core.excludeorinclude;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
/**
* @author Jiaju Zhuang
*/
@Data
public class ExcludeOrIncludeData {
@ExcelProperty(order = 1)
private String column1;
@ExcelProperty(order = 2)
private String column2;
@ExcelProperty(order = 3)
private String column3;
@ExcelProperty(order = 4)
private String column4;
}

161
src/test/java/com/alibaba/easyexcel/test/core/excludeorinclude/ExcludeOrIncludeDataTest.java

@ -0,0 +1,161 @@
package com.alibaba.easyexcel.test.core.excludeorinclude;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
import com.alibaba.easyexcel.test.core.sort.SortData;
import com.alibaba.easyexcel.test.core.sort.SortDataListener;
import com.alibaba.easyexcel.test.util.TestFileUtil;
import com.alibaba.excel.EasyExcel;
/**
* @author Jiaju Zhuang
*/
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class ExcludeOrIncludeDataTest {
private static File excludeIndex07;
private static File excludeIndex03;
private static File excludeFiledName07;
private static File excludeFiledName03;
private static File includeIndex07;
private static File includeIndex03;
private static File includeFiledName07;
private static File includeFiledName03;
@BeforeClass
public static void init() {
excludeIndex07 = TestFileUtil.createNewFile("excludeIndex.xlsx");
excludeIndex03 = TestFileUtil.createNewFile("excludeIndex.xls");
excludeFiledName07 = TestFileUtil.createNewFile("excludeFiledName.xlsx");
excludeFiledName03 = TestFileUtil.createNewFile("excludeFiledName.xls");
includeIndex07 = TestFileUtil.createNewFile("includeIndex.xlsx");
includeIndex03 = TestFileUtil.createNewFile("includeIndex.xls");
includeFiledName07 = TestFileUtil.createNewFile("includeFiledName.xlsx");
includeFiledName03 = TestFileUtil.createNewFile("includeFiledName.xls");
}
@Test
public void t01ExcludeIndex07() {
excludeIndex(excludeIndex07);
}
@Test
public void t02ExcludeIndex07() {
excludeIndex(excludeIndex03);
}
@Test
public void t03ExcludeFiledName07() {
excludeFiledName(excludeFiledName07);
}
@Test
public void t04ExcludeFiledName07() {
excludeFiledName(excludeFiledName03);
}
@Test
public void t05IncludeIndex07() {
includeIndex(includeIndex07);
}
@Test
public void t06IncludeIndex07() {
includeIndex(includeIndex03);
}
@Test
public void t07IncludeFiledName07() {
includeFiledName(includeFiledName07);
}
@Test
public void t08IncludeFiledName07() {
includeFiledName(includeFiledName03);
}
private void excludeIndex(File file) {
Set<Integer> excludeColumnIndexes = new HashSet<Integer>();
excludeColumnIndexes.add(0);
excludeColumnIndexes.add(3);
EasyExcel.write(file, ExcludeOrIncludeData.class).excludeColumnIndexes(excludeColumnIndexes).sheet()
.doWrite(data());
List<Map<Integer, String>> dataMap = EasyExcel.read(file).sheet().doReadSync();
Assert.assertEquals(1, dataMap.size());
Map<Integer, String> record = dataMap.get(0);
Assert.assertEquals(2, record.size());
Assert.assertEquals("column2", record.get(0));
Assert.assertEquals("column3", record.get(1));
}
private void excludeFiledName(File file) {
Set<String> excludeColumnFiledNames = new HashSet<String>();
excludeColumnFiledNames.add("column1");
excludeColumnFiledNames.add("column3");
excludeColumnFiledNames.add("column4");
EasyExcel.write(file, ExcludeOrIncludeData.class).excludeColumnFiledNames(excludeColumnFiledNames).sheet()
.doWrite(data());
List<Map<Integer, String>> dataMap = EasyExcel.read(file).sheet().doReadSync();
Assert.assertEquals(1, dataMap.size());
Map<Integer, String> record = dataMap.get(0);
Assert.assertEquals(1, record.size());
Assert.assertEquals("column2", record.get(0));
}
private void includeIndex(File file) {
Set<Integer> includeColumnIndexes = new HashSet<Integer>();
includeColumnIndexes.add(1);
includeColumnIndexes.add(2);
EasyExcel.write(file, ExcludeOrIncludeData.class).includeColumnIndexes(includeColumnIndexes).sheet()
.doWrite(data());
List<Map<Integer, String>> dataMap = EasyExcel.read(file).sheet().doReadSync();
Assert.assertEquals(1, dataMap.size());
Map<Integer, String> record = dataMap.get(0);
Assert.assertEquals(2, record.size());
Assert.assertEquals("column2", record.get(0));
Assert.assertEquals("column3", record.get(1));
}
private void includeFiledName(File file) {
Set<String> includeColumnFiledNames = new HashSet<String>();
includeColumnFiledNames.add("column2");
includeColumnFiledNames.add("column3");
EasyExcel.write(file, ExcludeOrIncludeData.class).includeColumnFiledNames(includeColumnFiledNames).sheet()
.doWrite(data());
List<Map<Integer, String>> dataMap = EasyExcel.read(file).sheet().doReadSync();
Assert.assertEquals(1, dataMap.size());
Map<Integer, String> record = dataMap.get(0);
Assert.assertEquals(2, record.size());
Assert.assertEquals("column2", record.get(0));
Assert.assertEquals("column3", record.get(1));
}
private List<ExcludeOrIncludeData> data() {
List<ExcludeOrIncludeData> list = new ArrayList<ExcludeOrIncludeData>();
ExcludeOrIncludeData excludeOrIncludeData = new ExcludeOrIncludeData();
excludeOrIncludeData.setColumn1("column1");
excludeOrIncludeData.setColumn2("column2");
excludeOrIncludeData.setColumn3("column3");
excludeOrIncludeData.setColumn4("column4");
list.add(excludeOrIncludeData);
return list;
}
}

23
src/test/java/com/alibaba/easyexcel/test/core/sort/SortData.java

@ -0,0 +1,23 @@
package com.alibaba.easyexcel.test.core.sort;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
/**
* @author Jiaju Zhuang
*/
@Data
public class SortData {
private String column5;
private String column6;
@ExcelProperty(order = 99)
private String column3;
@ExcelProperty(order = 100)
private String column4;
@ExcelProperty(value = "column2", index = 1)
private String column2;
@ExcelProperty(value = "column1", index = 0)
private String column1;
}

41
src/test/java/com/alibaba/easyexcel/test/core/sort/SortDataListener.java

@ -0,0 +1,41 @@
package com.alibaba.easyexcel.test.core.sort;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.junit.Assert;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.easyexcel.test.core.simple.SimpleData;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
/**
* @author Jiaju Zhuang
*/
public class SortDataListener extends AnalysisEventListener<SortData> {
private static final Logger LOGGER = LoggerFactory.getLogger(SortDataListener.class);
List<SortData> list = new ArrayList<SortData>();
@Override
public void invoke(SortData data, AnalysisContext context) {
list.add(data);
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
Assert.assertEquals(list.size(), 1);
SortData sortData = list.get(0);
Assert.assertEquals("column1", sortData.getColumn1());
Assert.assertEquals("column2", sortData.getColumn2());
Assert.assertEquals("column3", sortData.getColumn3());
Assert.assertEquals("column4", sortData.getColumn4());
Assert.assertEquals("column5", sortData.getColumn5());
Assert.assertEquals("column6", sortData.getColumn6());
}
}

111
src/test/java/com/alibaba/easyexcel/test/core/sort/SortDataTest.java

@ -0,0 +1,111 @@
package com.alibaba.easyexcel.test.core.sort;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
import com.alibaba.easyexcel.test.util.TestFileUtil;
import com.alibaba.excel.EasyExcel;
/**
* @author Jiaju Zhuang
*/
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class SortDataTest {
private static File file07;
private static File file03;
private static File sortNoHead07;
private static File sortNoHead03;
@BeforeClass
public static void init() {
file07 = TestFileUtil.createNewFile("sort.xlsx");
file03 = TestFileUtil.createNewFile("sort.xls");
sortNoHead07 = TestFileUtil.createNewFile("sortNoHead.xlsx");
sortNoHead03 = TestFileUtil.createNewFile("sortNoHead.xls");
}
@Test
public void t01ReadAndWrite07() {
readAndWrite(file07);
}
@Test
public void t02ReadAndWrite03() {
readAndWrite(file03);
}
@Test
public void t03ReadAndWriteNoHead07() {
readAndWriteNoHead(sortNoHead07);
}
@Test
public void t04ReadAndWriteNoHead03() {
readAndWriteNoHead(sortNoHead03);
}
private void readAndWrite(File file) {
EasyExcel.write(file, SortData.class).sheet().doWrite(data());
List<Map<Integer, String>> dataMap = EasyExcel.read(file).sheet().doReadSync();
Assert.assertEquals(1, dataMap.size());
Map<Integer, String> record = dataMap.get(0);
Assert.assertEquals("column1", record.get(0));
Assert.assertEquals("column2", record.get(1));
Assert.assertEquals("column3", record.get(2));
Assert.assertEquals("column4", record.get(3));
Assert.assertEquals("column5", record.get(4));
Assert.assertEquals("column6", record.get(5));
EasyExcel.read(file, SortData.class, new SortDataListener()).sheet().doRead();
}
private void readAndWriteNoHead(File file) {
EasyExcel.write(file).head(head()).sheet().doWrite(data());
List<Map<Integer, String>> dataMap = EasyExcel.read(file).sheet().doReadSync();
Assert.assertEquals(1, dataMap.size());
Map<Integer, String> record = dataMap.get(0);
Assert.assertEquals("column1", record.get(0));
Assert.assertEquals("column2", record.get(1));
Assert.assertEquals("column3", record.get(2));
Assert.assertEquals("column4", record.get(3));
Assert.assertEquals("column5", record.get(4));
Assert.assertEquals("column6", record.get(5));
EasyExcel.read(file, SortData.class, new SortDataListener()).sheet().doRead();
}
private List<List<String>> head() {
List<List<String>> head = new ArrayList<List<String>>();
head.add(Collections.singletonList("column1"));
head.add(Collections.singletonList("column2"));
head.add(Collections.singletonList("column3"));
head.add(Collections.singletonList("column4"));
head.add(Collections.singletonList("column5"));
head.add(Collections.singletonList("column6"));
return head;
}
private List<SortData> data() {
List<SortData> list = new ArrayList<SortData>();
SortData sortData = new SortData();
sortData.setColumn1("column1");
sortData.setColumn2("column2");
sortData.setColumn3("column3");
sortData.setColumn4("column4");
sortData.setColumn5("column5");
sortData.setColumn6("column6");
list.add(sortData);
return list;
}
}

36
src/test/java/com/alibaba/easyexcel/test/temp/large/NoModelLargeDataListener.java

@ -0,0 +1,36 @@
package com.alibaba.easyexcel.test.temp.large;
import java.util.Map;
import org.apache.poi.ss.formula.functions.Index;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
/**
* @author Jiaju Zhuang
*/
public class NoModelLargeDataListener extends AnalysisEventListener<Map<Integer, String>> {
private static final Logger LOGGER = LoggerFactory.getLogger(NoModelLargeDataListener.class);
private int count = 0;
@Override
public void invoke(Map<Integer, String> data, AnalysisContext context) {
if (count == 0) {
LOGGER.info("First row:{}", JSON.toJSONString(data));
}
count++;
if (count % 100000 == 0) {
LOGGER.info("Already read:{}", count);
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
LOGGER.info("Large row count:{}", count);
}
}

11
src/test/java/com/alibaba/easyexcel/test/temp/large/TempLargeDataTest.java

@ -8,14 +8,15 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.alibaba.easyexcel.test.core.large.LargeDataTest; import com.alibaba.easyexcel.test.core.large.LargeDataTest;
import com.alibaba.easyexcel.test.util.TestFileUtil;
import com.alibaba.excel.EasyExcel; import com.alibaba.excel.EasyExcel;
/** /**
*
* @author Jiaju Zhuang * @author Jiaju Zhuang
*/ */
@Ignore @Ignore
public class TempLargeDataTest { public class TempLargeDataTest {
private static final Logger LOGGER = LoggerFactory.getLogger(LargeDataTest.class); private static final Logger LOGGER = LoggerFactory.getLogger(LargeDataTest.class);
@Test @Test
@ -25,4 +26,12 @@ public class TempLargeDataTest {
.headRowNumber(2).sheet().doRead(); .headRowNumber(2).sheet().doRead();
LOGGER.info("Large data total time spent:{}", System.currentTimeMillis() - start); LOGGER.info("Large data total time spent:{}", System.currentTimeMillis() - start);
} }
@Test
public void noModelRead() throws Exception {
long start = System.currentTimeMillis();
EasyExcel.read(TestFileUtil.readUserHomeFile("test/ld.xlsx"), new NoModelLargeDataListener())
.sheet().doRead();
LOGGER.info("Large data total time spent:{}", System.currentTimeMillis() - start);
}
} }

4
update.md

@ -1,3 +1,7 @@
# 2.2.5
* `ExcelProperty`新增`order` 用于排序
* 修复导出指定`index`会导致空行的bug
# 2.2.4 # 2.2.4
* 撤销删除`AbstractMergeStrategy` * 撤销删除`AbstractMergeStrategy`
* 修改默认用String读取数字不使用科学计数法 通过`useScientificFormat`修改 * 修改默认用String读取数字不使用科学计数法 通过`useScientificFormat`修改

Loading…
Cancel
Save