替换easyexcel默认处理类

This commit is contained in:
b2baccline
2021-05-06 10:39:58 +08:00
parent 9f1f4e968c
commit 8ef6874efc
2 changed files with 400 additions and 0 deletions

View File

@@ -0,0 +1,215 @@
package com.alibaba.excel.util;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.exception.ExcelCommonException;
import com.alibaba.excel.metadata.BaseRowModel;
import com.alibaba.excel.metadata.Holder;
import com.alibaba.excel.write.metadata.holder.WriteHolder;
import java.lang.ref.SoftReference;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* Class utils
*
* @author Jiaju Zhuang
**/
public class ClassUtils {
private static final Map<Class, SoftReference<FieldCache>> FIELD_CACHE = new ConcurrentHashMap<Class, SoftReference<FieldCache>>();
public static void declaredFields(Class clazz, Map<Integer, Field> sortedAllFiledMap,
Map<Integer, Field> indexFiledMap, Map<String, Field> ignoreMap, Boolean convertAllFiled,
Boolean needIgnore, Holder holder) {
FieldCache fieldCache = getFieldCache(clazz, convertAllFiled);
if (fieldCache == null) {
return;
}
if (ignoreMap != null) {
ignoreMap.putAll(fieldCache.getIgnoreMap());
}
Map<Integer, Field> tempIndexFildMap = indexFiledMap;
if (tempIndexFildMap == null) {
tempIndexFildMap = new TreeMap<Integer, Field>();
}
tempIndexFildMap.putAll(fieldCache.getIndexFiledMap());
Map<Integer, Field> originSortedAllFiledMap = fieldCache.getSortedAllFiledMap();
if (!needIgnore) {
sortedAllFiledMap.putAll(originSortedAllFiledMap);
return;
}
// 获取到属性字段的最大index
int maxIndex = -1;
for (Integer filedIndex : originSortedAllFiledMap.keySet()) {
maxIndex = Math.max(filedIndex, maxIndex);
}
// 被忽略的属性数量
int ignoreNum = 0;
// 当有属性被忽略时,需要将其后面的所有属性 index 前移
for (int index = 0; index <= maxIndex; index++) {
Field field = originSortedAllFiledMap.get(index);
String name = field == null ? null : field.getName();
if (((WriteHolder) holder).ignore(name, index)) {
if (ignoreMap != null && name != null) {
ignoreMap.put(name, field);
}
tempIndexFildMap.remove(index);
ignoreNum++;
}
else if (field != null) {
int finalIndex = index - ignoreNum;
sortedAllFiledMap.put(finalIndex, field);
}
}
}
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) {
if (clazz == null) {
return null;
}
SoftReference<FieldCache> fieldCacheSoftReference = FIELD_CACHE.get(clazz);
if (fieldCacheSoftReference != null && fieldCacheSoftReference.get() != null) {
return fieldCacheSoftReference.get();
}
synchronized (clazz) {
fieldCacheSoftReference = FIELD_CACHE.get(clazz);
if (fieldCacheSoftReference != null && fieldCacheSoftReference.get() != null) {
return fieldCacheSoftReference.get();
}
declaredFields(clazz, convertAllFiled);
}
return FIELD_CACHE.get(clazz).get();
}
private static void declaredFields(Class clazz, Boolean convertAllFiled) {
List<Field> tempFieldList = new ArrayList<Field>();
Class tempClass = clazz;
// When the parent class is null, it indicates that the parent class (Object
// class) has reached the top
// level.
while (tempClass != null && tempClass != BaseRowModel.class) {
Collections.addAll(tempFieldList, tempClass.getDeclaredFields());
// Get the parent class and give it to yourself
tempClass = tempClass.getSuperclass();
}
// Screening of field
Map<Integer, List<Field>> orderFiledMap = new TreeMap<Integer, List<Field>>();
Map<Integer, Field> indexFiledMap = new TreeMap<Integer, Field>();
Map<String, Field> ignoreMap = new HashMap<String, Field>(16);
ExcelIgnoreUnannotated excelIgnoreUnannotated = (ExcelIgnoreUnannotated) clazz
.getAnnotation(ExcelIgnoreUnannotated.class);
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);
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");
}
indexFiledMap.put(excelProperty.index(), field);
return;
}
int order = Integer.MAX_VALUE;
if (excelProperty != null) {
order = excelProperty.order();
}
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 Map<Integer, Field> sortedAllFiledMap;
private Map<Integer, Field> indexFiledMap;
private Map<String, Field> ignoreMap;
public FieldCache(Map<Integer, Field> sortedAllFiledMap, Map<Integer, Field> indexFiledMap,
Map<String, Field> ignoreMap) {
this.sortedAllFiledMap = sortedAllFiledMap;
this.indexFiledMap = indexFiledMap;
this.ignoreMap = ignoreMap;
}
public Map<Integer, Field> getSortedAllFiledMap() {
return sortedAllFiledMap;
}
public Map<Integer, Field> getIndexFiledMap() {
return indexFiledMap;
}
public Map<String, Field> getIgnoreMap() {
return ignoreMap;
}
}
}

View File

@@ -0,0 +1,185 @@
package com.alibaba.excel.write.executor;
import com.alibaba.excel.context.WriteContext;
import com.alibaba.excel.enums.HeadKindEnum;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
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.executor.AbstractExcelWriteExecutor;
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 net.sf.cglib.beans.BeanMap;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
/**
* Add the data into excel
*
* @author Jiaju Zhuang
*/
public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor {
public ExcelWriteAddExecutor(WriteContext writeContext) {
super(writeContext);
}
public void add(List data) {
if (CollectionUtils.isEmpty(data)) {
data = new ArrayList();
}
WriteSheetHolder writeSheetHolder = writeContext.writeSheetHolder();
int newRowIndex = writeSheetHolder.getNewRowIndexAndStartDoWrite();
if (writeSheetHolder.isNew() && !writeSheetHolder.getExcelWriteHeadProperty().hasHead()) {
newRowIndex += writeContext.currentWriteHolder().relativeHeadRowIndex();
}
// BeanMap is out of order,so use sortedAllFiledMap
Map<Integer, Field> sortedAllFiledMap = new TreeMap<Integer, Field>();
int relativeRowIndex = 0;
for (Object oneRowData : data) {
int n = relativeRowIndex + newRowIndex;
addOneRowOfDataToExcel(oneRowData, n, relativeRowIndex, sortedAllFiledMap);
relativeRowIndex++;
}
}
private void addOneRowOfDataToExcel(Object oneRowData, int n, int relativeRowIndex,
Map<Integer, Field> sortedAllFiledMap) {
if (oneRowData == null) {
return;
}
WriteHandlerUtils.beforeRowCreate(writeContext, n, relativeRowIndex, Boolean.FALSE);
Row row = WorkBookUtil.createRow(writeContext.writeSheetHolder().getSheet(), n);
WriteHandlerUtils.afterRowCreate(writeContext, row, relativeRowIndex, Boolean.FALSE);
if (oneRowData instanceof List) {
addBasicTypeToExcel((List) oneRowData, row, relativeRowIndex);
}
else {
addJavaObjectToExcel(oneRowData, row, relativeRowIndex, sortedAllFiledMap);
}
WriteHandlerUtils.afterRowDispose(writeContext, row, relativeRowIndex, Boolean.FALSE);
}
private void addBasicTypeToExcel(List<Object> oneRowData, Row row, int relativeRowIndex) {
if (CollectionUtils.isEmpty(oneRowData)) {
return;
}
Map<Integer, Head> headMap = writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadMap();
int dataIndex = 0;
int cellIndex = 0;
for (Map.Entry<Integer, Head> entry : headMap.entrySet()) {
if (dataIndex >= oneRowData.size()) {
return;
}
cellIndex = entry.getKey();
Head head = entry.getValue();
doAddBasicTypeToExcel(oneRowData, head, row, relativeRowIndex, dataIndex++, cellIndex);
}
// Finish
if (dataIndex >= oneRowData.size()) {
return;
}
if (cellIndex != 0) {
cellIndex++;
}
int size = oneRowData.size() - dataIndex;
for (int i = 0; i < size; i++) {
doAddBasicTypeToExcel(oneRowData, null, row, relativeRowIndex, dataIndex++, cellIndex++);
}
}
private void doAddBasicTypeToExcel(List<Object> oneRowData, Head head, Row row, int relativeRowIndex, int dataIndex,
int cellIndex) {
WriteHandlerUtils.beforeCellCreate(writeContext, row, head, cellIndex, relativeRowIndex, Boolean.FALSE);
Cell cell = WorkBookUtil.createCell(row, cellIndex);
WriteHandlerUtils.afterCellCreate(writeContext, cell, head, relativeRowIndex, Boolean.FALSE);
Object value = oneRowData.get(dataIndex);
CellData cellData = converterAndSet(writeContext.currentWriteHolder(), value == null ? null : value.getClass(),
cell, value, null, head, relativeRowIndex);
WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, head, relativeRowIndex, Boolean.FALSE);
}
private void addJavaObjectToExcel(Object oneRowData, Row row, int relativeRowIndex,
Map<Integer, Field> sortedAllFiledMap) {
WriteHolder currentWriteHolder = writeContext.currentWriteHolder();
BeanMap beanMap = BeanMap.create(oneRowData);
Set<String> beanMapHandledSet = new HashSet<String>();
int cellIndex = 0;
// If it's a class it needs to be cast by type
if (HeadKindEnum.CLASS.equals(writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadKind())) {
Map<Integer, Head> headMap = writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadMap();
Map<Integer, ExcelContentProperty> contentPropertyMap = writeContext.currentWriteHolder()
.excelWriteHeadProperty().getContentPropertyMap();
for (Map.Entry<Integer, ExcelContentProperty> entry : contentPropertyMap.entrySet()) {
cellIndex = entry.getKey();
ExcelContentProperty excelContentProperty = entry.getValue();
String name = excelContentProperty.getField().getName();
if (!beanMap.containsKey(name)) {
continue;
}
Head head = headMap.get(cellIndex);
WriteHandlerUtils.beforeCellCreate(writeContext, row, head, cellIndex, relativeRowIndex, Boolean.FALSE);
Cell cell = WorkBookUtil.createCell(row, cellIndex);
WriteHandlerUtils.afterCellCreate(writeContext, cell, head, relativeRowIndex, Boolean.FALSE);
Object value = beanMap.get(name);
CellData cellData = converterAndSet(currentWriteHolder, excelContentProperty.getField().getType(), cell,
value, excelContentProperty, head, relativeRowIndex);
WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, head, relativeRowIndex, Boolean.FALSE);
beanMapHandledSet.add(name);
}
}
// Finish
if (beanMapHandledSet.size() == beanMap.size()) {
return;
}
Map<String, Field> ignoreMap = writeContext.currentWriteHolder().excelWriteHeadProperty().getIgnoreMap();
initSortedAllFiledMapFieldList(oneRowData.getClass(), sortedAllFiledMap);
for (Map.Entry<Integer, Field> 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);
if (uselessData) {
continue;
}
Object value = beanMap.get(filedName);
WriteHandlerUtils.beforeCellCreate(writeContext, row, null, cellIndex, relativeRowIndex, Boolean.FALSE);
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);
WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, null, relativeRowIndex, Boolean.FALSE);
}
}
private void initSortedAllFiledMapFieldList(Class clazz, Map<Integer, Field> sortedAllFiledMap) {
if (!sortedAllFiledMap.isEmpty()) {
return;
}
// 获取当前的使用的 holder
WriteHolder holder = writeContext.currentWriteHolder();
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(clazz, sortedAllFiledMap,
writeContext.writeWorkbookHolder().getWriteWorkbook().getConvertAllFiled(), needIgnore, holder);
}
}