diff --git a/pom.xml b/pom.xml index be70e6bf..a887a7c6 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.alibaba easyexcel - 2.2.4 + 2.2.5 jar easyexcel diff --git a/src/main/java/com/alibaba/excel/annotation/ExcelProperty.java b/src/main/java/com/alibaba/excel/annotation/ExcelProperty.java index b107d32e..78262c6f 100644 --- a/src/main/java/com/alibaba/excel/annotation/ExcelProperty.java +++ b/src/main/java/com/alibaba/excel/annotation/ExcelProperty.java @@ -32,12 +32,23 @@ public @interface ExcelProperty { /** * 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 */ 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. * diff --git a/src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java b/src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java index 5a035772..a191260d 100644 --- a/src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java +++ b/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.Holder; import com.alibaba.excel.util.ClassUtils; +import com.alibaba.excel.util.CollectionUtils; import com.alibaba.excel.util.StringUtils; import com.alibaba.excel.write.metadata.holder.AbstractWriteHolder; @@ -117,24 +118,19 @@ public class ExcelHeadProperty { return; } // Declared fields - List defaultFieldList = new ArrayList(); - Map customFiledMap = new TreeMap(); - ClassUtils.declaredFields(headClazz, defaultFieldList, customFiledMap, ignoreMap, convertAllFiled); - - int index = 0; - for (Field field : defaultFieldList) { - while (customFiledMap.containsKey(index)) { - Field customFiled = customFiledMap.get(index); - customFiledMap.remove(index); - if (!initOneColumnProperty(holder, index, customFiled, Boolean.TRUE)) { - index++; - } - } - initOneColumnProperty(holder, index, field, Boolean.FALSE); - index++; - } - for (Map.Entry entry : customFiledMap.entrySet()) { - initOneColumnProperty(holder, entry.getKey(), entry.getValue(), Boolean.TRUE); + Map sortedAllFiledMap = new TreeMap(); + Map indexFiledMap = new TreeMap(); + + boolean needIgnore = (holder instanceof AbstractWriteHolder) && ( + !CollectionUtils.isEmpty(((AbstractWriteHolder) holder).getExcludeColumnFiledNames()) || !CollectionUtils + .isEmpty(((AbstractWriteHolder) holder).getExcludeColumnIndexes()) || !CollectionUtils + .isEmpty(((AbstractWriteHolder) holder).getIncludeColumnFiledNames()) || !CollectionUtils + .isEmpty(((AbstractWriteHolder) holder).getIncludeColumnIndexes())); + ClassUtils.declaredFields(headClazz, sortedAllFiledMap, indexFiledMap, ignoreMap, convertAllFiled, needIgnore, + holder); + + for (Map.Entry entry : sortedAllFiledMap.entrySet()) { + initOneColumnProperty(entry.getKey(), entry.getValue(), indexFiledMap.containsKey(entry.getKey())); } headKind = HeadKindEnum.CLASS; } @@ -142,18 +138,12 @@ public class ExcelHeadProperty { /** * Initialization column property * - * @param holder * @param index * @param field * @param forceIndex * @return Ignore current field */ - private boolean initOneColumnProperty(Holder holder, int index, Field field, Boolean forceIndex) { - if (holder instanceof AbstractWriteHolder) { - if (((AbstractWriteHolder) holder).ignore(field.getName(), index)) { - return true; - } - } + private void initOneColumnProperty(int index, Field field, Boolean forceIndex) { ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class); List tmpHeadList = new ArrayList(); boolean notForceName = excelProperty == null || excelProperty.value().length <= 0 @@ -189,7 +179,6 @@ public class ExcelHeadProperty { headMap.put(index, head); contentPropertyMap.put(index, excelContentProperty); fieldNameContentPropertyMap.put(field.getName(), excelContentProperty); - return false; } public Class getHeadClazz() { diff --git a/src/main/java/com/alibaba/excel/util/ClassUtils.java b/src/main/java/com/alibaba/excel/util/ClassUtils.java index 20b30e34..936c325d 100644 --- a/src/main/java/com/alibaba/excel/util/ClassUtils.java +++ b/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.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelProperty; +import com.alibaba.excel.event.Handler; import com.alibaba.excel.exception.ExcelCommonException; 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 @@ -23,26 +27,54 @@ import com.alibaba.excel.metadata.BaseRowModel; * @author Jiaju Zhuang **/ public class ClassUtils { + private static final Map> FIELD_CACHE = new ConcurrentHashMap>(); - public static void declaredFields(Class clazz, List defaultFieldList, Map customFiledMap, - Map ignoreMap, Boolean convertAllFiled) { + public static void declaredFields(Class clazz, Map sortedAllFiledMap, + Map indexFiledMap, Map ignoreMap, Boolean convertAllFiled, + Boolean needIgnore, Holder holder) { FieldCache fieldCache = getFieldCache(clazz, convertAllFiled); - if (fieldCache != null) { - defaultFieldList.addAll(fieldCache.getDefaultFieldList()); - customFiledMap.putAll(fieldCache.getCustomFiledMap()); + if (fieldCache == null) { + return; + } + if (ignoreMap != null) { ignoreMap.putAll(fieldCache.getIgnoreMap()); } - } + Map tempIndexFildMap = indexFiledMap; + if (tempIndexFildMap == null) { + tempIndexFildMap = new TreeMap(); + } + tempIndexFildMap.putAll(fieldCache.getIndexFiledMap()); - public static void declaredFields(Class clazz, List fieldList, Boolean convertAllFiled) { - FieldCache fieldCache = getFieldCache(clazz, convertAllFiled); - if (fieldCache != null) { - fieldList.addAll(fieldCache.getAllFieldList()); + if (!needIgnore) { + sortedAllFiledMap.putAll(fieldCache.getSortedAllFiledMap()); + return; + } + + int index = 0; + for (Map.Entry 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 sortedAllFiledMap, Boolean convertAllFiled, + Boolean needIgnore, WriteHolder writeHolder) { + declaredFields(clazz, sortedAllFiledMap, null, null, convertAllFiled, needIgnore, writeHolder); + } + private static FieldCache getFieldCache(Class clazz, Boolean convertAllFiled) { if (clazz == null) { return null; @@ -72,80 +104,108 @@ public class ClassUtils { tempClass = tempClass.getSuperclass(); } // Screening of field - List defaultFieldList = new ArrayList(); - Map customFiledMap = new TreeMap(); - List allFieldList = new ArrayList(); + Map> orderFiledMap = new TreeMap>(); + Map indexFiledMap = new TreeMap(); Map ignoreMap = new HashMap(16); ExcelIgnoreUnannotated excelIgnoreUnannotated = - (ExcelIgnoreUnannotated)clazz.getAnnotation(ExcelIgnoreUnannotated.class); + (ExcelIgnoreUnannotated) clazz.getAnnotation(ExcelIgnoreUnannotated.class); for (Field field : tempFieldList) { - ExcelIgnore excelIgnore = field.getAnnotation(ExcelIgnore.class); - if (excelIgnore != null) { - ignoreMap.put(field.getName(), field); - continue; - } - ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class); - boolean noExcelProperty = excelProperty == null - && ((convertAllFiled != null && !convertAllFiled) || excelIgnoreUnannotated != null); - if (noExcelProperty) { - ignoreMap.put(field.getName(), field); - continue; - } - boolean isStaticFinalOrTransient = - (Modifier.isStatic(field.getModifiers()) && Modifier.isFinal(field.getModifiers())) - || Modifier.isTransient(field.getModifiers()); - if (excelProperty == null && isStaticFinalOrTransient) { - ignoreMap.put(field.getName(), field); - continue; - } - if (excelProperty == null || excelProperty.index() < 0) { - defaultFieldList.add(field); - allFieldList.add(field); - continue; + declaredOneField(field, orderFiledMap, indexFiledMap, ignoreMap, excelIgnoreUnannotated, convertAllFiled); + } + FIELD_CACHE.put(clazz, new SoftReference( + new FieldCache(buildSortedAllFiledMap(orderFiledMap, indexFiledMap), indexFiledMap, ignoreMap))); + } + + private static Map buildSortedAllFiledMap(Map> orderFiledMap, + Map indexFiledMap) { + + Map sortedAllFiledMap = new HashMap( + (orderFiledMap.size() + indexFiledMap.size()) * 4 / 3 + 1); + + Map tempIndexFiledMap = new HashMap(indexFiledMap); + int index = 0; + for (List 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++; } - if (customFiledMap.containsKey(excelProperty.index())) { - throw new ExcelCommonException("The index of '" + customFiledMap.get(excelProperty.index()).getName() + } + sortedAllFiledMap.putAll(tempIndexFiledMap); + return sortedAllFiledMap; + } + + private static void declaredOneField(Field field, Map> orderFiledMap, + Map indexFiledMap, Map ignoreMap, ExcelIgnoreUnannotated excelIgnoreUnannotated, + Boolean convertAllFiled) { + ExcelIgnore excelIgnore = field.getAnnotation(ExcelIgnore.class); + if (excelIgnore != null) { + ignoreMap.put(field.getName(), field); + return; + } + ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class); + boolean noExcelProperty = excelProperty == null + && ((convertAllFiled != null && !convertAllFiled) || excelIgnoreUnannotated != null); + if (noExcelProperty) { + ignoreMap.put(field.getName(), field); + return; + } + boolean isStaticFinalOrTransient = + (Modifier.isStatic(field.getModifiers()) && Modifier.isFinal(field.getModifiers())) + || Modifier.isTransient(field.getModifiers()); + if (excelProperty == null && isStaticFinalOrTransient) { + ignoreMap.put(field.getName(), field); + return; + } + if (excelProperty != null && excelProperty.index() >= 0) { + if (indexFiledMap.containsKey(excelProperty.index())) { + throw new ExcelCommonException("The index of '" + indexFiledMap.get(excelProperty.index()).getName() + "' and '" + field.getName() + "' must be inconsistent"); } - customFiledMap.put(excelProperty.index(), field); + indexFiledMap.put(excelProperty.index(), field); + return; } - List allWriteFieldList = new ArrayList(customFiledMap.values()); - allWriteFieldList.addAll(allFieldList); - FIELD_CACHE.put(clazz, - new SoftReference(new FieldCache(defaultFieldList, customFiledMap, allWriteFieldList, ignoreMap))); + int order = Integer.MAX_VALUE; + if (excelProperty != null) { + order = excelProperty.order(); + } + List orderFiledList = orderFiledMap.get(order); + if (orderFiledList == null) { + orderFiledList = new ArrayList(); + orderFiledMap.put(order, orderFiledList); + } + orderFiledList.add(field); } private static class FieldCache { - private List defaultFieldList; - private Map customFiledMap; - private List allFieldList; + + private Map sortedAllFiledMap; + private Map indexFiledMap; private Map ignoreMap; - public FieldCache(List defaultFieldList, Map customFiledMap, List allFieldList, + public FieldCache(Map sortedAllFiledMap, Map indexFiledMap, Map ignoreMap) { - this.defaultFieldList = defaultFieldList; - this.customFiledMap = customFiledMap; - this.allFieldList = allFieldList; + this.sortedAllFiledMap = sortedAllFiledMap; + this.indexFiledMap = indexFiledMap; this.ignoreMap = ignoreMap; } - public List getDefaultFieldList() { - return defaultFieldList; + public Map getSortedAllFiledMap() { + return sortedAllFiledMap; } - public Map getCustomFiledMap() { - return customFiledMap; - } - - public List getAllFieldList() { - return allFieldList; + public Map getIndexFiledMap() { + return indexFiledMap; } public Map getIgnoreMap() { return ignoreMap; } - } } diff --git a/src/main/java/com/alibaba/excel/write/executor/ExcelWriteAddExecutor.java b/src/main/java/com/alibaba/excel/write/executor/ExcelWriteAddExecutor.java index 728703ef..9f229029 100644 --- a/src/main/java/com/alibaba/excel/write/executor/ExcelWriteAddExecutor.java +++ b/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.Map; import java.util.Set; +import java.util.TreeMap; import org.apache.poi.ss.usermodel.Cell; 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.WorkBookUtil; 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.WriteSheetHolder; +import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; import net.sf.cglib.beans.BeanMap; @@ -44,17 +48,18 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor { if (writeSheetHolder.isNew() && !writeSheetHolder.getExcelWriteHeadProperty().hasHead()) { newRowIndex += writeContext.currentWriteHolder().relativeHeadRowIndex(); } - // BeanMap is out of order,so use fieldList - List fieldList = new ArrayList(); - int relativeRowIndex=0; - for(Object oneRowData : data){ + // BeanMap is out of order,so use sortedAllFiledMap + Map sortedAllFiledMap = new TreeMap(); + int relativeRowIndex = 0; + for (Object oneRowData : data) { int n = relativeRowIndex + newRowIndex; - addOneRowOfDataToExcel(oneRowData, n, relativeRowIndex, fieldList); + addOneRowOfDataToExcel(oneRowData, n, relativeRowIndex, sortedAllFiledMap); relativeRowIndex++; } } - private void addOneRowOfDataToExcel(Object oneRowData, int n, int relativeRowIndex, List fieldList) { + private void addOneRowOfDataToExcel(Object oneRowData, int n, int relativeRowIndex, + Map sortedAllFiledMap) { if (oneRowData == null) { return; } @@ -62,9 +67,9 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor { Row row = WorkBookUtil.createRow(writeContext.writeSheetHolder().getSheet(), n); WriteHandlerUtils.afterRowCreate(writeContext, row, relativeRowIndex, Boolean.FALSE); if (oneRowData instanceof List) { - addBasicTypeToExcel((List)oneRowData, row, relativeRowIndex); + addBasicTypeToExcel((List) oneRowData, row, relativeRowIndex); } else { - addJavaObjectToExcel(oneRowData, row, relativeRowIndex, fieldList); + addJavaObjectToExcel(oneRowData, row, relativeRowIndex, sortedAllFiledMap); } WriteHandlerUtils.afterRowDispose(writeContext, row, relativeRowIndex, Boolean.FALSE); } @@ -99,9 +104,6 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor { private void doAddBasicTypeToExcel(List oneRowData, Head head, Row row, int relativeRowIndex, int dataIndex, int cellIndex) { - if (writeContext.currentWriteHolder().ignore(null, cellIndex)) { - return; - } WriteHandlerUtils.beforeCellCreate(writeContext, row, head, cellIndex, relativeRowIndex, Boolean.FALSE); Cell cell = WorkBookUtil.createCell(row, cellIndex); 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); } - private void addJavaObjectToExcel(Object oneRowData, Row row, int relativeRowIndex, List fieldList) { + private void addJavaObjectToExcel(Object oneRowData, Row row, int relativeRowIndex, + Map sortedAllFiledMap) { WriteHolder currentWriteHolder = writeContext.currentWriteHolder(); BeanMap beanMap = BeanMap.create(oneRowData); Set beanMapHandledSet = new HashSet(); @@ -125,9 +128,6 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor { cellIndex = entry.getKey(); ExcelContentProperty excelContentProperty = entry.getValue(); String name = excelContentProperty.getField().getName(); - if (writeContext.currentWriteHolder().ignore(name, cellIndex)) { - continue; - } if (!beanMap.containsKey(name)) { continue; } @@ -146,22 +146,20 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor { if (beanMapHandledSet.size() == beanMap.size()) { return; } - if (cellIndex != 0) { - cellIndex++; - } Map ignoreMap = writeContext.currentWriteHolder().excelWriteHeadProperty().getIgnoreMap(); - initFieldList(oneRowData.getClass(), fieldList); - for (Field field : fieldList) { + initSortedAllFiledMapFieldList(oneRowData.getClass(), sortedAllFiledMap); + for (Map.Entry entry : sortedAllFiledMap.entrySet()) { + cellIndex = entry.getKey(); + Field field = entry.getValue(); String filedName = field.getName(); boolean uselessData = !beanMap.containsKey(filedName) || beanMapHandledSet.contains(filedName) - || ignoreMap.containsKey(filedName) || writeContext.currentWriteHolder().ignore(filedName, cellIndex); + || ignoreMap.containsKey(filedName); if (uselessData) { - cellIndex++; continue; } Object value = beanMap.get(filedName); 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); CellData cellData = converterAndSet(currentWriteHolder, value == null ? null : value.getClass(), cell, value, null, null, relativeRowIndex); @@ -169,12 +167,18 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor { } } - private void initFieldList(Class clazz, List fieldList) { - if (!fieldList.isEmpty()) { + private void initSortedAllFiledMapFieldList(Class clazz, Map sortedAllFiledMap) { + if (!sortedAllFiledMap.isEmpty()) { return; } - ClassUtils.declaredFields(clazz, fieldList, - writeContext.writeWorkbookHolder().getWriteWorkbook().getConvertAllFiled()); + WriteWorkbookHolder writeWorkbookHolder = writeContext.writeWorkbookHolder(); + 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); } } diff --git a/src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java b/src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java index 29a037a6..5930a311 100644 --- a/src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java +++ b/src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java @@ -192,9 +192,6 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { Cell cell = getOneCell(analysisCell, fillConfig); if (analysisCell.getOnlyOneVariable()) { String variable = analysisCell.getVariableList().get(0); - if (writeContext.currentWriteHolder().ignore(variable, analysisCell.getColumnIndex())) { - continue; - } if (!dataMap.containsKey(variable)) { continue; } @@ -208,9 +205,6 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { List cellDataList = new ArrayList(); for (String variable : analysisCell.getVariableList()) { cellValueBuild.append(analysisCell.getPrepareDataList().get(index++)); - if (writeContext.currentWriteHolder().ignore(variable, analysisCell.getColumnIndex())) { - continue; - } if (!dataMap.containsKey(variable)) { continue; } diff --git a/src/test/java/com/alibaba/easyexcel/test/core/excludeorinclude/ExcludeOrIncludeData.java b/src/test/java/com/alibaba/easyexcel/test/core/excludeorinclude/ExcludeOrIncludeData.java new file mode 100644 index 00000000..7c49b01d --- /dev/null +++ b/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; +} diff --git a/src/test/java/com/alibaba/easyexcel/test/core/excludeorinclude/ExcludeOrIncludeDataTest.java b/src/test/java/com/alibaba/easyexcel/test/core/excludeorinclude/ExcludeOrIncludeDataTest.java new file mode 100644 index 00000000..e6a8fc1c --- /dev/null +++ b/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 excludeColumnIndexes = new HashSet(); + excludeColumnIndexes.add(0); + excludeColumnIndexes.add(3); + EasyExcel.write(file, ExcludeOrIncludeData.class).excludeColumnIndexes(excludeColumnIndexes).sheet() + .doWrite(data()); + List> dataMap = EasyExcel.read(file).sheet().doReadSync(); + Assert.assertEquals(1, dataMap.size()); + Map 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 excludeColumnFiledNames = new HashSet(); + excludeColumnFiledNames.add("column1"); + excludeColumnFiledNames.add("column3"); + excludeColumnFiledNames.add("column4"); + EasyExcel.write(file, ExcludeOrIncludeData.class).excludeColumnFiledNames(excludeColumnFiledNames).sheet() + .doWrite(data()); + List> dataMap = EasyExcel.read(file).sheet().doReadSync(); + Assert.assertEquals(1, dataMap.size()); + Map record = dataMap.get(0); + Assert.assertEquals(1, record.size()); + Assert.assertEquals("column2", record.get(0)); + + } + + private void includeIndex(File file) { + Set includeColumnIndexes = new HashSet(); + includeColumnIndexes.add(1); + includeColumnIndexes.add(2); + EasyExcel.write(file, ExcludeOrIncludeData.class).includeColumnIndexes(includeColumnIndexes).sheet() + .doWrite(data()); + List> dataMap = EasyExcel.read(file).sheet().doReadSync(); + Assert.assertEquals(1, dataMap.size()); + Map 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 includeColumnFiledNames = new HashSet(); + includeColumnFiledNames.add("column2"); + includeColumnFiledNames.add("column3"); + EasyExcel.write(file, ExcludeOrIncludeData.class).includeColumnFiledNames(includeColumnFiledNames).sheet() + .doWrite(data()); + List> dataMap = EasyExcel.read(file).sheet().doReadSync(); + Assert.assertEquals(1, dataMap.size()); + Map record = dataMap.get(0); + Assert.assertEquals(2, record.size()); + Assert.assertEquals("column2", record.get(0)); + Assert.assertEquals("column3", record.get(1)); + } + + + private List data() { + List list = new ArrayList(); + ExcludeOrIncludeData excludeOrIncludeData = new ExcludeOrIncludeData(); + excludeOrIncludeData.setColumn1("column1"); + excludeOrIncludeData.setColumn2("column2"); + excludeOrIncludeData.setColumn3("column3"); + excludeOrIncludeData.setColumn4("column4"); + list.add(excludeOrIncludeData); + return list; + } +} diff --git a/src/test/java/com/alibaba/easyexcel/test/core/sort/SortData.java b/src/test/java/com/alibaba/easyexcel/test/core/sort/SortData.java new file mode 100644 index 00000000..fd928d6b --- /dev/null +++ b/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; +} diff --git a/src/test/java/com/alibaba/easyexcel/test/core/sort/SortDataListener.java b/src/test/java/com/alibaba/easyexcel/test/core/sort/SortDataListener.java new file mode 100644 index 00000000..227bddfd --- /dev/null +++ b/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 { + + private static final Logger LOGGER = LoggerFactory.getLogger(SortDataListener.class); + List list = new ArrayList(); + + + @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()); + } +} diff --git a/src/test/java/com/alibaba/easyexcel/test/core/sort/SortDataTest.java b/src/test/java/com/alibaba/easyexcel/test/core/sort/SortDataTest.java new file mode 100644 index 00000000..698078a1 --- /dev/null +++ b/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> dataMap = EasyExcel.read(file).sheet().doReadSync(); + Assert.assertEquals(1, dataMap.size()); + Map 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> dataMap = EasyExcel.read(file).sheet().doReadSync(); + Assert.assertEquals(1, dataMap.size()); + Map 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> head() { + List> head = new ArrayList>(); + 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 data() { + List list = new ArrayList(); + 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; + } +} diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/large/NoModelLargeDataListener.java b/src/test/java/com/alibaba/easyexcel/test/temp/large/NoModelLargeDataListener.java new file mode 100644 index 00000000..715dc4f4 --- /dev/null +++ b/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> { + + private static final Logger LOGGER = LoggerFactory.getLogger(NoModelLargeDataListener.class); + private int count = 0; + + @Override + public void invoke(Map 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); + } +} diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/large/TempLargeDataTest.java b/src/test/java/com/alibaba/easyexcel/test/temp/large/TempLargeDataTest.java index 6d142333..0bde12ef 100644 --- a/src/test/java/com/alibaba/easyexcel/test/temp/large/TempLargeDataTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/temp/large/TempLargeDataTest.java @@ -8,14 +8,15 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.easyexcel.test.core.large.LargeDataTest; +import com.alibaba.easyexcel.test.util.TestFileUtil; import com.alibaba.excel.EasyExcel; /** - * * @author Jiaju Zhuang */ @Ignore public class TempLargeDataTest { + private static final Logger LOGGER = LoggerFactory.getLogger(LargeDataTest.class); @Test @@ -25,4 +26,12 @@ public class TempLargeDataTest { .headRowNumber(2).sheet().doRead(); 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); + } } diff --git a/update.md b/update.md index 5374449a..32b34e00 100644 --- a/update.md +++ b/update.md @@ -1,3 +1,7 @@ +# 2.2.5 +* `ExcelProperty`新增`order` 用于排序 +* 修复导出指定`index`会导致空行的bug + # 2.2.4 * 撤销删除`AbstractMergeStrategy` * 修改默认用String读取数字不使用科学计数法 通过`useScientificFormat`修改