Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix:#3604 #3610

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import com.alibaba.excel.write.handler.context.RowWriteHandlerContext;
import com.alibaba.excel.write.metadata.fill.AnalysisCell;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.excel.write.metadata.fill.FillIndex;
import com.alibaba.excel.write.metadata.fill.FillWrapper;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;

Expand Down Expand Up @@ -71,7 +72,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor {
* Style cache for collection fields
*/
private final Map<UniqueDataFlagKey, Map<AnalysisCell, CellStyle>> collectionFieldStyleCache
= MapUtils.newHashMap();
= MapUtils.newHashMap();
/**
* Row height cache for collection
*/
Expand Down Expand Up @@ -174,11 +175,11 @@ private void shiftRows(int size, List<AnalysisCell> analysisCellList) {
}

private void increaseRowIndex(Map<UniqueDataFlagKey, List<AnalysisCell>> templateAnalysisCache, int number,
int maxRowIndex) {
int maxRowIndex) {
for (Map.Entry<UniqueDataFlagKey, List<AnalysisCell>> entry : templateAnalysisCache.entrySet()) {
UniqueDataFlagKey uniqueDataFlagKey = entry.getKey();
if (!Objects.equals(currentUniqueDataFlag.getSheetNo(), uniqueDataFlagKey.getSheetNo()) || !Objects.equals(
currentUniqueDataFlag.getSheetName(), uniqueDataFlagKey.getSheetName())) {
currentUniqueDataFlag.getSheetName(), uniqueDataFlagKey.getSheetName())) {
continue;
}
for (AnalysisCell analysisCell : entry.getValue()) {
Expand All @@ -190,7 +191,7 @@ private void increaseRowIndex(Map<UniqueDataFlagKey, List<AnalysisCell>> templat
}

private void doFill(List<AnalysisCell> analysisCellList, Object oneRowData, FillConfig fillConfig,
Integer relativeRowIndex) {
Integer relativeRowIndex) {
if (CollectionUtils.isEmpty(analysisCellList) || oneRowData == null) {
return;
}
Expand All @@ -203,22 +204,23 @@ private void doFill(List<AnalysisCell> analysisCellList, Object oneRowData, Fill
Set<String> dataKeySet = new HashSet<>(dataMap.keySet());

RowWriteHandlerContext rowWriteHandlerContext = WriteHandlerUtils.createRowWriteHandlerContext(writeContext,
null, relativeRowIndex, Boolean.FALSE);
null, relativeRowIndex, Boolean.FALSE);

for (AnalysisCell analysisCell : analysisCellList) {
CellWriteHandlerContext cellWriteHandlerContext = WriteHandlerUtils.createCellWriteHandlerContext(
writeContext, null, analysisCell.getRowIndex(), null, analysisCell.getColumnIndex(),
relativeRowIndex, Boolean.FALSE, ExcelContentProperty.EMPTY);
writeContext, null, analysisCell.getRowIndex(), null, analysisCell.getColumnIndex(),
relativeRowIndex, Boolean.FALSE, ExcelContentProperty.EMPTY);

if (analysisCell.getOnlyOneVariable()) {
String variable = analysisCell.getVariableList().get(0);
if (!dataKeySet.contains(variable)) {
updateFileIndex(analysisCell, fillConfig);
continue;
}
Object value = dataMap.get(variable);
ExcelContentProperty excelContentProperty = ClassUtils.declaredExcelContentProperty(dataMap,
writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadClazz(), variable,
writeContext.currentWriteHolder());
writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadClazz(), variable,
writeContext.currentWriteHolder());
cellWriteHandlerContext.setExcelContentProperty(excelContentProperty);

createCell(analysisCell, fillConfig, cellWriteHandlerContext, rowWriteHandlerContext);
Expand All @@ -231,8 +233,8 @@ private void doFill(List<AnalysisCell> analysisCellList, Object oneRowData, Fill
// Restyle
if (fillConfig.getAutoStyle()) {
Optional.ofNullable(collectionFieldStyleCache.get(currentUniqueDataFlag))
.map(collectionFieldStyleMap -> collectionFieldStyleMap.get(analysisCell))
.ifPresent(cellData::setOriginCellStyle);
.map(collectionFieldStyleMap -> collectionFieldStyleMap.get(analysisCell))
.ifPresent(cellData::setOriginCellStyle);
}
} else {
StringBuilder cellValueBuild = new StringBuilder();
Expand All @@ -248,12 +250,13 @@ private void doFill(List<AnalysisCell> analysisCellList, Object oneRowData, Fill
for (String variable : analysisCell.getVariableList()) {
cellValueBuild.append(analysisCell.getPrepareDataList().get(index++));
if (!dataKeySet.contains(variable)) {
updateFileIndex(analysisCell, fillConfig);
continue;
}
Object value = dataMap.get(variable);
ExcelContentProperty excelContentProperty = ClassUtils.declaredExcelContentProperty(dataMap,
writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadClazz(), variable,
writeContext.currentWriteHolder());
writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadClazz(), variable,
writeContext.currentWriteHolder());
cellWriteHandlerContext.setOriginalValue(value);
cellWriteHandlerContext.setOriginalFieldClass(FieldUtils.getFieldClass(dataMap, variable, value));
cellWriteHandlerContext.setExcelContentProperty(excelContentProperty);
Expand Down Expand Up @@ -289,8 +292,8 @@ private void doFill(List<AnalysisCell> analysisCellList, Object oneRowData, Fill
// Restyle
if (fillConfig.getAutoStyle()) {
Optional.ofNullable(collectionFieldStyleCache.get(currentUniqueDataFlag))
.map(collectionFieldStyleMap -> collectionFieldStyleMap.get(analysisCell))
.ifPresent(cell::setCellStyle);
.map(collectionFieldStyleMap -> collectionFieldStyleMap.get(analysisCell))
.ifPresent(cell::setCellStyle);
}
}
WriteHandlerUtils.afterCellDispose(cellWriteHandlerContext);
Expand All @@ -313,22 +316,9 @@ private Integer getRelativeRowIndex() {
return relativeRowIndex;
}

private void createCell(AnalysisCell analysisCell, FillConfig fillConfig,
CellWriteHandlerContext cellWriteHandlerContext, RowWriteHandlerContext rowWriteHandlerContext) {
Sheet cachedSheet = writeContext.writeSheetHolder().getCachedSheet();
if (WriteTemplateAnalysisCellTypeEnum.COMMON.equals(analysisCell.getCellType())) {
Row row = cachedSheet.getRow(analysisCell.getRowIndex());
cellWriteHandlerContext.setRow(row);
Cell cell = row.getCell(analysisCell.getColumnIndex());
cellWriteHandlerContext.setCell(cell);
rowWriteHandlerContext.setRow(row);
rowWriteHandlerContext.setRowIndex(analysisCell.getRowIndex());
return;
}
Sheet sheet = writeContext.writeSheetHolder().getSheet();

private FillIndex updateFileIndex(AnalysisCell analysisCell,FillConfig fillConfig){
Map<AnalysisCell, Integer> collectionLastIndexMap = collectionLastIndexCache
.computeIfAbsent(currentUniqueDataFlag, key -> MapUtils.newHashMap());
.computeIfAbsent(currentUniqueDataFlag, key -> MapUtils.newHashMap());

boolean isOriginalCell = false;
Integer lastRowIndex;
Expand Down Expand Up @@ -359,25 +349,43 @@ private void createCell(AnalysisCell analysisCell, FillConfig fillConfig,
default:
throw new ExcelGenerateException("The wrong direction.");
}
return new FillIndex(lastRowIndex,lastColumnIndex,isOriginalCell);
}

private void createCell(AnalysisCell analysisCell, FillConfig fillConfig,
CellWriteHandlerContext cellWriteHandlerContext, RowWriteHandlerContext rowWriteHandlerContext) {
Sheet cachedSheet = writeContext.writeSheetHolder().getCachedSheet();
if (WriteTemplateAnalysisCellTypeEnum.COMMON.equals(analysisCell.getCellType())) {
Row row = cachedSheet.getRow(analysisCell.getRowIndex());
cellWriteHandlerContext.setRow(row);
Cell cell = row.getCell(analysisCell.getColumnIndex());
cellWriteHandlerContext.setCell(cell);
rowWriteHandlerContext.setRow(row);
rowWriteHandlerContext.setRowIndex(analysisCell.getRowIndex());
return;
}
Sheet sheet = writeContext.writeSheetHolder().getSheet();

FillIndex fillIndex = updateFileIndex(analysisCell, fillConfig);

Row row = createRowIfNecessary(sheet, cachedSheet, lastRowIndex, fillConfig, analysisCell, isOriginalCell,
rowWriteHandlerContext);
Row row = createRowIfNecessary(sheet, cachedSheet, fillIndex.getLastRowIndex(), fillConfig, analysisCell, fillIndex.getIsOriginalCell(),
rowWriteHandlerContext);
cellWriteHandlerContext.setRow(row);

cellWriteHandlerContext.setRowIndex(lastRowIndex);
cellWriteHandlerContext.setColumnIndex(lastColumnIndex);
Cell cell = createCellIfNecessary(row, lastColumnIndex, cellWriteHandlerContext);
cellWriteHandlerContext.setRowIndex(fillIndex.getLastRowIndex());
cellWriteHandlerContext.setColumnIndex(fillIndex.getLastColumnIndex());
Cell cell = createCellIfNecessary(row, fillIndex.getLastColumnIndex(), cellWriteHandlerContext);
cellWriteHandlerContext.setCell(cell);

if (isOriginalCell) {
if (fillIndex.getIsOriginalCell()) {
Map<AnalysisCell, CellStyle> collectionFieldStyleMap = collectionFieldStyleCache.computeIfAbsent(
currentUniqueDataFlag, key -> MapUtils.newHashMap());
currentUniqueDataFlag, key -> MapUtils.newHashMap());
collectionFieldStyleMap.put(analysisCell, cell.getCellStyle());
}
}

private Cell createCellIfNecessary(Row row, Integer lastColumnIndex,
CellWriteHandlerContext cellWriteHandlerContext) {
CellWriteHandlerContext cellWriteHandlerContext) {
Cell cell = row.getCell(lastColumnIndex);
if (cell != null) {
return cell;
Expand All @@ -391,7 +399,7 @@ private Cell createCellIfNecessary(Row row, Integer lastColumnIndex,
}

private Row createRowIfNecessary(Sheet sheet, Sheet cachedSheet, Integer lastRowIndex, FillConfig fillConfig,
AnalysisCell analysisCell, boolean isOriginalCell, RowWriteHandlerContext rowWriteHandlerContext) {
AnalysisCell analysisCell, boolean isOriginalCell, RowWriteHandlerContext rowWriteHandlerContext) {
rowWriteHandlerContext.setRowIndex(lastRowIndex);
Row row = sheet.getRow(lastRowIndex);
if (row != null) {
Expand Down Expand Up @@ -481,7 +489,7 @@ private List<AnalysisCell> readTemplateData(Map<UniqueDataFlagKey, List<Analysis
* @return Returns the data that the cell needs to replace
*/
private String prepareData(Cell cell, int rowIndex, int columnIndex,
Map<UniqueDataFlagKey, Set<Integer>> firstRowCache) {
Map<UniqueDataFlagKey, Set<Integer>> firstRowCache) {
if (!CellType.STRING.equals(cell.getCellType())) {
return null;
}
Expand Down Expand Up @@ -560,11 +568,11 @@ private String prepareData(Cell cell, int rowIndex, int columnIndex,
cell.setBlank();
}
return dealAnalysisCell(analysisCell, value, rowIndex, lastPrepareDataIndex, length, firstRowCache,
preparedData);
preparedData);
}

private String dealAnalysisCell(AnalysisCell analysisCell, String value, int rowIndex, int lastPrepareDataIndex,
int length, Map<UniqueDataFlagKey, Set<Integer>> firstRowCache, StringBuilder preparedData) {
int length, Map<UniqueDataFlagKey, Set<Integer>> firstRowCache, StringBuilder preparedData) {
if (analysisCell != null) {
if (lastPrepareDataIndex == length) {
analysisCell.getPrepareDataList().add(StringUtils.EMPTY);
Expand All @@ -573,22 +581,22 @@ private String dealAnalysisCell(AnalysisCell analysisCell, String value, int row
analysisCell.setOnlyOneVariable(Boolean.FALSE);
}
UniqueDataFlagKey uniqueDataFlag = uniqueDataFlag(writeContext.writeSheetHolder(),
analysisCell.getPrefix());
analysisCell.getPrefix());
if (WriteTemplateAnalysisCellTypeEnum.COMMON.equals(analysisCell.getCellType())) {
List<AnalysisCell> analysisCellList = templateAnalysisCache.computeIfAbsent(uniqueDataFlag,
key -> ListUtils.newArrayList());
key -> ListUtils.newArrayList());
analysisCellList.add(analysisCell);
} else {
Set<Integer> uniqueFirstRowCache = firstRowCache.computeIfAbsent(uniqueDataFlag,
key -> new HashSet<>());
key -> new HashSet<>());

if (!uniqueFirstRowCache.contains(rowIndex)) {
analysisCell.setFirstRow(Boolean.TRUE);
uniqueFirstRowCache.add(rowIndex);
}

List<AnalysisCell> collectionAnalysisCellList = templateCollectionAnalysisCache.computeIfAbsent(
uniqueDataFlag, key -> ListUtils.newArrayList());
uniqueDataFlag, key -> ListUtils.newArrayList());

collectionAnalysisCellList.add(analysisCell);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.alibaba.excel.write.metadata.fill;

import lombok.*;

/**
* @author youlingdada
* @version 1.0
* createDate 2023/12/16 16:06
*/
@Getter
@Setter
@EqualsAndHashCode
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class FillIndex {
/**
* last row index
*/
private Integer lastRowIndex;
/**
* last column index
*/
private Integer lastColumnIndex;

/**
* Whether the original cell is used
*/
private Boolean isOriginalCell;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.alibaba.easyexcel.test.temp.issue3604;

import com.alibaba.easyexcel.test.util.TestFileUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.enums.WriteDirectionEnum;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.excel.write.metadata.fill.FillWrapper;
import org.junit.jupiter.api.Test;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* @author youlingdada
* @version 1.0
* createDate 2023/12/16 16:40
*/
public class Issue3604 {

@Test
public void test1() {
// 准备 10 行数据,基本上每行都有 aaa 和 bbb 两个 key,值分别为 a1 和 b1, a2 和 b2, ...
// 唯独第 5 行,故意删除掉 bbb 这个 key
List<Map<String, Object>> dataLineList = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
Map<String, Object> m = new HashMap<>();
m.put("aaa", "a" + i);
m.put("bbb", "b" + i);
if (i == 5) {
m.remove("bbb");
}
dataLineList.add(m);
}
String targetFile = TestFileUtil.getPath() + "temp/issue3604" + File.separator + "result3.xlsx";
String templateFile = TestFileUtil.getPath() + "temp/issue3604" + File.separator + "template3.xlsx";

ExcelWriter excelWriter = EasyExcel.write(targetFile).withTemplate(templateFile).build();
WriteSheet writeSheet = EasyExcel.writerSheet().build();
FillConfig fillConfig = FillConfig.builder().direction(WriteDirectionEnum.VERTICAL).build();
excelWriter.fill(new FillWrapper("dataLine", dataLineList), fillConfig, writeSheet);
excelWriter.writeContext().writeWorkbookHolder().getWorkbook().setForceFormulaRecalculation(true);
excelWriter.finish();
}
}
Binary file not shown.
Binary file not shown.