|
|
@ -18,6 +18,8 @@ import com.alibaba.excel.metadata.data.WriteCellData; |
|
|
|
import com.alibaba.excel.metadata.property.ExcelContentProperty; |
|
|
|
import com.alibaba.excel.metadata.property.ExcelContentProperty; |
|
|
|
import com.alibaba.excel.util.BeanMapUtils; |
|
|
|
import com.alibaba.excel.util.BeanMapUtils; |
|
|
|
import com.alibaba.excel.util.FieldUtils; |
|
|
|
import com.alibaba.excel.util.FieldUtils; |
|
|
|
|
|
|
|
import com.alibaba.excel.util.ListUtils; |
|
|
|
|
|
|
|
import com.alibaba.excel.util.MapUtils; |
|
|
|
import com.alibaba.excel.util.StringUtils; |
|
|
|
import com.alibaba.excel.util.StringUtils; |
|
|
|
import com.alibaba.excel.util.WriteHandlerUtils; |
|
|
|
import com.alibaba.excel.util.WriteHandlerUtils; |
|
|
|
import com.alibaba.excel.write.metadata.fill.AnalysisCell; |
|
|
|
import com.alibaba.excel.write.metadata.fill.AnalysisCell; |
|
|
@ -48,32 +50,25 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { |
|
|
|
/** |
|
|
|
/** |
|
|
|
* Fields to replace in the template |
|
|
|
* Fields to replace in the template |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private final Map<String, List<AnalysisCell>> templateAnalysisCache = new HashMap<String, List<AnalysisCell>>(8); |
|
|
|
private final Map<String, List<AnalysisCell>> templateAnalysisCache = MapUtils.newHashMap(); |
|
|
|
/** |
|
|
|
/** |
|
|
|
* Collection fields to replace in the template |
|
|
|
* Collection fields to replace in the template |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private final Map<String, List<AnalysisCell>> templateCollectionAnalysisCache = |
|
|
|
private final Map<String, List<AnalysisCell>> templateCollectionAnalysisCache = MapUtils.newHashMap(); |
|
|
|
new HashMap<String, List<AnalysisCell>>(8); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Style cache for collection fields |
|
|
|
* Style cache for collection fields |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private final Map<String, Map<AnalysisCell, CellStyle>> collectionFieldStyleCache = |
|
|
|
private final Map<String, Map<AnalysisCell, CellStyle>> collectionFieldStyleCache = MapUtils.newHashMap(); |
|
|
|
new HashMap<String, Map<AnalysisCell, CellStyle>>(8); |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Row height cache for collection |
|
|
|
* Row height cache for collection |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private final Map<String, Short> collectionRowHeightCache = new HashMap<String, Short>(8); |
|
|
|
private final Map<String, Short> collectionRowHeightCache = MapUtils.newHashMap(); |
|
|
|
/** |
|
|
|
/** |
|
|
|
* Last index cache for collection fields |
|
|
|
* Last index cache for collection fields |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private final Map<String, Map<AnalysisCell, Integer>> collectionLastIndexCache = |
|
|
|
private final Map<String, Map<AnalysisCell, Integer>> collectionLastIndexCache = MapUtils.newHashMap(); |
|
|
|
new HashMap<String, Map<AnalysisCell, Integer>>(8); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final Map<String, Integer> relativeRowIndexMap = new HashMap<String, Integer>(8); |
|
|
|
private final Map<String, Integer> relativeRowIndexMap = MapUtils.newHashMap(); |
|
|
|
/** |
|
|
|
|
|
|
|
* The data prefix that is populated this time |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
private String currentDataPrefix; |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* The unique data encoding for this fill |
|
|
|
* The unique data encoding for this fill |
|
|
|
*/ |
|
|
|
*/ |
|
|
@ -93,6 +88,9 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { |
|
|
|
fillConfig.init(); |
|
|
|
fillConfig.init(); |
|
|
|
|
|
|
|
|
|
|
|
Object realData; |
|
|
|
Object realData; |
|
|
|
|
|
|
|
// The data prefix that is populated this time
|
|
|
|
|
|
|
|
String currentDataPrefix; |
|
|
|
|
|
|
|
|
|
|
|
if (data instanceof FillWrapper) { |
|
|
|
if (data instanceof FillWrapper) { |
|
|
|
FillWrapper fillWrapper = (FillWrapper)data; |
|
|
|
FillWrapper fillWrapper = (FillWrapper)data; |
|
|
|
currentDataPrefix = fillWrapper.getName(); |
|
|
|
currentDataPrefix = fillWrapper.getName(); |
|
|
@ -106,11 +104,11 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { |
|
|
|
// processing data
|
|
|
|
// processing data
|
|
|
|
if (realData instanceof Collection) { |
|
|
|
if (realData instanceof Collection) { |
|
|
|
List<AnalysisCell> analysisCellList = readTemplateData(templateCollectionAnalysisCache); |
|
|
|
List<AnalysisCell> analysisCellList = readTemplateData(templateCollectionAnalysisCache); |
|
|
|
Collection collectionData = (Collection)realData; |
|
|
|
Collection<?> collectionData = (Collection<?>)realData; |
|
|
|
if (CollectionUtils.isEmpty(collectionData)) { |
|
|
|
if (CollectionUtils.isEmpty(collectionData)) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
Iterator iterator = collectionData.iterator(); |
|
|
|
Iterator<?> iterator = collectionData.iterator(); |
|
|
|
if (WriteDirectionEnum.VERTICAL.equals(fillConfig.getDirection()) && fillConfig.getForceNewRow()) { |
|
|
|
if (WriteDirectionEnum.VERTICAL.equals(fillConfig.getDirection()) && fillConfig.getForceNewRow()) { |
|
|
|
shiftRows(collectionData.size(), analysisCellList); |
|
|
|
shiftRows(collectionData.size(), analysisCellList); |
|
|
|
} |
|
|
|
} |
|
|
@ -182,9 +180,9 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { |
|
|
|
if (CollectionUtils.isEmpty(analysisCellList)) { |
|
|
|
if (CollectionUtils.isEmpty(analysisCellList)) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
Map dataMap; |
|
|
|
Map<?, ?> dataMap; |
|
|
|
if (oneRowData instanceof Map) { |
|
|
|
if (oneRowData instanceof Map) { |
|
|
|
dataMap = (Map)oneRowData; |
|
|
|
dataMap = (Map<?, ?>)oneRowData; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
dataMap = BeanMapUtils.create(oneRowData); |
|
|
|
dataMap = BeanMapUtils.create(oneRowData); |
|
|
|
} |
|
|
|
} |
|
|
@ -259,11 +257,9 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { |
|
|
|
} |
|
|
|
} |
|
|
|
Sheet sheet = writeContext.writeSheetHolder().getSheet(); |
|
|
|
Sheet sheet = writeContext.writeSheetHolder().getSheet(); |
|
|
|
|
|
|
|
|
|
|
|
Map<AnalysisCell, Integer> collectionLastIndexMap = collectionLastIndexCache.get(currentUniqueDataFlag); |
|
|
|
Map<AnalysisCell, Integer> collectionLastIndexMap = collectionLastIndexCache |
|
|
|
if (collectionLastIndexMap == null) { |
|
|
|
.computeIfAbsent(currentUniqueDataFlag, key -> MapUtils.newHashMap()); |
|
|
|
collectionLastIndexMap = new HashMap<AnalysisCell, Integer>(16); |
|
|
|
|
|
|
|
collectionLastIndexCache.put(currentUniqueDataFlag, collectionLastIndexMap); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
boolean isOriginalCell = false; |
|
|
|
boolean isOriginalCell = false; |
|
|
|
Integer lastRowIndex; |
|
|
|
Integer lastRowIndex; |
|
|
|
Integer lastColumnIndex; |
|
|
|
Integer lastColumnIndex; |
|
|
@ -297,11 +293,9 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { |
|
|
|
Row row = createRowIfNecessary(sheet, cachedSheet, lastRowIndex, fillConfig, analysisCell, isOriginalCell); |
|
|
|
Row row = createRowIfNecessary(sheet, cachedSheet, lastRowIndex, fillConfig, analysisCell, isOriginalCell); |
|
|
|
Cell cell = createCellIfNecessary(row, lastColumnIndex); |
|
|
|
Cell cell = createCellIfNecessary(row, lastColumnIndex); |
|
|
|
|
|
|
|
|
|
|
|
Map<AnalysisCell, CellStyle> collectionFieldStyleMap = collectionFieldStyleCache.get(currentUniqueDataFlag); |
|
|
|
Map<AnalysisCell, CellStyle> collectionFieldStyleMap = collectionFieldStyleCache.computeIfAbsent( |
|
|
|
if (collectionFieldStyleMap == null) { |
|
|
|
currentUniqueDataFlag, key -> MapUtils.newHashMap()); |
|
|
|
collectionFieldStyleMap = new HashMap<AnalysisCell, CellStyle>(16); |
|
|
|
|
|
|
|
collectionFieldStyleCache.put(currentUniqueDataFlag, collectionFieldStyleMap); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (isOriginalCell) { |
|
|
|
if (isOriginalCell) { |
|
|
|
collectionFieldStyleMap.put(analysisCell, cell.getCellStyle()); |
|
|
|
collectionFieldStyleMap.put(analysisCell, cell.getCellStyle()); |
|
|
|
} else { |
|
|
|
} else { |
|
|
@ -373,7 +367,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { |
|
|
|
return analysisCellList; |
|
|
|
return analysisCellList; |
|
|
|
} |
|
|
|
} |
|
|
|
Sheet sheet = writeContext.writeSheetHolder().getCachedSheet(); |
|
|
|
Sheet sheet = writeContext.writeSheetHolder().getCachedSheet(); |
|
|
|
Map<String, Set<Integer>> firstRowCache = new HashMap<String, Set<Integer>>(8); |
|
|
|
Map<String, Set<Integer>> firstRowCache = MapUtils.newHashMapWithExpectedSize(8); |
|
|
|
for (int i = 0; i <= sheet.getLastRowNum(); i++) { |
|
|
|
for (int i = 0; i <= sheet.getLastRowNum(); i++) { |
|
|
|
Row row = sheet.getRow(i); |
|
|
|
Row row = sheet.getRow(i); |
|
|
|
if (row == null) { |
|
|
|
if (row == null) { |
|
|
@ -397,14 +391,14 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { |
|
|
|
/** |
|
|
|
/** |
|
|
|
* To prepare data |
|
|
|
* To prepare data |
|
|
|
* |
|
|
|
* |
|
|
|
* @param cell |
|
|
|
* @param cell cell |
|
|
|
* @param rowIndex |
|
|
|
* @param rowIndex row index |
|
|
|
* @param columnIndex |
|
|
|
* @param columnIndex column index |
|
|
|
* @param firstRowCache |
|
|
|
* @param firstRowCache first row cache |
|
|
|
* @return Returns the data that the cell needs to replace |
|
|
|
* @return Returns the data that the cell needs to replace |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private String prepareData(Cell cell, int rowIndex, int columnIndex, Map<String, Set<Integer>> firstRowCache) { |
|
|
|
private String prepareData(Cell cell, int rowIndex, int columnIndex, Map<String, Set<Integer>> firstRowCache) { |
|
|
|
if (!CellType.STRING.equals(cell.getCellTypeEnum())) { |
|
|
|
if (!CellType.STRING.equals(cell.getCellType())) { |
|
|
|
return null; |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
String value = cell.getStringCellValue(); |
|
|
|
String value = cell.getStringCellValue(); |
|
|
@ -421,7 +415,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { |
|
|
|
while (startIndex < length) { |
|
|
|
while (startIndex < length) { |
|
|
|
int prefixIndex = value.indexOf(FILL_PREFIX, startIndex); |
|
|
|
int prefixIndex = value.indexOf(FILL_PREFIX, startIndex); |
|
|
|
if (prefixIndex < 0) { |
|
|
|
if (prefixIndex < 0) { |
|
|
|
break out; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
if (prefixIndex != 0) { |
|
|
|
if (prefixIndex != 0) { |
|
|
|
char prefixPrefixChar = value.charAt(prefixIndex - 1); |
|
|
|
char prefixPrefixChar = value.charAt(prefixIndex - 1); |
|
|
@ -491,28 +485,21 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { |
|
|
|
} |
|
|
|
} |
|
|
|
String uniqueDataFlag = uniqueDataFlag(writeContext.writeSheetHolder(), analysisCell.getPrefix()); |
|
|
|
String uniqueDataFlag = uniqueDataFlag(writeContext.writeSheetHolder(), analysisCell.getPrefix()); |
|
|
|
if (WriteTemplateAnalysisCellTypeEnum.COMMON.equals(analysisCell.getCellType())) { |
|
|
|
if (WriteTemplateAnalysisCellTypeEnum.COMMON.equals(analysisCell.getCellType())) { |
|
|
|
List<AnalysisCell> analysisCellList = templateAnalysisCache.get(uniqueDataFlag); |
|
|
|
List<AnalysisCell> analysisCellList = templateAnalysisCache.computeIfAbsent(uniqueDataFlag, |
|
|
|
if (analysisCellList == null) { |
|
|
|
key -> ListUtils.newArrayList()); |
|
|
|
analysisCellList = new ArrayList<AnalysisCell>(); |
|
|
|
|
|
|
|
templateAnalysisCache.put(uniqueDataFlag, analysisCellList); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
analysisCellList.add(analysisCell); |
|
|
|
analysisCellList.add(analysisCell); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
Set<Integer> uniqueFirstRowCache = firstRowCache.get(uniqueDataFlag); |
|
|
|
Set<Integer> uniqueFirstRowCache = firstRowCache.computeIfAbsent(uniqueDataFlag, |
|
|
|
if (uniqueFirstRowCache == null) { |
|
|
|
key -> new HashSet<>()); |
|
|
|
uniqueFirstRowCache = new HashSet<Integer>(); |
|
|
|
|
|
|
|
firstRowCache.put(uniqueDataFlag, uniqueFirstRowCache); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (!uniqueFirstRowCache.contains(rowIndex)) { |
|
|
|
if (!uniqueFirstRowCache.contains(rowIndex)) { |
|
|
|
analysisCell.setFirstRow(Boolean.TRUE); |
|
|
|
analysisCell.setFirstRow(Boolean.TRUE); |
|
|
|
uniqueFirstRowCache.add(rowIndex); |
|
|
|
uniqueFirstRowCache.add(rowIndex); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
List<AnalysisCell> collectionAnalysisCellList = templateCollectionAnalysisCache.get(uniqueDataFlag); |
|
|
|
List<AnalysisCell> collectionAnalysisCellList = templateCollectionAnalysisCache.computeIfAbsent( |
|
|
|
if (collectionAnalysisCellList == null) { |
|
|
|
uniqueDataFlag, key -> ListUtils.newArrayList()); |
|
|
|
collectionAnalysisCellList = new ArrayList<AnalysisCell>(); |
|
|
|
|
|
|
|
templateCollectionAnalysisCache.put(uniqueDataFlag, collectionAnalysisCellList); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
collectionAnalysisCellList.add(analysisCell); |
|
|
|
collectionAnalysisCellList.add(analysisCell); |
|
|
|
} |
|
|
|
} |
|
|
|
return preparedData.toString(); |
|
|
|
return preparedData.toString(); |
|
|
@ -525,9 +512,9 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { |
|
|
|
analysisCell.setRowIndex(rowIndex); |
|
|
|
analysisCell.setRowIndex(rowIndex); |
|
|
|
analysisCell.setColumnIndex(columnIndex); |
|
|
|
analysisCell.setColumnIndex(columnIndex); |
|
|
|
analysisCell.setOnlyOneVariable(Boolean.TRUE); |
|
|
|
analysisCell.setOnlyOneVariable(Boolean.TRUE); |
|
|
|
List<String> variableList = new ArrayList<String>(); |
|
|
|
List<String> variableList = ListUtils.newArrayList(); |
|
|
|
analysisCell.setVariableList(variableList); |
|
|
|
analysisCell.setVariableList(variableList); |
|
|
|
List<String> prepareDataList = new ArrayList<String>(); |
|
|
|
List<String> prepareDataList = ListUtils.newArrayList(); |
|
|
|
analysisCell.setPrepareDataList(prepareDataList); |
|
|
|
analysisCell.setPrepareDataList(prepareDataList); |
|
|
|
analysisCell.setCellType(WriteTemplateAnalysisCellTypeEnum.COMMON); |
|
|
|
analysisCell.setCellType(WriteTemplateAnalysisCellTypeEnum.COMMON); |
|
|
|
analysisCell.setFirstRow(Boolean.FALSE); |
|
|
|
analysisCell.setFirstRow(Boolean.FALSE); |
|
|
@ -545,7 +532,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { |
|
|
|
if (writeSheetHolder.getSheetNo() != null) { |
|
|
|
if (writeSheetHolder.getSheetNo() != null) { |
|
|
|
prefix = writeSheetHolder.getSheetNo().toString(); |
|
|
|
prefix = writeSheetHolder.getSheetNo().toString(); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
prefix = writeSheetHolder.getSheetName().toString(); |
|
|
|
prefix = writeSheetHolder.getSheetName(); |
|
|
|
} |
|
|
|
} |
|
|
|
if (StringUtils.isEmpty(wrapperName)) { |
|
|
|
if (StringUtils.isEmpty(wrapperName)) { |
|
|
|
return prefix + "-"; |
|
|
|
return prefix + "-"; |
|
|
|