From e57a2a718ac8beaff9a9303e7582bc18937ee809 Mon Sep 17 00:00:00 2001 From: milixiang Date: Wed, 30 Jul 2025 10:53:55 +0800 Subject: [PATCH 1/9] feature: Support Dynamic Column in Fill Operation for Collection Data --- .../excel/annotation/fill/DynamicColumn.java | 15 +++ .../fesod/excel/temp/fill/FillTempTest.java | 67 ++++++++++- .../executor/AbstractExcelWriteExecutor.java | 107 +++++++++++++++++- .../executor/ExcelWriteFillExecutor.java | 90 ++++++++++++++- .../context/CellWriteHandlerContext.java | 49 +++++++- .../excel/write/metadata/fill/FillConfig.java | 8 ++ 6 files changed, 324 insertions(+), 12 deletions(-) create mode 100644 fastexcel/src/main/java/cn/idev/excel/annotation/fill/DynamicColumn.java diff --git a/fastexcel/src/main/java/cn/idev/excel/annotation/fill/DynamicColumn.java b/fastexcel/src/main/java/cn/idev/excel/annotation/fill/DynamicColumn.java new file mode 100644 index 000000000..1df5c33f0 --- /dev/null +++ b/fastexcel/src/main/java/cn/idev/excel/annotation/fill/DynamicColumn.java @@ -0,0 +1,15 @@ +package cn.idev.excel.annotation.fill; + + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.annotation.Inherited; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@Inherited +public @interface DynamicColumn { + +} diff --git a/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/FillTempTest.java b/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/FillTempTest.java index 1366aa814..1187b9c08 100644 --- a/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/FillTempTest.java +++ b/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/FillTempTest.java @@ -35,6 +35,8 @@ import org.apache.fesod.excel.write.metadata.fill.FillWrapper; import org.junit.jupiter.api.Test; +import static cn.idev.excel.enums.WriteDirectionEnum.HORIZONTAL; + /** * Example of filling data into Excel templates. * @@ -72,6 +74,69 @@ public void simpleFill() { */ } + @Test + public void dynamicFill() { + String templateFileName = "src/test/resources/fill/dynamicColumn.xlsx"; + String fileName = TestFileUtil.getPath() + "dynamicColumnFill" + System.currentTimeMillis() + ".xlsx"; + + DynamicFillData fillData1 = new DynamicFillData(); + fillData1.setName("Zhang San"); + fillData1.setNumber(5.2); + HashMap qtyMap = new HashMap<>(); + qtyMap.put("2023-01-01", "100"); + qtyMap.put("2023-01-02", "200"); + qtyMap.put("2023-01-03", "300"); + fillData1.setQtyMap(qtyMap); + HashMap priceMap = new HashMap<>(); + priceMap.put("2023-01-01", new DynamicFillDataObj("100个", 100)); + priceMap.put("2023-01-02", new DynamicFillDataObj("200个", 200)); + priceMap.put("2023-01-03", new DynamicFillDataObj("300个", 300)); + fillData1.setPriceMap(priceMap); + + DynamicFillData fillData2 = new DynamicFillData(); + fillData2.setName("Li Si"); + fillData2.setNumber(6.3); + HashMap qtyMap2 = new HashMap<>(); + qtyMap2.put("2023-01-01", "100"); + qtyMap2.put("2023-01-02", "200"); + qtyMap2.put("2023-01-03", "300"); + fillData2.setQtyMap(qtyMap2); + HashMap priceMap2 = new HashMap<>(); + priceMap2.put("2023-01-01", new DynamicFillDataObj("100", 100)); + priceMap2.put("2023-01-02", new DynamicFillDataObj("200", 200)); + priceMap2.put("2023-01-03", new DynamicFillDataObj("300", 300)); + fillData2.setPriceMap(priceMap2); + + List fillDataList = new ArrayList<>(); + fillDataList.add(fillData1); + fillDataList.add(fillData2); + + ArrayList dateListMap = new ArrayList<>(); + HashMap date1 = new HashMap<>(); + date1.put("date", "2023-01-01"); + dateListMap.add(date1); + HashMap date2 = new HashMap<>(); + date2.put("date", "2023-01-02"); + dateListMap.add(date2); + HashMap date3 = new HashMap<>(); + date3.put("date", "2023-01-03"); + dateListMap.add(date3); + + ArrayList dateList = new ArrayList<>(); + dateList.add("2023-01-01"); + dateList.add("2023-01-02"); + dateList.add("2023-01-03"); + + ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build(); + WriteSheet writeSheet = EasyExcel.writerSheet().build(); + excelWriter.fill(new FillWrapper("dataList", fillDataList), FillConfig.builder().dynamicColumnKeys(dateList).forceNewRow(true).build(), writeSheet); + excelWriter.fill(new FillWrapper("dataObjList", fillDataList), FillConfig.builder().dynamicColumnGroupSize(2).dynamicColumnKeys(dateList).forceNewRow(true).build(), writeSheet); + excelWriter.fill(new FillWrapper("dateListMap", dateListMap), FillConfig.builder().direction(HORIZONTAL).build(), writeSheet); + // Do not forget to close the stream + excelWriter.finish(); + + } + /** * Example of filling a list of data. * @@ -205,7 +270,7 @@ public void horizontalFill() { excelWriter.fill(data(), fillConfig, writeSheet); excelWriter.fill(data(), fillConfig, writeSheet); - Map map = new HashMap(); + Map map = new HashMap(); map.put("date", "2019-10-09 13:28:28"); excelWriter.fill(map, writeSheet); diff --git a/fesod/src/main/java/org/apache/fesod/excel/write/executor/AbstractExcelWriteExecutor.java b/fesod/src/main/java/org/apache/fesod/excel/write/executor/AbstractExcelWriteExecutor.java index b6a7f6cce..31acd1bb8 100644 --- a/fesod/src/main/java/org/apache/fesod/excel/write/executor/AbstractExcelWriteExecutor.java +++ b/fesod/src/main/java/org/apache/fesod/excel/write/executor/AbstractExcelWriteExecutor.java @@ -20,6 +20,33 @@ package org.apache.fesod.excel.write.executor; import java.util.List; +import cn.idev.excel.annotation.fill.DynamicColumn; +import cn.idev.excel.context.WriteContext; +import cn.idev.excel.converters.Converter; +import cn.idev.excel.converters.ConverterKeyBuild; +import cn.idev.excel.converters.NullableObjectConverter; +import cn.idev.excel.converters.WriteConverterContext; +import cn.idev.excel.enums.CellDataTypeEnum; +import cn.idev.excel.enums.WriteDirectionEnum; +import cn.idev.excel.exception.ExcelWriteDataConvertException; +import cn.idev.excel.metadata.data.CommentData; +import cn.idev.excel.metadata.data.FormulaData; +import cn.idev.excel.metadata.data.HyperlinkData; +import cn.idev.excel.metadata.data.ImageData; +import cn.idev.excel.metadata.data.WriteCellData; +import cn.idev.excel.metadata.property.ExcelContentProperty; +import cn.idev.excel.support.ExcelTypeEnum; +import cn.idev.excel.support.cglib.beans.BeanMap; +import cn.idev.excel.util.BeanMapUtils; +import cn.idev.excel.util.DateUtils; +import cn.idev.excel.util.FieldUtils; +import cn.idev.excel.util.FileTypeUtils; +import cn.idev.excel.util.ListUtils; +import cn.idev.excel.util.StyleUtil; +import cn.idev.excel.util.WorkBookUtil; +import cn.idev.excel.util.WriteHandlerUtils; +import cn.idev.excel.write.handler.context.CellWriteHandlerContext; +import cn.idev.excel.write.metadata.fill.FillConfig; import org.apache.commons.collections4.CollectionUtils; import org.apache.fesod.excel.context.WriteContext; import org.apache.fesod.excel.converters.Converter; @@ -53,6 +80,10 @@ import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.usermodel.XSSFClientAnchor; +import java.lang.reflect.Field; +import java.util.List; +import java.util.Map; + /** * Excel write Executor * @@ -66,12 +97,11 @@ public AbstractExcelWriteExecutor(WriteContext writeContext) { } /** - * Transform the data and then to set into the cell + * Transform item * * @param cellWriteHandlerContext context - */ - protected void converterAndSet(CellWriteHandlerContext cellWriteHandlerContext) { - + * */ + protected void convertAndSetItem(CellWriteHandlerContext cellWriteHandlerContext) { WriteCellData cellData = convert(cellWriteHandlerContext); cellWriteHandlerContext.setCellDataList(ListUtils.newArrayList(cellData)); cellWriteHandlerContext.setFirstCellData(cellData); @@ -97,7 +127,20 @@ protected void converterAndSet(CellWriteHandlerContext cellWriteHandlerContext) if (cellData.getType() == null) { cellData.setType(CellDataTypeEnum.EMPTY); } - Cell cell = cellWriteHandlerContext.getCell(); + if (null != cellWriteHandlerContext.getCellMap() && cellWriteHandlerContext.getCellMap().size() > 1) { + cellWriteHandlerContext.getCellMap().forEach((k,cell) -> { + String[] split = k.split("_"); + int rowIndex = Integer.parseInt(split[0]); + int columnIndex = Integer.parseInt(split[1]); + setCellValue(cell, cellData, cell.getCell()); + }); + }else{ + Cell cell = cellWriteHandlerContext.getCell(); + setCellValue(cellWriteHandlerContext, cellData, cell); + } + } + + private void setCellValue(CellWriteHandlerContext cellWriteHandlerContext, WriteCellData cellData, Cell cell) { switch (cellData.getType()) { case STRING: cell.setCellValue(cellData.getStringValue()); @@ -126,6 +169,60 @@ protected void converterAndSet(CellWriteHandlerContext cellWriteHandlerContext) } } + /** + * Transform the data and then to set into the cell + * + * @param cellWriteHandlerContext context + */ + protected void converterAndSet(CellWriteHandlerContext cellWriteHandlerContext) { + Object originalValue = cellWriteHandlerContext.getOriginalValue(); + Field field = cellWriteHandlerContext.getExcelContentProperty().getField(); + if (null != field && field.isAnnotationPresent(DynamicColumn.class)) { + Map dynamicColumnMap = (Map) originalValue; + FillConfig fillConfig = cellWriteHandlerContext.getFillConfig(); + if(null == fillConfig || CollectionUtils.isEmpty(fillConfig.getDynamicColumnKeys())){ + throw new ExcelWriteDataConvertException(cellWriteHandlerContext, "DynamicColumn annotation must be used with FillConfig.dynamicColumnKeys,FillConfig.dynamicColumnGroupSize"); + } + List dynamicColumnKeys = fillConfig.getDynamicColumnKeys(); + Integer columnIndex = cellWriteHandlerContext.getColumnIndex(); + Integer rowIndex = cellWriteHandlerContext.getRowIndex(); + for (int i = 0; i < dynamicColumnKeys.size(); i++) { + String key = dynamicColumnKeys.get(i); + Object o = dynamicColumnMap.get(key); + String originalVariable = cellWriteHandlerContext.getOriginalVariable(); + if(originalVariable.contains(".")){ + key = originalVariable.split("\\.")[1]; + Object itemBean = o; + BeanMap beanMap = BeanMapUtils.create(itemBean); + o = beanMap.get(key); + } + + Integer dynamicColumnGroupSize = fillConfig.getDynamicColumnGroupSize(); + WriteDirectionEnum direction = fillConfig.getDirection(); + int currentRowIndex = rowIndex; + int currentColumnIndex = columnIndex; + if(WriteDirectionEnum.VERTICAL.equals(direction)){ + currentColumnIndex = columnIndex + dynamicColumnGroupSize * i; + }else{ + currentRowIndex = rowIndex + dynamicColumnGroupSize*i; + } + + Map cellMap = cellWriteHandlerContext.getCellMap(); + CellWriteHandlerContext currentCellWriteHandlerContext = cellMap.get(currentRowIndex + "_" + currentColumnIndex); + currentCellWriteHandlerContext.setOriginalValue(o); + currentCellWriteHandlerContext.setOriginalFieldClass(FieldUtils.getFieldClass(o)); + convertAndSetItem(currentCellWriteHandlerContext); + if (i == 0) { + cellWriteHandlerContext.setOriginalValue(o); + cellWriteHandlerContext.setOriginalFieldClass(FieldUtils.getFieldClass(o)); + convertAndSetItem(cellWriteHandlerContext); + } + } + } else { + convertAndSetItem(cellWriteHandlerContext); + } + } + private void fillFormula(CellWriteHandlerContext cellWriteHandlerContext, FormulaData formulaData) { if (formulaData == null) { return; diff --git a/fesod/src/main/java/org/apache/fesod/excel/write/executor/ExcelWriteFillExecutor.java b/fesod/src/main/java/org/apache/fesod/excel/write/executor/ExcelWriteFillExecutor.java index ab0289dc5..0abdcc1e6 100644 --- a/fesod/src/main/java/org/apache/fesod/excel/write/executor/ExcelWriteFillExecutor.java +++ b/fesod/src/main/java/org/apache/fesod/excel/write/executor/ExcelWriteFillExecutor.java @@ -17,6 +17,30 @@ * under the License. */ +import cn.idev.excel.annotation.fill.DynamicColumn; +import cn.idev.excel.context.WriteContext; +import cn.idev.excel.enums.CellDataTypeEnum; +import cn.idev.excel.enums.WriteDirectionEnum; +import cn.idev.excel.enums.WriteTemplateAnalysisCellTypeEnum; +import cn.idev.excel.exception.ExcelGenerateException; +import cn.idev.excel.metadata.data.WriteCellData; +import cn.idev.excel.metadata.property.ExcelContentProperty; +import cn.idev.excel.util.BeanMapUtils; +import cn.idev.excel.util.ClassUtils; +import cn.idev.excel.util.FieldUtils; +import cn.idev.excel.util.ListUtils; +import cn.idev.excel.util.MapUtils; +import cn.idev.excel.util.PoiUtils; +import cn.idev.excel.util.StringUtils; +import cn.idev.excel.util.WriteHandlerUtils; +import cn.idev.excel.write.handler.context.CellWriteHandlerContext; +import cn.idev.excel.write.handler.context.RowWriteHandlerContext; +import cn.idev.excel.write.metadata.fill.AnalysisCell; +import cn.idev.excel.write.metadata.fill.FillConfig; +import cn.idev.excel.write.metadata.fill.FillWrapper; +import cn.idev.excel.write.metadata.holder.WriteSheetHolder; + +import java.lang.reflect.Field; package org.apache.fesod.excel.write.executor; import java.util.ArrayList; @@ -232,10 +256,14 @@ private void doFill( ExcelContentProperty.EMPTY); if (analysisCell.getOnlyOneVariable()) { - String variable = analysisCell.getVariableList().get(0); + String originalVariable = analysisCell.getVariableList().get(0); + String variable = originalVariable; Object value = null; if (dataKeySet.contains(variable)) { value = dataMap.get(variable); + }else if(variable.contains(".")){ + variable = variable.split("\\.")[0]; + value = dataMap.get(variable); } ExcelContentProperty excelContentProperty = ClassUtils.declaredExcelContentProperty( dataMap, @@ -245,11 +273,12 @@ private void doFill( .getHeadClazz(), variable, writeContext.currentWriteHolder()); + cellWriteHandlerContext.setOriginalVariable(originalVariable); + cellWriteHandlerContext.setFillConfig(fillConfig); cellWriteHandlerContext.setExcelContentProperty(excelContentProperty); - - createCell(analysisCell, fillConfig, cellWriteHandlerContext, rowWriteHandlerContext); cellWriteHandlerContext.setOriginalValue(value); cellWriteHandlerContext.setOriginalFieldClass(FieldUtils.getFieldClass(dataMap, variable, value)); + createCell(analysisCell, fillConfig, cellWriteHandlerContext, rowWriteHandlerContext); converterAndSet(cellWriteHandlerContext); WriteCellData cellData = cellWriteHandlerContext.getFirstCellData(); @@ -258,7 +287,13 @@ private void doFill( if (fillConfig.getAutoStyle()) { Optional.ofNullable(collectionFieldStyleCache.get(currentUniqueDataFlag)) .map(collectionFieldStyleMap -> collectionFieldStyleMap.get(analysisCell)) - .ifPresent(cellData::setOriginCellStyle); + .ifPresent(style -> { + if (cellWriteHandlerContext.getCellMap() != null && cellWriteHandlerContext.getCellMap().size() > 1) { + cellWriteHandlerContext.getCellMap().values().forEach(cell -> cell.getFirstCellData().setOriginCellStyle(style)); + }else{ + cellData.setOriginCellStyle(style); + } + }); } } else { StringBuilder cellValueBuild = new StringBuilder(); @@ -324,7 +359,12 @@ private void doFill( .ifPresent(cell::setCellStyle); } } - WriteHandlerUtils.afterCellDispose(cellWriteHandlerContext); + if (cellWriteHandlerContext.getCellMap() != null && cellWriteHandlerContext.getCellMap().size() > 1) { + //trigger afterCellDispose for every dynamicColumns + cellWriteHandlerContext.getCellMap().values().forEach(WriteHandlerUtils::afterCellDispose); + }else{ + WriteHandlerUtils.afterCellDispose(cellWriteHandlerContext); + } } // In the case of the fill line may be called many times @@ -394,6 +434,9 @@ private void createCell( throw new ExcelGenerateException("The wrong direction."); } + ExcelContentProperty excelContentProperty = cellWriteHandlerContext.getExcelContentProperty(); + Field field = excelContentProperty.getField(); + Row row = createRowIfNecessary( sheet, cachedSheet, lastRowIndex, fillConfig, analysisCell, isOriginalCell, rowWriteHandlerContext); cellWriteHandlerContext.setRow(row); @@ -403,10 +446,47 @@ private void createCell( Cell cell = createCellIfNecessary(row, lastColumnIndex, cellWriteHandlerContext); cellWriteHandlerContext.setCell(cell); + if(null != field && field.isAnnotationPresent(DynamicColumn.class)){ + if (cellWriteHandlerContext.getCellMap() == null) { + cellWriteHandlerContext.setCellMap(new HashMap<>()); + } + cellWriteHandlerContext.getCellMap().put(lastRowIndex + "_" + lastColumnIndex, cellWriteHandlerContext); + List dynamicColumnKeys = fillConfig.getDynamicColumnKeys(); + if(CollectionUtils.isEmpty(dynamicColumnKeys)){ + throw new ExcelGenerateException(String.format("Plase set dynamic column keys for %s in fillConfig",field.getName())); + } + for (int i = 1; i < dynamicColumnKeys.size(); i++) { + switch (fillConfig.getDirection()) { + case VERTICAL: + lastColumnIndex = lastColumnIndex + fillConfig.getDynamicColumnGroupSize(); + break; + case HORIZONTAL: + lastRowIndex = lastRowIndex + fillConfig.getDynamicColumnGroupSize(); + break; + default: + throw new ExcelGenerateException("The wrong direction."); + } + Row newRow = createRowIfNecessary( sheet, cachedSheet, lastRowIndex, fillConfig, analysisCell, false, rowWriteHandlerContext); + CellWriteHandlerContext cloneContext = cellWriteHandlerContext.clone(); + cloneContext.setColumnIndex(lastColumnIndex); + cloneContext.setRowIndex(row.getRowNum()); + Cell cloneCell = createCellIfNecessary(newRow, lastColumnIndex, cloneContext); + cloneContext.setCell(cloneCell); + cellWriteHandlerContext.getCellMap().put(row.getRowNum() + "_" + lastColumnIndex, cloneContext); + } + } + if (isOriginalCell) { Map collectionFieldStyleMap = collectionFieldStyleCache.computeIfAbsent(currentUniqueDataFlag, key -> MapUtils.newHashMap()); collectionFieldStyleMap.put(analysisCell, cell.getCellStyle()); + if (cellWriteHandlerContext.getCellMap() != null && cellWriteHandlerContext.getCellMap().size() > 1) { + cellWriteHandlerContext.getCellMap().forEach((k, cellContext) -> { + Integer currentColumnIndex = cellContext.getColumnIndex(); + int columnWidth = sheet.getColumnWidth(cellWriteHandlerContext.getColumnIndex()); + sheet.setColumnWidth(currentColumnIndex,columnWidth); + }); + } } } diff --git a/fesod/src/main/java/org/apache/fesod/excel/write/handler/context/CellWriteHandlerContext.java b/fesod/src/main/java/org/apache/fesod/excel/write/handler/context/CellWriteHandlerContext.java index c80232cff..8043bb834 100644 --- a/fesod/src/main/java/org/apache/fesod/excel/write/handler/context/CellWriteHandlerContext.java +++ b/fesod/src/main/java/org/apache/fesod/excel/write/handler/context/CellWriteHandlerContext.java @@ -17,9 +17,21 @@ * under the License. */ +import cn.idev.excel.context.WriteContext; +import cn.idev.excel.enums.CellDataTypeEnum; +import cn.idev.excel.metadata.Head; +import cn.idev.excel.metadata.data.WriteCellData; +import cn.idev.excel.metadata.property.ExcelContentProperty; +import cn.idev.excel.write.handler.impl.FillStyleCellWriteHandler; +import cn.idev.excel.write.metadata.fill.FillConfig; +import cn.idev.excel.write.metadata.holder.WriteSheetHolder; +import cn.idev.excel.write.metadata.holder.WriteTableHolder; +import cn.idev.excel.write.metadata.holder.WriteWorkbookHolder; package org.apache.fesod.excel.write.handler.context; import java.util.List; +import java.util.Map; + import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; @@ -43,7 +55,7 @@ @Getter @Setter @EqualsAndHashCode -public class CellWriteHandlerContext { +public class CellWriteHandlerContext implements Cloneable { /** * write context */ @@ -72,6 +84,11 @@ public class CellWriteHandlerContext { * cell */ private Cell cell; + /** + * cellMap use by DynamicColumn + * key rowIndex_columnIndex + */ + private Map cellMap; /** * index */ @@ -126,6 +143,36 @@ public class CellWriteHandlerContext { */ private Boolean ignoreFillStyle; + /** + * Fill config + */ + private FillConfig fillConfig; + /** + * Original variable + */ + private String originalVariable; + + @Override + public CellWriteHandlerContext clone() { + CellWriteHandlerContext cellWriteHandlerContext = new CellWriteHandlerContext( + this.writeContext, + this.writeWorkbookHolder, + this.writeSheetHolder, + this.writeTableHolder, + this.row, + this.rowIndex, + this.cell, + this.columnIndex, + this.relativeRowIndex, + this.headData, + this.cellDataList, + this.firstCellData, + this.head, + this.excelContentProperty + ); + return cellWriteHandlerContext; + } + public CellWriteHandlerContext( WriteContext writeContext, WriteWorkbookHolder writeWorkbookHolder, diff --git a/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/FillConfig.java b/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/FillConfig.java index f4bab8b18..96837c5e5 100644 --- a/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/FillConfig.java +++ b/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/FillConfig.java @@ -27,6 +27,8 @@ import lombok.Setter; import org.apache.fesod.excel.enums.WriteDirectionEnum; +import java.util.List; + /** * Fill config * @@ -57,6 +59,9 @@ public class FillConfig { private boolean hasInit; + private List dynamicColumnKeys; + private Integer dynamicColumnGroupSize; + public void init() { if (hasInit) { return; @@ -70,6 +75,9 @@ public void init() { if (autoStyle == null) { autoStyle = Boolean.TRUE; } + if (dynamicColumnGroupSize == null) { + dynamicColumnGroupSize = 1; + } hasInit = true; } } From 1e2cdad8291552ef7aa1d180d621ae9325e113c8 Mon Sep 17 00:00:00 2001 From: milixiang Date: Fri, 1 Aug 2025 18:30:54 +0800 Subject: [PATCH 2/9] =?UTF-8?q?refactor(fill):=20=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E5=8A=A8=E6=80=81=E5=88=97=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 DynamicColumnInfo 类封装动态列信息 - 修改 FillConfig 类,使用 Map 存储多个动态列信息 - 更新动态列相关的处理逻辑和异常提示 - 优化单元测试用例 --- .../fesod/excel/temp/fill/FillTempTest.java | 6 ++- .../executor/AbstractExcelWriteExecutor.java | 13 ++--- .../executor/ExcelWriteFillExecutor.java | 49 ++++++++++++++++--- .../metadata/fill/DynamicColumnInfo.java | 26 ++++++++++ .../excel/write/metadata/fill/FillConfig.java | 42 ++++++++++++++-- 5 files changed, 117 insertions(+), 19 deletions(-) create mode 100644 fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/DynamicColumnInfo.java diff --git a/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/FillTempTest.java b/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/FillTempTest.java index 1187b9c08..ab2a989e5 100644 --- a/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/FillTempTest.java +++ b/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/FillTempTest.java @@ -129,8 +129,10 @@ public void dynamicFill() { ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build(); WriteSheet writeSheet = EasyExcel.writerSheet().build(); - excelWriter.fill(new FillWrapper("dataList", fillDataList), FillConfig.builder().dynamicColumnKeys(dateList).forceNewRow(true).build(), writeSheet); - excelWriter.fill(new FillWrapper("dataObjList", fillDataList), FillConfig.builder().dynamicColumnGroupSize(2).dynamicColumnKeys(dateList).forceNewRow(true).build(), writeSheet); + excelWriter.fill(new FillWrapper("dataList", fillDataList), FillConfig.builder().forceNewRow(true).addDynamicInfo(dateList,1,"qtyMap") + .addDefaultDynamicInfo(dateList,1) + .build(), writeSheet); + excelWriter.fill(new FillWrapper("dataObjList", fillDataList), FillConfig.builder().addDefaultDynamicInfo(dateList,2).forceNewRow(true).build(), writeSheet); excelWriter.fill(new FillWrapper("dateListMap", dateListMap), FillConfig.builder().direction(HORIZONTAL).build(), writeSheet); // Do not forget to close the stream excelWriter.finish(); diff --git a/fesod/src/main/java/org/apache/fesod/excel/write/executor/AbstractExcelWriteExecutor.java b/fesod/src/main/java/org/apache/fesod/excel/write/executor/AbstractExcelWriteExecutor.java index 31acd1bb8..25542e04f 100644 --- a/fesod/src/main/java/org/apache/fesod/excel/write/executor/AbstractExcelWriteExecutor.java +++ b/fesod/src/main/java/org/apache/fesod/excel/write/executor/AbstractExcelWriteExecutor.java @@ -46,6 +46,7 @@ import cn.idev.excel.util.WorkBookUtil; import cn.idev.excel.util.WriteHandlerUtils; import cn.idev.excel.write.handler.context.CellWriteHandlerContext; +import cn.idev.excel.write.metadata.fill.DynamicColumnInfo; import cn.idev.excel.write.metadata.fill.FillConfig; import org.apache.commons.collections4.CollectionUtils; import org.apache.fesod.excel.context.WriteContext; @@ -180,14 +181,14 @@ protected void converterAndSet(CellWriteHandlerContext cellWriteHandlerContext) if (null != field && field.isAnnotationPresent(DynamicColumn.class)) { Map dynamicColumnMap = (Map) originalValue; FillConfig fillConfig = cellWriteHandlerContext.getFillConfig(); - if(null == fillConfig || CollectionUtils.isEmpty(fillConfig.getDynamicColumnKeys())){ - throw new ExcelWriteDataConvertException(cellWriteHandlerContext, "DynamicColumn annotation must be used with FillConfig.dynamicColumnKeys,FillConfig.dynamicColumnGroupSize"); + if(null == fillConfig || null == fillConfig.getDynamicColumnInfoMap()){ + throw new ExcelWriteDataConvertException(cellWriteHandlerContext, "DynamicColumn annotation must be used with FillConfig.dynamicColumnInfoMap"); } - List dynamicColumnKeys = fillConfig.getDynamicColumnKeys(); + DynamicColumnInfo dynamicColumnInfo = fillConfig.getDynamicColumnInfo(field.getName()); Integer columnIndex = cellWriteHandlerContext.getColumnIndex(); Integer rowIndex = cellWriteHandlerContext.getRowIndex(); - for (int i = 0; i < dynamicColumnKeys.size(); i++) { - String key = dynamicColumnKeys.get(i); + for (int i = 0; i < dynamicColumnInfo.getKeys().size(); i++) { + String key = dynamicColumnInfo.getKeys().get(i); Object o = dynamicColumnMap.get(key); String originalVariable = cellWriteHandlerContext.getOriginalVariable(); if(originalVariable.contains(".")){ @@ -197,7 +198,7 @@ protected void converterAndSet(CellWriteHandlerContext cellWriteHandlerContext) o = beanMap.get(key); } - Integer dynamicColumnGroupSize = fillConfig.getDynamicColumnGroupSize(); + Integer dynamicColumnGroupSize = dynamicColumnInfo.getGroupSize(); WriteDirectionEnum direction = fillConfig.getDirection(); int currentRowIndex = rowIndex; int currentColumnIndex = columnIndex; diff --git a/fesod/src/main/java/org/apache/fesod/excel/write/executor/ExcelWriteFillExecutor.java b/fesod/src/main/java/org/apache/fesod/excel/write/executor/ExcelWriteFillExecutor.java index 0abdcc1e6..e7b96bfdf 100644 --- a/fesod/src/main/java/org/apache/fesod/excel/write/executor/ExcelWriteFillExecutor.java +++ b/fesod/src/main/java/org/apache/fesod/excel/write/executor/ExcelWriteFillExecutor.java @@ -36,6 +36,7 @@ import cn.idev.excel.write.handler.context.CellWriteHandlerContext; import cn.idev.excel.write.handler.context.RowWriteHandlerContext; import cn.idev.excel.write.metadata.fill.AnalysisCell; +import cn.idev.excel.write.metadata.fill.DynamicColumnInfo; import cn.idev.excel.write.metadata.fill.FillConfig; import cn.idev.excel.write.metadata.fill.FillWrapper; import cn.idev.excel.write.metadata.holder.WriteSheetHolder; @@ -45,6 +46,7 @@ import java.util.ArrayList; import java.util.Collection; +import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -160,6 +162,7 @@ public void fill(Object data, FillConfig fillConfig) { if (CollectionUtils.isEmpty(collectionData)) { return; } + shiftCellsIfNecessary(fillConfig, collectionData, analysisCellList); Iterator iterator = collectionData.iterator(); if (WriteDirectionEnum.VERTICAL.equals(fillConfig.getDirection()) && fillConfig.getForceNewRow()) { shiftRows(collectionData.size(), analysisCellList); @@ -172,6 +175,40 @@ public void fill(Object data, FillConfig fillConfig) { } } + private void shiftCellsIfNecessary(FillConfig fillConfig, Collection collectionData, List analysisCellList) { + if (WriteDirectionEnum.VERTICAL.equals(fillConfig.getDirection()) && CollectionUtils.isNotEmpty(collectionData) && collectionData.size() > 1) { + Sheet sheet = writeContext.writeSheetHolder().getCachedSheet(); + Object item = collectionData.iterator().next(); + Class itemClass = item.getClass(); + Field[] declaredFields = itemClass.getDeclaredFields(); + Map dynamicFieldMap = new HashMap<>(); + for (Field declaredField : declaredFields) { + if (declaredField.isAnnotationPresent(DynamicColumn.class)) { + dynamicFieldMap.put(declaredField.getName(), declaredField); + } + } + analysisCellList.stream().sorted(Comparator.comparingInt(AnalysisCell::getColumnIndex).reversed()).forEach(analysisCell -> { + int rowIndex = analysisCell.getRowIndex(); + int columnIndex = analysisCell.getColumnIndex(); + Row row = sheet.getRow(rowIndex); + List variableList = analysisCell.getVariableList(); + for (String fieldName: dynamicFieldMap.keySet()) { + for (String variable : variableList) { + String variableFieldName = variable.split("\\.")[0]; + if (StringUtils.equals(fieldName, variableFieldName)) { + List headers = fillConfig.getDynamicColumnInfo(fieldName).getKeys(); + Integer columnGroupSize = fillConfig.getDynamicColumnInfo(fieldName).getGroupSize(); + row.shiftCellsRight(columnIndex + columnGroupSize, row.getLastCellNum(), headers.size()-1); + analysisCellList.stream().filter(ac->ac.getColumnIndex()>(columnIndex+columnGroupSize-1)).forEach(ac->{ + ac.setColumnIndex(ac.getColumnIndex()+headers.size()-1); + }); + } + } + } + }); + } + } + private void shiftRows(int size, List analysisCellList) { if (CollectionUtils.isEmpty(analysisCellList)) { return; @@ -261,7 +298,7 @@ private void doFill( Object value = null; if (dataKeySet.contains(variable)) { value = dataMap.get(variable); - }else if(variable.contains(".")){ + }else if(variable.contains(COLLECTION_PREFIX)){ variable = variable.split("\\.")[0]; value = dataMap.get(variable); } @@ -451,17 +488,17 @@ private void createCell( cellWriteHandlerContext.setCellMap(new HashMap<>()); } cellWriteHandlerContext.getCellMap().put(lastRowIndex + "_" + lastColumnIndex, cellWriteHandlerContext); - List dynamicColumnKeys = fillConfig.getDynamicColumnKeys(); - if(CollectionUtils.isEmpty(dynamicColumnKeys)){ + DynamicColumnInfo dynamicColumnInfo = fillConfig.getDynamicColumnInfo(field.getName()); + if(null == dynamicColumnInfo || CollectionUtils.isEmpty(dynamicColumnInfo.getKeys())){ throw new ExcelGenerateException(String.format("Plase set dynamic column keys for %s in fillConfig",field.getName())); } - for (int i = 1; i < dynamicColumnKeys.size(); i++) { + for (int i = 1; i < dynamicColumnInfo.getKeys().size(); i++) { switch (fillConfig.getDirection()) { case VERTICAL: - lastColumnIndex = lastColumnIndex + fillConfig.getDynamicColumnGroupSize(); + lastColumnIndex = lastColumnIndex + dynamicColumnInfo.getGroupSize(); break; case HORIZONTAL: - lastRowIndex = lastRowIndex + fillConfig.getDynamicColumnGroupSize(); + lastRowIndex = lastRowIndex + dynamicColumnInfo.getGroupSize(); break; default: throw new ExcelGenerateException("The wrong direction."); diff --git a/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/DynamicColumnInfo.java b/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/DynamicColumnInfo.java new file mode 100644 index 000000000..3603631ad --- /dev/null +++ b/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/DynamicColumnInfo.java @@ -0,0 +1,26 @@ +package cn.idev.excel.write.metadata.fill; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +public class DynamicColumnInfo { + + /** + * dynamic column keys + * */ + private List keys; + + /** + * dynamic column group size + * */ + private Integer groupSize; + +} diff --git a/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/FillConfig.java b/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/FillConfig.java index 96837c5e5..82879f9e0 100644 --- a/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/FillConfig.java +++ b/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/FillConfig.java @@ -17,6 +17,9 @@ * under the License. */ +import cn.idev.excel.annotation.fill.DynamicColumn; +import cn.idev.excel.enums.WriteDirectionEnum; +import com.sun.istack.internal.Nullable; package org.apache.fesod.excel.write.metadata.fill; import lombok.AllArgsConstructor; @@ -27,7 +30,9 @@ import lombok.Setter; import org.apache.fesod.excel.enums.WriteDirectionEnum; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * Fill config @@ -41,6 +46,7 @@ @NoArgsConstructor @AllArgsConstructor public class FillConfig { + public static final String DEFAULT_DYNAMIC_INFO_KEY = "default"; private WriteDirectionEnum direction; /** * Create a new row each time you use the list parameter.The default create if necessary. @@ -59,8 +65,18 @@ public class FillConfig { private boolean hasInit; - private List dynamicColumnKeys; - private Integer dynamicColumnGroupSize; + /** + * dynamic column info + * */ + private Map dynamicColumnInfoMap; + + public DynamicColumnInfo getDynamicColumnInfo(@Nullable String fieldName) { + if (null == fieldName || !dynamicColumnInfoMap.containsKey(fieldName)) { + return dynamicColumnInfoMap.get(DEFAULT_DYNAMIC_INFO_KEY); + }else{ + return dynamicColumnInfoMap.get(fieldName); + } + } public void init() { if (hasInit) { @@ -75,9 +91,25 @@ public void init() { if (autoStyle == null) { autoStyle = Boolean.TRUE; } - if (dynamicColumnGroupSize == null) { - dynamicColumnGroupSize = 1; - } hasInit = true; } + + public static class FillConfigBuilder { + public FillConfigBuilder addDynamicInfo(List keys, Integer groupSize, String fieldName) { + if (null == dynamicColumnInfoMap) { + dynamicColumnInfoMap = new HashMap<>(); + } + dynamicColumnInfoMap.put(fieldName, new DynamicColumnInfo(keys, groupSize)); + return this; + } + + public FillConfigBuilder addDefaultDynamicInfo(List keys) { + return addDynamicInfo(keys, 1, DEFAULT_DYNAMIC_INFO_KEY); + } + + public FillConfigBuilder addDefaultDynamicInfo(List keys, Integer groupSize) { + return addDynamicInfo(keys, groupSize, DEFAULT_DYNAMIC_INFO_KEY); + } + + } } From 2fe3694954e123b269900fafa6f63e9dd67e5bc5 Mon Sep 17 00:00:00 2001 From: milixiang Date: Mon, 4 Aug 2025 11:34:47 +0800 Subject: [PATCH 3/9] =?UTF-8?q?feat(write):=20=E5=A2=9E=E5=8A=A0=E8=87=AA?= =?UTF-8?q?=E5=BC=95=E7=94=A8=E5=8F=98=E9=87=8F=E6=9B=BF=E6=8D=A2=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增自引用变量标识符 "$" - 在单元格填充时,如果变量为自引用标识符,则使用当前行数据进行替换 - 优化了变量替换逻辑,增加了对自引用变量的处理 --- .../apache/fesod/excel/temp/fill/FillTempTest.java | 13 +------------ .../write/executor/ExcelWriteFillExecutor.java | 9 +++++++-- .../fesod/excel/write/metadata/fill/FillConfig.java | 11 ++++++++++- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/FillTempTest.java b/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/FillTempTest.java index ab2a989e5..27f232279 100644 --- a/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/FillTempTest.java +++ b/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/FillTempTest.java @@ -111,17 +111,6 @@ public void dynamicFill() { fillDataList.add(fillData1); fillDataList.add(fillData2); - ArrayList dateListMap = new ArrayList<>(); - HashMap date1 = new HashMap<>(); - date1.put("date", "2023-01-01"); - dateListMap.add(date1); - HashMap date2 = new HashMap<>(); - date2.put("date", "2023-01-02"); - dateListMap.add(date2); - HashMap date3 = new HashMap<>(); - date3.put("date", "2023-01-03"); - dateListMap.add(date3); - ArrayList dateList = new ArrayList<>(); dateList.add("2023-01-01"); dateList.add("2023-01-02"); @@ -133,7 +122,7 @@ public void dynamicFill() { .addDefaultDynamicInfo(dateList,1) .build(), writeSheet); excelWriter.fill(new FillWrapper("dataObjList", fillDataList), FillConfig.builder().addDefaultDynamicInfo(dateList,2).forceNewRow(true).build(), writeSheet); - excelWriter.fill(new FillWrapper("dateListMap", dateListMap), FillConfig.builder().direction(HORIZONTAL).build(), writeSheet); + excelWriter.fill(new FillWrapper("dateList", dateList), FillConfig.builder().direction(HORIZONTAL).build(), writeSheet); // Do not forget to close the stream excelWriter.finish(); diff --git a/fesod/src/main/java/org/apache/fesod/excel/write/executor/ExcelWriteFillExecutor.java b/fesod/src/main/java/org/apache/fesod/excel/write/executor/ExcelWriteFillExecutor.java index e7b96bfdf..08220da3f 100644 --- a/fesod/src/main/java/org/apache/fesod/excel/write/executor/ExcelWriteFillExecutor.java +++ b/fesod/src/main/java/org/apache/fesod/excel/write/executor/ExcelWriteFillExecutor.java @@ -100,6 +100,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { private static final String FILL_SUFFIX = "}"; private static final char IGNORE_CHAR = '\\'; private static final String COLLECTION_PREFIX = "."; + private static final String FILL_VARIABLE_SELF = "$"; /** * Fields to replace in the template */ @@ -296,7 +297,9 @@ private void doFill( String originalVariable = analysisCell.getVariableList().get(0); String variable = originalVariable; Object value = null; - if (dataKeySet.contains(variable)) { + if (FILL_VARIABLE_SELF.equals(variable)) { + value = oneRowData; + }else if (dataKeySet.contains(variable)) { value = dataMap.get(variable); }else if(variable.contains(COLLECTION_PREFIX)){ variable = variable.split("\\.")[0]; @@ -346,7 +349,9 @@ private void doFill( for (String variable : analysisCell.getVariableList()) { cellValueBuild.append(analysisCell.getPrepareDataList().get(index++)); Object value = null; - if (dataKeySet.contains(variable)) { + if (FILL_VARIABLE_SELF.equals(variable)) { + value = oneRowData; + }else if (dataKeySet.contains(variable)) { value = dataMap.get(variable); } ExcelContentProperty excelContentProperty = ClassUtils.declaredExcelContentProperty( diff --git a/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/FillConfig.java b/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/FillConfig.java index 82879f9e0..75a15c5b7 100644 --- a/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/FillConfig.java +++ b/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/FillConfig.java @@ -70,7 +70,16 @@ public class FillConfig { * */ private Map dynamicColumnInfoMap; - public DynamicColumnInfo getDynamicColumnInfo(@Nullable String fieldName) { + /** + * get dynamic column info + * + * if field name is null or not exist, return default dynamic column info + * else return dynamic column info by field name + * + * @param fieldName field name nullable + * @return dynamic column info + * */ + public DynamicColumnInfo getDynamicColumnInfo(String fieldName) { if (null == fieldName || !dynamicColumnInfoMap.containsKey(fieldName)) { return dynamicColumnInfoMap.get(DEFAULT_DYNAMIC_INFO_KEY); }else{ From e8863d30a56b50fc2d582a556a15bf21ecc84ff5 Mon Sep 17 00:00:00 2001 From: milixiang Date: Tue, 12 Aug 2025 17:45:26 +0800 Subject: [PATCH 4/9] =?UTF-8?q?fix:=20=E5=88=A0=E9=99=A4=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E9=80=BB=E8=BE=91=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../write/executor/AbstractExcelWriteExecutor.java | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/fesod/src/main/java/org/apache/fesod/excel/write/executor/AbstractExcelWriteExecutor.java b/fesod/src/main/java/org/apache/fesod/excel/write/executor/AbstractExcelWriteExecutor.java index 25542e04f..e0e6b2fcd 100644 --- a/fesod/src/main/java/org/apache/fesod/excel/write/executor/AbstractExcelWriteExecutor.java +++ b/fesod/src/main/java/org/apache/fesod/excel/write/executor/AbstractExcelWriteExecutor.java @@ -128,17 +128,8 @@ protected void convertAndSetItem(CellWriteHandlerContext cellWriteHandlerContext if (cellData.getType() == null) { cellData.setType(CellDataTypeEnum.EMPTY); } - if (null != cellWriteHandlerContext.getCellMap() && cellWriteHandlerContext.getCellMap().size() > 1) { - cellWriteHandlerContext.getCellMap().forEach((k,cell) -> { - String[] split = k.split("_"); - int rowIndex = Integer.parseInt(split[0]); - int columnIndex = Integer.parseInt(split[1]); - setCellValue(cell, cellData, cell.getCell()); - }); - }else{ - Cell cell = cellWriteHandlerContext.getCell(); - setCellValue(cellWriteHandlerContext, cellData, cell); - } + Cell cell = cellWriteHandlerContext.getCell(); + setCellValue(cellWriteHandlerContext, cellData, cell); } private void setCellValue(CellWriteHandlerContext cellWriteHandlerContext, WriteCellData cellData, Cell cell) { From 68dbedde885464442107c60f14429e52d03d08c2 Mon Sep 17 00:00:00 2001 From: milixiang Date: Thu, 14 Aug 2025 18:35:51 +0800 Subject: [PATCH 5/9] =?UTF-8?q?fix:=20=E6=A8=AA=E5=90=91=E5=A1=AB=E5=85=85?= =?UTF-8?q?=20=E5=A4=8D=E5=88=B6=E5=88=97=E5=AE=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/apache/fesod/excel/temp/fill/FillTempTest.java | 9 +++++++++ .../excel/write/executor/AbstractExcelWriteExecutor.java | 8 ++++++-- .../excel/write/executor/ExcelWriteFillExecutor.java | 6 ++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/FillTempTest.java b/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/FillTempTest.java index 27f232279..c6232c183 100644 --- a/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/FillTempTest.java +++ b/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/FillTempTest.java @@ -115,6 +115,15 @@ public void dynamicFill() { dateList.add("2023-01-01"); dateList.add("2023-01-02"); dateList.add("2023-01-03"); + dateList.add("2023-01-04"); + dateList.add("2023-01-05"); + dateList.add("2023-01-06"); + dateList.add("2023-01-07"); + dateList.add("2023-01-08"); + dateList.add("2023-01-09"); + dateList.add("2023-01-10"); + dateList.add("2023-01-11"); + dateList.add("2023-01-12"); ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build(); WriteSheet writeSheet = EasyExcel.writerSheet().build(); diff --git a/fesod/src/main/java/org/apache/fesod/excel/write/executor/AbstractExcelWriteExecutor.java b/fesod/src/main/java/org/apache/fesod/excel/write/executor/AbstractExcelWriteExecutor.java index e0e6b2fcd..f34ac6417 100644 --- a/fesod/src/main/java/org/apache/fesod/excel/write/executor/AbstractExcelWriteExecutor.java +++ b/fesod/src/main/java/org/apache/fesod/excel/write/executor/AbstractExcelWriteExecutor.java @@ -185,8 +185,12 @@ protected void converterAndSet(CellWriteHandlerContext cellWriteHandlerContext) if(originalVariable.contains(".")){ key = originalVariable.split("\\.")[1]; Object itemBean = o; - BeanMap beanMap = BeanMapUtils.create(itemBean); - o = beanMap.get(key); + if (null == itemBean) { + o = null; + }else{ + BeanMap beanMap = BeanMapUtils.create(itemBean); + o = beanMap.get(key); + } } Integer dynamicColumnGroupSize = dynamicColumnInfo.getGroupSize(); diff --git a/fesod/src/main/java/org/apache/fesod/excel/write/executor/ExcelWriteFillExecutor.java b/fesod/src/main/java/org/apache/fesod/excel/write/executor/ExcelWriteFillExecutor.java index 08220da3f..82667ad65 100644 --- a/fesod/src/main/java/org/apache/fesod/excel/write/executor/ExcelWriteFillExecutor.java +++ b/fesod/src/main/java/org/apache/fesod/excel/write/executor/ExcelWriteFillExecutor.java @@ -331,6 +331,12 @@ private void doFill( if (cellWriteHandlerContext.getCellMap() != null && cellWriteHandlerContext.getCellMap().size() > 1) { cellWriteHandlerContext.getCellMap().values().forEach(cell -> cell.getFirstCellData().setOriginCellStyle(style)); }else{ + if(fillConfig.getDirection() == WriteDirectionEnum.HORIZONTAL){ + Integer orginColumnIndex = analysisCell.getColumnIndex(); + Sheet sheet = writeContext.writeSheetHolder().getSheet(); + int columnWidth = sheet.getColumnWidth(orginColumnIndex); + sheet.setColumnWidth(cellWriteHandlerContext.getColumnIndex(), columnWidth); + } cellData.setOriginCellStyle(style); } }); From 2fb9bc7c6678050e59a6c0f86422e5efb736cf4e Mon Sep 17 00:00:00 2001 From: milixiang Date: Sun, 28 Sep 2025 18:11:11 +0800 Subject: [PATCH 6/9] fix: fix merge conflicts --- .../excel/temp/fill/DynamicFillData.java | 17 +++++ .../excel/temp/fill/DynamicFillDataObj.java | 16 +++++ .../fesod/excel/temp/fill/FillTempTest.java | 19 +++--- .../test/resources/fill/dynamicColumn.xlsx | Bin 0 -> 10151 bytes .../test/resources/fill/dynamicColumnObj.xlsx | Bin 0 -> 9794 bytes .../excel/annotation/fill/DynamicColumn.java | 2 +- .../executor/AbstractExcelWriteExecutor.java | 34 ++-------- .../executor/ExcelWriteFillExecutor.java | 62 ++++++------------ .../context/CellWriteHandlerContext.java | 17 ++--- .../metadata/fill/DynamicColumnInfo.java | 2 +- .../excel/write/metadata/fill/FillConfig.java | 3 - 11 files changed, 74 insertions(+), 98 deletions(-) create mode 100644 fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/DynamicFillData.java create mode 100644 fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/DynamicFillDataObj.java create mode 100644 fesod-examples/src/test/resources/fill/dynamicColumn.xlsx create mode 100644 fesod-examples/src/test/resources/fill/dynamicColumnObj.xlsx rename {fastexcel/src/main/java/cn/idev => fesod/src/main/java/org/apache/fesod}/excel/annotation/fill/DynamicColumn.java (86%) diff --git a/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/DynamicFillData.java b/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/DynamicFillData.java new file mode 100644 index 000000000..917b1f55d --- /dev/null +++ b/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/DynamicFillData.java @@ -0,0 +1,17 @@ +package org.apache.fesod.excel.temp.fill; + +import lombok.Data; +import org.apache.fesod.excel.annotation.fill.DynamicColumn; + +import java.util.Map; + +@Data +public class DynamicFillData { + private String name; + private double number; + @DynamicColumn() + private Map qtyMap; + + @DynamicColumn() + private Map priceMap; +} diff --git a/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/DynamicFillDataObj.java b/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/DynamicFillDataObj.java new file mode 100644 index 000000000..77b65244a --- /dev/null +++ b/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/DynamicFillDataObj.java @@ -0,0 +1,16 @@ +package org.apache.fesod.excel.temp.fill; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +@AllArgsConstructor +@Getter +@Setter +public class DynamicFillDataObj { + + private String qty; + private double price; + + +} \ No newline at end of file diff --git a/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/FillTempTest.java b/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/FillTempTest.java index c6232c183..9027d56bf 100644 --- a/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/FillTempTest.java +++ b/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/FillTempTest.java @@ -19,12 +19,6 @@ package org.apache.fesod.excel.temp.fill; -import java.io.File; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; import org.apache.fesod.excel.ExcelWriter; import org.apache.fesod.excel.FastExcel; import org.apache.fesod.excel.demo.fill.FillData; @@ -35,7 +29,12 @@ import org.apache.fesod.excel.write.metadata.fill.FillWrapper; import org.junit.jupiter.api.Test; -import static cn.idev.excel.enums.WriteDirectionEnum.HORIZONTAL; +import java.io.File; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * Example of filling data into Excel templates. @@ -125,13 +124,13 @@ public void dynamicFill() { dateList.add("2023-01-11"); dateList.add("2023-01-12"); - ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build(); - WriteSheet writeSheet = EasyExcel.writerSheet().build(); + ExcelWriter excelWriter = FastExcel.write(fileName).withTemplate(templateFileName).build(); + WriteSheet writeSheet = FastExcel.writerSheet().build(); excelWriter.fill(new FillWrapper("dataList", fillDataList), FillConfig.builder().forceNewRow(true).addDynamicInfo(dateList,1,"qtyMap") .addDefaultDynamicInfo(dateList,1) .build(), writeSheet); excelWriter.fill(new FillWrapper("dataObjList", fillDataList), FillConfig.builder().addDefaultDynamicInfo(dateList,2).forceNewRow(true).build(), writeSheet); - excelWriter.fill(new FillWrapper("dateList", dateList), FillConfig.builder().direction(HORIZONTAL).build(), writeSheet); + excelWriter.fill(new FillWrapper("dateList", dateList), FillConfig.builder().direction(WriteDirectionEnum.HORIZONTAL).build(), writeSheet); // Do not forget to close the stream excelWriter.finish(); diff --git a/fesod-examples/src/test/resources/fill/dynamicColumn.xlsx b/fesod-examples/src/test/resources/fill/dynamicColumn.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..f65306048c09cf6a1a9eab2dea58b8624df38d8b GIT binary patch literal 10151 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 T<7Gtyb<4njy!Z{-livRU_+Xxx literal 0 HcmV?d00001 diff --git a/fesod-examples/src/test/resources/fill/dynamicColumnObj.xlsx b/fesod-examples/src/test/resources/fill/dynamicColumnObj.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..12ba8bcbdab9a45cf8bb4681886feaa8ef714170 GIT binary patch literal 9794 zcmaJ{1ymi&vc)Ah9D=*M6Ck*|ySux)y9Ot?6Wjv9gS!WJ2tk6o!-wSFo80{OUaxg# z=FC)eb?>gOmff-vpkM$X5FjX^fOni4A5PRARDgki;J|@^P=J7dGz4s{9gVCVbrjuf zjU2RSU9Bw36Naoi=@Esl5^oV=KPl<&U@zDF4#7QIIW*;j^}U%kzr@S)n{|{FIHC_ z%v5PvCK1z>GmOco(o5v;F|{ZU-Lu~vp%ZT-04&X$SCtU0RPpxnKudk|X)ipA5{Wkl zomVAsSBh4e1mlt>$Tjq;Ui}u6qQ_CrQq|XKCjl&l4@w$i2_0rWXS6ajL(s8%d=Qy> z7#{|czc$KkYvMrcX+)w->E~9|{RVlg&_FU9RvBp1@}%od7G7PW!PR%>9O(UZp8w%I zPul7NHjsA^^AoI|_len=I-AlR(RDexQS&(+w&C{Y5rW06`C}~E=XQAYj5rWbi1Y^U z%l+>J@%*4;Z)E8}_agJFtvuMATW+4et%3jn!Tcjb`yyE$CnW*OfEaw_|D^Zc6_O_0EIE_u9mWFe4Dw; zw&~+0x71~USg_WfST3_UIe#TDuR6~hBoc&z3WVZ*Ko+wj;W}TjA%}g6IQ-_BSl2|( zrjex*FO#l>xtx*<<)b05S3C8LvVi6yJ0MLf+hJ~rxiv?GRYOEOTJwY|b^u)i8Scvm zZZ>$EVS)EK+0o5Q=|`tmZxf05BK!w!^VLG#IK;C&9%ia7GtZnC$fTiZXw~4Q_*de% z$^!|~8Jk-3W9Lcru4IJnhLhtsu9Ggv{yU1$&j=aX7|7b&*!~S9(6iIOfZhCNzLNgg z>6xE_MEqS$&(`+E<1=DA#6cMVLRbDzh&47$G=%bu6#k)aA=RC5m~0l>C6VK{$8Tw9 z9SN=>tQFVcW=q`kayT`vcX!2}6ICEaw4+A)p0@i3o)n!e&pl?~VxeGScA$Bkw7Q`zHI_8#oCdc;{z|S`xZcYv^Xld7} zZ+FX+yLM#vKpA#H<@O<({kxH(v^ooVF+1IqL}Pq_WP;nd1UjYIB3OV5GX&ZmHyUm{IwE)kq^SI55&FC$I_ zauOmT4(Hvc_E=EwjyA%Yq-BRk`-;sbh9%$O|84lm`^;q1vrR$i9DZg%9gSQHDxCLB zU9^>A{Hr;VPENmDA$X}d9QZ*;-LT76^oGM+1kY7H|w?bZxBe3G1C zE0^lGN6&EzqM|r&n@;JF27~&wR<;HgY53kkvpD0)9;h3I`<51u9p$J3YnvY6#KyG* z4c)f-f;e{E#DiVRt$RjIHyS?8qoK-}G3+O6NYUg*GQUv%R|_WGlrr&Yi_;*97z4EW zj1gbv!!;)@g`wTdiZWYl6fWSLQXUXC0?R~&ixg6&M7oKx_wBPD15bZMk6)1itJ%;Z z>ltzu(4SHKAHO$na&WY^5{@RNxfCpiogPIjQ}L+gTi~%iw?*=CH>}h zbCyab?LqbHH9~dWqJ&QRMvxRXIN_JM!-+_!W z(TYP27nE{m-r;Yyf3&D8+uwQv-*Q~o`lw+@`lVE>SxpPGD-Djiwq+I?jjGZy_GZmQ zu!}r5bb;77CkhGPl2soCs}U;JHxRlxCd+qPGYz`RT>JffR_6%SG1|x3FE#9+)JF(6 zmqIEcmRvh~^&;P+kRJ9!caqzoFs)(r;(A*6*!jOH_E~3ZVjsn8OTAZ1{+>-WXh}46 zHwY%DZ@|c0$xWQ1cbf&?_ol6 zMnbdOy%8Lq%b~Sf(%G0e*$0g;k8cl>C(N?wWNrC9b4NXpEZKQXN-Uw=*o19mWQx8( zHfUScQLna@l8u{g2fpw-*>%9VKmSq z=Y5|lZ3*n~^RaBeY#>^%Mno5v$Jj#YB&Q%Nvnj<9cciLXj{u&`l`b;)p>?0!p>R

;Oh=RZFJc9qPx9Lt`b;PW*sxhp33A6WSo7r^l8WQy(gF@;tp`u#3JV~o zOfvOtQ1e^8fF>jv$exaH7V6(zBM)zfX3`0YZkY9hh6)$Kt94}2G7|LaCBW$?I1T%%O33aKO@F%IH~snF;VK6- zP=5Fs8_(zd1Ne!NgQ=dqk)eX4y_vO%!;gsdZbTfM0XFE$|46pRg`-I}w%&!HVKRf8 zH$BYd)t8T-213zJmJhB$3GMA%MhB9yLl;}}=Q$M;Q|7zOW&;RtPto1>*4H1mHjyLA zPeUDyPpioMq}aIa3C$O1BSOULG}WlO1fdItf*PbU?WI19%#U|f{p18wZ zi3_6M;b&KDmtD6la1Xh(`v_^gc-8s#-?gU=29{fg1p+$Lf1U&WReMJ_OQRpvUe;Q) z!BWHU5!vuTZ}f)@v>0>sd~X>S$A)26@JcBkpO|-g4wsCm7x&0@i8Ml)(osTBE>_mB z)0`wpEAf;UlsdFL$?7VrczH9-$L}b;G5yGOR5P{r(l9N=y?49$Y4m1vc~1o%vflBF zV_y=}68S)KDain~b4Di1(ki*vRg<=LVt%y=tVi$x>`2sPEIX~%{QY;8nZA`+t3#ZW zLNefpb=N${HMhJvaib+JddS}E8Yae&W2sd;$Y98rLvJHad#SuPq=KN$xr(JxgY8wp zBw1Yx*=ZpI?Y2Ig7>UiJx`wXGeKj;kp{JB$0f!4|cLIGZ9IPMQcgzV)uF(y+s+ua8 zoNrf*bd~IGy-F>5nG>*3XIspWj!X+iF4hgR5n8IJoJa+1^74f%iJ#KmcpS^qinUEx z6+xOWy=x=Ty4@;}n8upK+B`!Ty58Nhk-|QTs(HerIVs1IFGddU^h|VXLrz59NfjXh(uD4lh?|6WrT=E+HA?bFncGs{Xy*wog{f zvolqEWr7kp0b3PF^|WSVC?#G|E0x$VzIknDu7%m@G+AO(ZMc+fp#`2b zrYX8~V|!mx8q?l*JUhMiBS3NHJaxsAn%c7eV|E;hUtP~SF|F*X`QfHz|0sy0AMd1V zW@!+`iAJVVWx}4lJ7W+14&LB4Ry{yZ9gDG}amHU!FY0!K2BuR8H1>Um4w2?I49o%o zra8se&)3rBx#`8`q1b}GgRN7;18a+jUOmM+;xR&l+wb2B3(aU6C(P@Z z>qzOEMti=^^0g^jn8ATheW1k@u)ASFTrHc`a8grHbenKudiR-_X|G^97-K+3EG70n zG4Q=})$5cF5M~x-Y-3^{5(E0_9 z|ERi&X#uI0tC{`C2V=lzg#HUK4Q$Ta=*55nE(+C(xKeu0i&d+NMdQ@~zEX<=ymwDr zCW66L(c2yRb6f6XjF%ZXdR=|uqDYT2AE(RzvGD;VWbIHFq}gr>#w1ej-3^z=LPJJhk(|aNI}Tq z=P~%;1{&R zWv#)uXkjG`_hcpXPk+9v)Kzaw>O%8$8X$^w%Z|4gPIey*6CcZ>EEjx0RN+fMIADiCp?SwqA*HbQkeAlDGC`@!G3VEa0 z^aMs(Rb-VaJ%6VB0n)>1#EG+ZZ(@X*c(JXf#PO*sNEWq;YQBRqSYbCh9cEoI(fYIz zu_Sj;{Cjdk&F#t4rQtY(R>mQifm2Y~T2&E=B5giHu`!y2!4$s#X&E0_`*b}1jEE6}Hq(MpxqB*RUFs5~5yMuFbpoMpJ^pf}IKDtpq-1-9CW!ny{dFN!$EwzOJVILrSOl zzy-mp0+ML9*<$jtq@a-)Y+9H!{OTlPIMmOr#F#ojG!bbYvL3~NH&?npAE7;V=|E_o z-`aLRU#gONM!3+EpD&_A>UItY;jVDpXv{xlZM#)6Jt$q3R&?@2hR#Nq%10$a9%^a7 zpsa$GK9Q$rQm=dUuj2XM3|$qeLSYX4h|YK-B6ZRO$}*9AlXf_h^$Bpse)@? zHAPyK@dbb%bcRI~P^Q)|0~d>Mhi@ruc;}cunw-F5sY@xn}-w z)9W{5@}a}D8Se8uX~_{XJA9K|Dz}&W>9v+(5eLdpFjs>&TriwCga4h2HfJ->L(iDZ z>XVfy1S>wHyQNp={^n{-k&F)}G9ooS`?=>dXU7l^HzYyrXA%C;S#&rqYGxTGp{9rI z+dNs!-M38Q?vI9p0+0U{hh3y-;31FOJp=ih=7*GIVH0r-E3Hrjopiu7L=9B1 z6F`^--#^z|Jo_wEGL9NngBQ&9Rj8|LdwN@Y1TYc+F4WcYT4Zx8!0Gh9wBzGlat z+W$R-A2z@JQLX5!7%2412+`=L`_pSZ!A=7Z>k6cI!`y9LcVF^$A6BJ~R^EGEy9o|` z1rhEAQO7%FQ0K7g)U1TsJKxW`GXC_06`og%9x51Gyqjkt=Z1?Mj)?q4CMNIHGa?6S z!q)xHgf5diOw^T{oS#~f=V^Zv&jsk~7cvAHp4+v}QxO$F9CF=@kK0S2{StQ)L*a1n8Mbd#W`$Mxv2bfy2#ir$JLisR)TKg~UIaPql?d#? zRm0S0Fk{pj#HD=af4nu;Qz-D2`k~WU6{XrvIzfemWeW;lM`?)zuI-m{eG|My9@1X; ziXm+WwKur0jI!JEr*sKoW0x`;l} z3R?fva0=ICl@6)!I(m1I9l{Oo73(%Hw&6uMv7444fslLfXciRoDP56w9wrZ8lB<29 zW-XIj{foiX9k|N5UhQkCZ)5d#Az!zog9X?9dW-oHYy`naiTb^HOwsfB6dmh zIHM?0cQlT@GVmYO*MG`j(2N}qQhcDdY@^cdx*t!z;eAL&e4M-{uIA8N8?UFT-V7&9 z`5+^CrfKD53O=>!h$vicg4-R}S=>%-n9+?(-Qs_PLiK)~TcS-}+Gq?+J3sit$ykQ7 zd}BWU#n8qM=fx$pHensa?J{noVmhu~)Yg<9=QPt@Z}(+|h>mr_+_psp^c$X8YfGmA zdpOt)|H;|1v}h4EtAsg|&mWN!dkF)eHvuz5o$;B4Fti@NCs0f7ZLHO6^anEE7e<}) z3O)`wDJcwnKOD7oE0wcKES;{e*O)DBDx6yJs|I7TpAEJsUk@x7sZ?%pTAL$HgcrW< zqT_Ivr1SxrZAm+HN!O6G<1m(@JY*ji>MYnrWG{AHweQnjtR@3(VCNnWh98NCvLsT@ zj4q8EQ~=H%&D>TeVv6GnaV%zTlXo!mo=u(5ql2`Qg76dEwbdLjZdS71 zxs_J4n#KH9?yNy;(X3I^M)XPj;!;^%_p6`(d-Hy4NiAHcYSDpWKdDp0mFv+)<~zU3 zqEdYQ_X)A|NUSke!?(>NaCIWY#DaX9?;7lQc?*;`>-D>@V@G_Mu!TUM9QV^iL#9r za&>xoxT?tJ!uSdXiJukDH3elrQQMkQCHqIxrfV$26Wco?#D| zc19MQq!*O~F+a*Y?|cXvg$M5`2AJ!Ly2+SzQ?*Zg%;%11G?l|mCtQHyy9&*?I040g z06;_IVd~}ktdBk>;(Sbok!$3eiQD_GLz@f}S!l#XmIWIwMwMt@;4Hf{3q(0Z{|$l#Xb9|{W5YZcwYlCtk2UDiwa<%q>F``v>3Orbtn5r{*igNYa-ORzvLboJj_ z2M6n0iAte`5|F*O48${rdZkxAr>*-!C8C~1`<|i9Gk2Oea zI7`NG!+p!!3y&6cJ16)D`o{oVl zM-JcCU+QzmcQc(`u-W;WmaZp1#9GeXDvFEO}`-I4GF|y2G9KSG19Z(_W zNvXl$Jj|Ixo@nZ?Kn;2kCB<;*>Jo!UR?%nJ|6bPsV~L0l1<6MA)^H8cjKWbAxqoQM z1V4WvY~&;(d*H*^9xJy~tSn-vd*qS9_rMd(RI!9>#Y;K<17AD>jJwGFk(=>er@%l- z8G0i=lfa9ERG_p$vFJ)Ly;c#Zg5N?pIg~+h{~E_9i57F z$cUF0T1H@x7MzJV*Sa-0L#RgFQ4W3Pau-dLGIc+MUyyv)3h|!J>H5?rU{mtVr;UzI zgTc|P4ug5os`W?BxzAHcCTM z!dYe{zFshFgs!NPDM$_p>*&5MSG5wAJW~cg?zqlC_oguJVp_$d;V_3hZG+r6UNwlfh20`ETL>2b zCBGiMpc)Z&mme%{JnRPXlri`Ow59lr}@nepck_fu_PZH5_C@1_W|3%=Lz(6?m+7M)$Q&3I=LPP}HPd;M;XH3Cpswh#pUC@PL+maq3V_fMcbR>2qMF*L_ zCKAv}(HAg6Bi&_Io$)W#R{2a)+5~r`jT**=4#>(7A=ZO(*$%TBKsL-yxp|&;|>g9AsI1pPAzmW-u zzg&W^-(El3mgP`DT5`H-K$!X~D@=|(Z8?izIIP*e1O7p*hO0Q?38O^gFG%2VeU^s7 z67I``78NNPZ?}f4cBrX}X?9akht~BOmOGt?N`yl7EpL=V+@4H4R$k{B=BYJ0jeA2z)Vgu$E6Z{}bpk5%alu&bE z#y9|8M(S*s7G$>Ila+zEVD=@U=q%&&-QnR|4`&Zrm~)(beSeWTtOj&o8KK^5f=;@{ z?)Uon%-=9*z(Sy&fP!qc@py*K33RUbTL=Z(l>%ebRR{g>Mx zeGms3nL^@C2FGYR3`|I{TVf2XK?v!0Na~c&FG6mx79$2Ird>|QDwP-vT}tIpnZVug zX%+JgLeI72h|nT(W_>I3)hY$fRk{$BVA^eL|Bx+S$yi7baopdK8~n*PCYDp_Bn)+n z6}?eFa!W-mGvBU^`z=JBdxQqsbfih{BiO#}l<;|4*wLcqDg3IV%_(Mt>z9ez#8IZZ zs>>AsiwOp!!@H~Zv-FN;6f~1$VP$5%e%tV%5x%wFvQ5=H#A<;)y^qY!A|2xxWZD~% zt?f=5u8hw2MvSL6E#H<0WxSngGHDFFmFgCq2jnRd`Y-TNNz9VZXWLpS%xe6;$1{(a za$C&vV@c6YSkT*mCQm$(BU&dpCrDgA`HpR2ppB!X@4JH>;m$5P$?SKT-yJwiqP3{@ z4GH<&>({DzE?2ZUlJxU{lNfJr**T?=Este9LHzew1^h2Ba4LFAy z;u7*}she}c!-55a6Ww4!DkwYjif-iiz7mE34`6@)RA+kd{-D4UMaN7vq&4#*lK60A zpgoz6_MD<4s=mpdVm4gZELm%1qFF2}TnDjLKS_V$2yiH4dPNPj#FJUE zH(60fVdIWU6mUuc{)tPyXgZo*n03zSnK0m=> zXZZw2Yzs*e{YvZ}YQN6=vRwv!kkbXoRk$~Ut>bn6c{iKT=R3?cARNlb*=_R}J=07{ zdH$a0Nvpbh5^)u@O;)YZiUIaVB^NwCZ1WKNEsEZY39*TG6E?r@u55d3fn5LLR-g(J z$&cK6ts z!(o+gN*Bwb4w11fj*N%yMUpFDn{r%rtl6;%yrmYFNwbua*`Yf^Lg2Ou?=K3q64Vs{ z?XwJ@6B0armz&OqvelA1AOcf^elk+ziI5!H1E`LIa&#JZ|}hfP%-taToLurjNF-u!;91W%;sOz*oQ+uE2QA z)v?Rc{WGHr48rqFhy1r=BG0}F1Pp}#a(hny;n2uS1^}S{Ojx~~Z}^#B$oJ6a2>Ca6 z^>3qpo_BcB`DwK5ADtiM)&DZ~GLiq8UW|=CcdmcP(VuEBoX>wg7Vx6>)857JYJVLP z_*45&+WVKb0@!ax|0cm-)PG0#PYU;!dhc^E_@~Uj2;Kix=@-uMXL_l0669YD;(u?F zf1~v2r^2sR0sLUbexmdzr}$#$CrT^7tNlLG{nkjo(EgKm`;`yKb7`I<-~VIb{zUvw z?&?<#FOK(;!#_;c{{rjZb%#a!q5Aj2?*+17W&U&N_sb&F?`ppmf`1nI&ndyL3^Z|m z*!>;0|5fOhk>qE3X<>c5f0X|jSN>h{KS!1q-Jh)%{r_}-jWe collecti Object item = collectionData.iterator().next(); Class itemClass = item.getClass(); Field[] declaredFields = itemClass.getDeclaredFields(); - Map dynamicFieldMap = new HashMap<>(); + Map dynamicFieldMap = new HashMap<>(); for (Field declaredField : declaredFields) { if (declaredField.isAnnotationPresent(DynamicColumn.class)) { dynamicFieldMap.put(declaredField.getName(), declaredField); @@ -193,15 +171,15 @@ private void shiftCellsIfNecessary(FillConfig fillConfig, Collection collecti int columnIndex = analysisCell.getColumnIndex(); Row row = sheet.getRow(rowIndex); List variableList = analysisCell.getVariableList(); - for (String fieldName: dynamicFieldMap.keySet()) { + for (String fieldName : dynamicFieldMap.keySet()) { for (String variable : variableList) { String variableFieldName = variable.split("\\.")[0]; if (StringUtils.equals(fieldName, variableFieldName)) { List headers = fillConfig.getDynamicColumnInfo(fieldName).getKeys(); Integer columnGroupSize = fillConfig.getDynamicColumnInfo(fieldName).getGroupSize(); - row.shiftCellsRight(columnIndex + columnGroupSize, row.getLastCellNum(), headers.size()-1); - analysisCellList.stream().filter(ac->ac.getColumnIndex()>(columnIndex+columnGroupSize-1)).forEach(ac->{ - ac.setColumnIndex(ac.getColumnIndex()+headers.size()-1); + row.shiftCellsRight(columnIndex + columnGroupSize, row.getLastCellNum(), headers.size() - 1); + analysisCellList.stream().filter(ac -> ac.getColumnIndex() > (columnIndex + columnGroupSize - 1)).forEach(ac -> { + ac.setColumnIndex(ac.getColumnIndex() + headers.size() - 1); }); } } @@ -299,9 +277,9 @@ private void doFill( Object value = null; if (FILL_VARIABLE_SELF.equals(variable)) { value = oneRowData; - }else if (dataKeySet.contains(variable)) { + } else if (dataKeySet.contains(variable)) { value = dataMap.get(variable); - }else if(variable.contains(COLLECTION_PREFIX)){ + } else if (variable.contains(COLLECTION_PREFIX)) { variable = variable.split("\\.")[0]; value = dataMap.get(variable); } @@ -330,8 +308,8 @@ private void doFill( .ifPresent(style -> { if (cellWriteHandlerContext.getCellMap() != null && cellWriteHandlerContext.getCellMap().size() > 1) { cellWriteHandlerContext.getCellMap().values().forEach(cell -> cell.getFirstCellData().setOriginCellStyle(style)); - }else{ - if(fillConfig.getDirection() == WriteDirectionEnum.HORIZONTAL){ + } else { + if (fillConfig.getDirection() == WriteDirectionEnum.HORIZONTAL) { Integer orginColumnIndex = analysisCell.getColumnIndex(); Sheet sheet = writeContext.writeSheetHolder().getSheet(); int columnWidth = sheet.getColumnWidth(orginColumnIndex); @@ -357,7 +335,7 @@ private void doFill( Object value = null; if (FILL_VARIABLE_SELF.equals(variable)) { value = oneRowData; - }else if (dataKeySet.contains(variable)) { + } else if (dataKeySet.contains(variable)) { value = dataMap.get(variable); } ExcelContentProperty excelContentProperty = ClassUtils.declaredExcelContentProperty( @@ -410,7 +388,7 @@ private void doFill( if (cellWriteHandlerContext.getCellMap() != null && cellWriteHandlerContext.getCellMap().size() > 1) { //trigger afterCellDispose for every dynamicColumns cellWriteHandlerContext.getCellMap().values().forEach(WriteHandlerUtils::afterCellDispose); - }else{ + } else { WriteHandlerUtils.afterCellDispose(cellWriteHandlerContext); } } @@ -494,14 +472,14 @@ private void createCell( Cell cell = createCellIfNecessary(row, lastColumnIndex, cellWriteHandlerContext); cellWriteHandlerContext.setCell(cell); - if(null != field && field.isAnnotationPresent(DynamicColumn.class)){ + if (null != field && field.isAnnotationPresent(DynamicColumn.class)) { if (cellWriteHandlerContext.getCellMap() == null) { cellWriteHandlerContext.setCellMap(new HashMap<>()); } cellWriteHandlerContext.getCellMap().put(lastRowIndex + "_" + lastColumnIndex, cellWriteHandlerContext); DynamicColumnInfo dynamicColumnInfo = fillConfig.getDynamicColumnInfo(field.getName()); - if(null == dynamicColumnInfo || CollectionUtils.isEmpty(dynamicColumnInfo.getKeys())){ - throw new ExcelGenerateException(String.format("Plase set dynamic column keys for %s in fillConfig",field.getName())); + if (null == dynamicColumnInfo || CollectionUtils.isEmpty(dynamicColumnInfo.getKeys())) { + throw new ExcelGenerateException(String.format("Plase set dynamic column keys for %s in fillConfig", field.getName())); } for (int i = 1; i < dynamicColumnInfo.getKeys().size(); i++) { switch (fillConfig.getDirection()) { @@ -514,7 +492,7 @@ private void createCell( default: throw new ExcelGenerateException("The wrong direction."); } - Row newRow = createRowIfNecessary( sheet, cachedSheet, lastRowIndex, fillConfig, analysisCell, false, rowWriteHandlerContext); + Row newRow = createRowIfNecessary(sheet, cachedSheet, lastRowIndex, fillConfig, analysisCell, false, rowWriteHandlerContext); CellWriteHandlerContext cloneContext = cellWriteHandlerContext.clone(); cloneContext.setColumnIndex(lastColumnIndex); cloneContext.setRowIndex(row.getRowNum()); @@ -532,7 +510,7 @@ private void createCell( cellWriteHandlerContext.getCellMap().forEach((k, cellContext) -> { Integer currentColumnIndex = cellContext.getColumnIndex(); int columnWidth = sheet.getColumnWidth(cellWriteHandlerContext.getColumnIndex()); - sheet.setColumnWidth(currentColumnIndex,columnWidth); + sheet.setColumnWidth(currentColumnIndex, columnWidth); }); } } diff --git a/fesod/src/main/java/org/apache/fesod/excel/write/handler/context/CellWriteHandlerContext.java b/fesod/src/main/java/org/apache/fesod/excel/write/handler/context/CellWriteHandlerContext.java index 8043bb834..e6efee542 100644 --- a/fesod/src/main/java/org/apache/fesod/excel/write/handler/context/CellWriteHandlerContext.java +++ b/fesod/src/main/java/org/apache/fesod/excel/write/handler/context/CellWriteHandlerContext.java @@ -17,21 +17,8 @@ * under the License. */ -import cn.idev.excel.context.WriteContext; -import cn.idev.excel.enums.CellDataTypeEnum; -import cn.idev.excel.metadata.Head; -import cn.idev.excel.metadata.data.WriteCellData; -import cn.idev.excel.metadata.property.ExcelContentProperty; -import cn.idev.excel.write.handler.impl.FillStyleCellWriteHandler; -import cn.idev.excel.write.metadata.fill.FillConfig; -import cn.idev.excel.write.metadata.holder.WriteSheetHolder; -import cn.idev.excel.write.metadata.holder.WriteTableHolder; -import cn.idev.excel.write.metadata.holder.WriteWorkbookHolder; package org.apache.fesod.excel.write.handler.context; -import java.util.List; -import java.util.Map; - import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; @@ -41,12 +28,16 @@ import org.apache.fesod.excel.metadata.data.WriteCellData; import org.apache.fesod.excel.metadata.property.ExcelContentProperty; import org.apache.fesod.excel.write.handler.impl.FillStyleCellWriteHandler; +import org.apache.fesod.excel.write.metadata.fill.FillConfig; import org.apache.fesod.excel.write.metadata.holder.WriteSheetHolder; import org.apache.fesod.excel.write.metadata.holder.WriteTableHolder; import org.apache.fesod.excel.write.metadata.holder.WriteWorkbookHolder; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; +import java.util.List; +import java.util.Map; + /** * cell context * diff --git a/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/DynamicColumnInfo.java b/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/DynamicColumnInfo.java index 3603631ad..397c00fdc 100644 --- a/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/DynamicColumnInfo.java +++ b/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/DynamicColumnInfo.java @@ -1,4 +1,4 @@ -package cn.idev.excel.write.metadata.fill; +package org.apache.fesod.excel.write.metadata.fill; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/FillConfig.java b/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/FillConfig.java index 75a15c5b7..6f95ef72d 100644 --- a/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/FillConfig.java +++ b/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/FillConfig.java @@ -17,9 +17,6 @@ * under the License. */ -import cn.idev.excel.annotation.fill.DynamicColumn; -import cn.idev.excel.enums.WriteDirectionEnum; -import com.sun.istack.internal.Nullable; package org.apache.fesod.excel.write.metadata.fill; import lombok.AllArgsConstructor; From 0245b3926a0577bf2bdb4045b40d24a5e753bc99 Mon Sep 17 00:00:00 2001 From: milixiang Date: Mon, 29 Sep 2025 09:05:22 +0800 Subject: [PATCH 7/9] chore(license): add license header --- .../excel/temp/fill/DynamicFillData.java | 19 +++++++++++++++++++ .../excel/temp/fill/DynamicFillDataObj.java | 19 +++++++++++++++++++ .../excel/annotation/fill/DynamicColumn.java | 19 +++++++++++++++++++ .../metadata/fill/DynamicColumnInfo.java | 19 +++++++++++++++++++ 4 files changed, 76 insertions(+) diff --git a/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/DynamicFillData.java b/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/DynamicFillData.java index 917b1f55d..84e4ca579 100644 --- a/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/DynamicFillData.java +++ b/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/DynamicFillData.java @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + package org.apache.fesod.excel.temp.fill; import lombok.Data; diff --git a/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/DynamicFillDataObj.java b/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/DynamicFillDataObj.java index 77b65244a..3a8422b5f 100644 --- a/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/DynamicFillDataObj.java +++ b/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/DynamicFillDataObj.java @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + package org.apache.fesod.excel.temp.fill; import lombok.AllArgsConstructor; diff --git a/fesod/src/main/java/org/apache/fesod/excel/annotation/fill/DynamicColumn.java b/fesod/src/main/java/org/apache/fesod/excel/annotation/fill/DynamicColumn.java index 776a9ffdc..d33c856f4 100644 --- a/fesod/src/main/java/org/apache/fesod/excel/annotation/fill/DynamicColumn.java +++ b/fesod/src/main/java/org/apache/fesod/excel/annotation/fill/DynamicColumn.java @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + package org.apache.fesod.excel.annotation.fill; diff --git a/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/DynamicColumnInfo.java b/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/DynamicColumnInfo.java index 397c00fdc..d9e7c2282 100644 --- a/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/DynamicColumnInfo.java +++ b/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/DynamicColumnInfo.java @@ -1,3 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + package org.apache.fesod.excel.write.metadata.fill; import lombok.AllArgsConstructor; From 9801ac96b574f00759054a9315c51de654e6b618 Mon Sep 17 00:00:00 2001 From: milixiang Date: Mon, 13 Oct 2025 15:27:05 +0800 Subject: [PATCH 8/9] fix: fix Copilot review issue --- .../executor/AbstractExcelWriteExecutor.java | 17 ++++++++++------- .../write/executor/ExcelWriteFillExecutor.java | 13 ++++++++++--- .../excel/write/metadata/fill/FillConfig.java | 3 +++ 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/fesod/src/main/java/org/apache/fesod/excel/write/executor/AbstractExcelWriteExecutor.java b/fesod/src/main/java/org/apache/fesod/excel/write/executor/AbstractExcelWriteExecutor.java index ad5dfef92..a0ada43f0 100644 --- a/fesod/src/main/java/org/apache/fesod/excel/write/executor/AbstractExcelWriteExecutor.java +++ b/fesod/src/main/java/org/apache/fesod/excel/write/executor/AbstractExcelWriteExecutor.java @@ -161,13 +161,16 @@ protected void converterAndSet(CellWriteHandlerContext cellWriteHandlerContext) Object o = dynamicColumnMap.get(key); String originalVariable = cellWriteHandlerContext.getOriginalVariable(); if(originalVariable.contains(".")){ - key = originalVariable.split("\\.")[1]; - Object itemBean = o; - if (null == itemBean) { - o = null; - }else{ - BeanMap beanMap = BeanMapUtils.create(itemBean); - o = beanMap.get(key); + int dotIndex = originalVariable.indexOf('.'); + if (dotIndex > 0) { + key = originalVariable.substring(dotIndex + 1); + Object itemBean = o; + if (null == itemBean) { + o = null; + }else{ + BeanMap beanMap = BeanMapUtils.create(itemBean); + o = beanMap.get(key); + } } } diff --git a/fesod/src/main/java/org/apache/fesod/excel/write/executor/ExcelWriteFillExecutor.java b/fesod/src/main/java/org/apache/fesod/excel/write/executor/ExcelWriteFillExecutor.java index 1646f67c2..a28170664 100644 --- a/fesod/src/main/java/org/apache/fesod/excel/write/executor/ExcelWriteFillExecutor.java +++ b/fesod/src/main/java/org/apache/fesod/excel/write/executor/ExcelWriteFillExecutor.java @@ -173,7 +173,11 @@ private void shiftCellsIfNecessary(FillConfig fillConfig, Collection collecti List variableList = analysisCell.getVariableList(); for (String fieldName : dynamicFieldMap.keySet()) { for (String variable : variableList) { - String variableFieldName = variable.split("\\.")[0]; + int dotIndex = variable.indexOf('.'); + if (dotIndex <= 0) { + continue; + } + String variableFieldName = variable.substring(0, dotIndex); if (StringUtils.equals(fieldName, variableFieldName)) { List headers = fillConfig.getDynamicColumnInfo(fieldName).getKeys(); Integer columnGroupSize = fillConfig.getDynamicColumnInfo(fieldName).getGroupSize(); @@ -280,7 +284,10 @@ private void doFill( } else if (dataKeySet.contains(variable)) { value = dataMap.get(variable); } else if (variable.contains(COLLECTION_PREFIX)) { - variable = variable.split("\\.")[0]; + int dotIndex = variable.indexOf('.'); + if (dotIndex > 0) { + variable = variable.substring(0, dotIndex); + } value = dataMap.get(variable); } ExcelContentProperty excelContentProperty = ClassUtils.declaredExcelContentProperty( @@ -479,7 +486,7 @@ private void createCell( cellWriteHandlerContext.getCellMap().put(lastRowIndex + "_" + lastColumnIndex, cellWriteHandlerContext); DynamicColumnInfo dynamicColumnInfo = fillConfig.getDynamicColumnInfo(field.getName()); if (null == dynamicColumnInfo || CollectionUtils.isEmpty(dynamicColumnInfo.getKeys())) { - throw new ExcelGenerateException(String.format("Plase set dynamic column keys for %s in fillConfig", field.getName())); + throw new ExcelGenerateException(String.format("Please set dynamic column keys for %s in fillConfig", field.getName())); } for (int i = 1; i < dynamicColumnInfo.getKeys().size(); i++) { switch (fillConfig.getDirection()) { diff --git a/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/FillConfig.java b/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/FillConfig.java index 6f95ef72d..5ee15a6c9 100644 --- a/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/FillConfig.java +++ b/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/FillConfig.java @@ -77,6 +77,9 @@ public class FillConfig { * @return dynamic column info * */ public DynamicColumnInfo getDynamicColumnInfo(String fieldName) { + if (null == dynamicColumnInfoMap) { + return null; + } if (null == fieldName || !dynamicColumnInfoMap.containsKey(fieldName)) { return dynamicColumnInfoMap.get(DEFAULT_DYNAMIC_INFO_KEY); }else{ From 4b4a62c21edb733a9eafed20e027f4e7c35a21a2 Mon Sep 17 00:00:00 2001 From: milixiang Date: Mon, 13 Oct 2025 15:46:46 +0800 Subject: [PATCH 9/9] fix: spotless apply --- .../excel/temp/fill/DynamicFillData.java | 8 +- .../excel/temp/fill/DynamicFillDataObj.java | 4 +- .../fesod/excel/temp/fill/FillTempTest.java | 49 ++++++---- .../excel/annotation/fill/DynamicColumn.java | 7 +- .../executor/AbstractExcelWriteExecutor.java | 28 +++--- .../executor/ExcelWriteFillExecutor.java | 89 ++++++++++++------- .../context/CellWriteHandlerContext.java | 10 +-- .../metadata/fill/DynamicColumnInfo.java | 4 +- .../excel/write/metadata/fill/FillConfig.java | 12 ++- 9 files changed, 118 insertions(+), 93 deletions(-) diff --git a/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/DynamicFillData.java b/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/DynamicFillData.java index 84e4ca579..4af1206b3 100644 --- a/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/DynamicFillData.java +++ b/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/DynamicFillData.java @@ -19,18 +19,18 @@ package org.apache.fesod.excel.temp.fill; +import java.util.Map; import lombok.Data; import org.apache.fesod.excel.annotation.fill.DynamicColumn; -import java.util.Map; - @Data public class DynamicFillData { private String name; private double number; + @DynamicColumn() - private Map qtyMap; + private Map qtyMap; @DynamicColumn() - private Map priceMap; + private Map priceMap; } diff --git a/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/DynamicFillDataObj.java b/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/DynamicFillDataObj.java index 3a8422b5f..c033dccee 100644 --- a/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/DynamicFillDataObj.java +++ b/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/DynamicFillDataObj.java @@ -30,6 +30,4 @@ public class DynamicFillDataObj { private String qty; private double price; - - -} \ No newline at end of file +} diff --git a/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/FillTempTest.java b/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/FillTempTest.java index 9027d56bf..5c6ad570e 100644 --- a/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/FillTempTest.java +++ b/fesod-examples/src/test/java/org/apache/fesod/excel/temp/fill/FillTempTest.java @@ -19,6 +19,12 @@ package org.apache.fesod.excel.temp.fill; +import java.io.File; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import org.apache.fesod.excel.ExcelWriter; import org.apache.fesod.excel.FastExcel; import org.apache.fesod.excel.demo.fill.FillData; @@ -29,13 +35,6 @@ import org.apache.fesod.excel.write.metadata.fill.FillWrapper; import org.junit.jupiter.api.Test; -import java.io.File; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - /** * Example of filling data into Excel templates. * @@ -81,12 +80,12 @@ public void dynamicFill() { DynamicFillData fillData1 = new DynamicFillData(); fillData1.setName("Zhang San"); fillData1.setNumber(5.2); - HashMap qtyMap = new HashMap<>(); + HashMap qtyMap = new HashMap<>(); qtyMap.put("2023-01-01", "100"); qtyMap.put("2023-01-02", "200"); qtyMap.put("2023-01-03", "300"); fillData1.setQtyMap(qtyMap); - HashMap priceMap = new HashMap<>(); + HashMap priceMap = new HashMap<>(); priceMap.put("2023-01-01", new DynamicFillDataObj("100个", 100)); priceMap.put("2023-01-02", new DynamicFillDataObj("200个", 200)); priceMap.put("2023-01-03", new DynamicFillDataObj("300个", 300)); @@ -95,12 +94,12 @@ public void dynamicFill() { DynamicFillData fillData2 = new DynamicFillData(); fillData2.setName("Li Si"); fillData2.setNumber(6.3); - HashMap qtyMap2 = new HashMap<>(); + HashMap qtyMap2 = new HashMap<>(); qtyMap2.put("2023-01-01", "100"); qtyMap2.put("2023-01-02", "200"); qtyMap2.put("2023-01-03", "300"); fillData2.setQtyMap(qtyMap2); - HashMap priceMap2 = new HashMap<>(); + HashMap priceMap2 = new HashMap<>(); priceMap2.put("2023-01-01", new DynamicFillDataObj("100", 100)); priceMap2.put("2023-01-02", new DynamicFillDataObj("200", 200)); priceMap2.put("2023-01-03", new DynamicFillDataObj("300", 300)); @@ -124,16 +123,30 @@ public void dynamicFill() { dateList.add("2023-01-11"); dateList.add("2023-01-12"); - ExcelWriter excelWriter = FastExcel.write(fileName).withTemplate(templateFileName).build(); + ExcelWriter excelWriter = + FastExcel.write(fileName).withTemplate(templateFileName).build(); WriteSheet writeSheet = FastExcel.writerSheet().build(); - excelWriter.fill(new FillWrapper("dataList", fillDataList), FillConfig.builder().forceNewRow(true).addDynamicInfo(dateList,1,"qtyMap") - .addDefaultDynamicInfo(dateList,1) - .build(), writeSheet); - excelWriter.fill(new FillWrapper("dataObjList", fillDataList), FillConfig.builder().addDefaultDynamicInfo(dateList,2).forceNewRow(true).build(), writeSheet); - excelWriter.fill(new FillWrapper("dateList", dateList), FillConfig.builder().direction(WriteDirectionEnum.HORIZONTAL).build(), writeSheet); + excelWriter.fill( + new FillWrapper("dataList", fillDataList), + FillConfig.builder() + .forceNewRow(true) + .addDynamicInfo(dateList, 1, "qtyMap") + .addDefaultDynamicInfo(dateList, 1) + .build(), + writeSheet); + excelWriter.fill( + new FillWrapper("dataObjList", fillDataList), + FillConfig.builder() + .addDefaultDynamicInfo(dateList, 2) + .forceNewRow(true) + .build(), + writeSheet); + excelWriter.fill( + new FillWrapper("dateList", dateList), + FillConfig.builder().direction(WriteDirectionEnum.HORIZONTAL).build(), + writeSheet); // Do not forget to close the stream excelWriter.finish(); - } /** diff --git a/fesod/src/main/java/org/apache/fesod/excel/annotation/fill/DynamicColumn.java b/fesod/src/main/java/org/apache/fesod/excel/annotation/fill/DynamicColumn.java index d33c856f4..5e8d2c388 100644 --- a/fesod/src/main/java/org/apache/fesod/excel/annotation/fill/DynamicColumn.java +++ b/fesod/src/main/java/org/apache/fesod/excel/annotation/fill/DynamicColumn.java @@ -19,16 +19,13 @@ package org.apache.fesod.excel.annotation.fill; - import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import java.lang.annotation.Inherited; @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Inherited -public @interface DynamicColumn { - -} +public @interface DynamicColumn {} diff --git a/fesod/src/main/java/org/apache/fesod/excel/write/executor/AbstractExcelWriteExecutor.java b/fesod/src/main/java/org/apache/fesod/excel/write/executor/AbstractExcelWriteExecutor.java index a0ada43f0..699dbe34d 100644 --- a/fesod/src/main/java/org/apache/fesod/excel/write/executor/AbstractExcelWriteExecutor.java +++ b/fesod/src/main/java/org/apache/fesod/excel/write/executor/AbstractExcelWriteExecutor.java @@ -20,6 +20,9 @@ package org.apache.fesod.excel.write.executor; import cn.idev.excel.support.cglib.beans.BeanMap; +import java.lang.reflect.Field; +import java.util.List; +import java.util.Map; import org.apache.commons.collections4.CollectionUtils; import org.apache.fesod.excel.annotation.fill.DynamicColumn; import org.apache.fesod.excel.context.WriteContext; @@ -59,10 +62,6 @@ import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.usermodel.XSSFClientAnchor; -import java.lang.reflect.Field; -import java.util.List; -import java.util.Map; - /** * Excel write Executor * @@ -150,24 +149,26 @@ protected void converterAndSet(CellWriteHandlerContext cellWriteHandlerContext) if (null != field && field.isAnnotationPresent(DynamicColumn.class)) { Map dynamicColumnMap = (Map) originalValue; FillConfig fillConfig = cellWriteHandlerContext.getFillConfig(); - if(null == fillConfig || null == fillConfig.getDynamicColumnInfoMap()){ - throw new ExcelWriteDataConvertException(cellWriteHandlerContext, "DynamicColumn annotation must be used with FillConfig.dynamicColumnInfoMap"); + if (null == fillConfig || null == fillConfig.getDynamicColumnInfoMap()) { + throw new ExcelWriteDataConvertException( + cellWriteHandlerContext, + "DynamicColumn annotation must be used with FillConfig.dynamicColumnInfoMap"); } DynamicColumnInfo dynamicColumnInfo = fillConfig.getDynamicColumnInfo(field.getName()); Integer columnIndex = cellWriteHandlerContext.getColumnIndex(); Integer rowIndex = cellWriteHandlerContext.getRowIndex(); for (int i = 0; i < dynamicColumnInfo.getKeys().size(); i++) { - String key = dynamicColumnInfo.getKeys().get(i); + String key = dynamicColumnInfo.getKeys().get(i); Object o = dynamicColumnMap.get(key); String originalVariable = cellWriteHandlerContext.getOriginalVariable(); - if(originalVariable.contains(".")){ + if (originalVariable.contains(".")) { int dotIndex = originalVariable.indexOf('.'); if (dotIndex > 0) { key = originalVariable.substring(dotIndex + 1); Object itemBean = o; if (null == itemBean) { o = null; - }else{ + } else { BeanMap beanMap = BeanMapUtils.create(itemBean); o = beanMap.get(key); } @@ -178,14 +179,15 @@ protected void converterAndSet(CellWriteHandlerContext cellWriteHandlerContext) WriteDirectionEnum direction = fillConfig.getDirection(); int currentRowIndex = rowIndex; int currentColumnIndex = columnIndex; - if(WriteDirectionEnum.VERTICAL.equals(direction)){ + if (WriteDirectionEnum.VERTICAL.equals(direction)) { currentColumnIndex = columnIndex + dynamicColumnGroupSize * i; - }else{ - currentRowIndex = rowIndex + dynamicColumnGroupSize*i; + } else { + currentRowIndex = rowIndex + dynamicColumnGroupSize * i; } Map cellMap = cellWriteHandlerContext.getCellMap(); - CellWriteHandlerContext currentCellWriteHandlerContext = cellMap.get(currentRowIndex + "_" + currentColumnIndex); + CellWriteHandlerContext currentCellWriteHandlerContext = + cellMap.get(currentRowIndex + "_" + currentColumnIndex); currentCellWriteHandlerContext.setOriginalValue(o); currentCellWriteHandlerContext.setOriginalFieldClass(FieldUtils.getFieldClass(o)); convertAndSetItem(currentCellWriteHandlerContext); diff --git a/fesod/src/main/java/org/apache/fesod/excel/write/executor/ExcelWriteFillExecutor.java b/fesod/src/main/java/org/apache/fesod/excel/write/executor/ExcelWriteFillExecutor.java index a28170664..2679f59d9 100644 --- a/fesod/src/main/java/org/apache/fesod/excel/write/executor/ExcelWriteFillExecutor.java +++ b/fesod/src/main/java/org/apache/fesod/excel/write/executor/ExcelWriteFillExecutor.java @@ -20,7 +20,6 @@ package org.apache.fesod.excel.write.executor; import java.lang.reflect.Field; - import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; @@ -32,7 +31,6 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; - import lombok.AllArgsConstructor; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -154,8 +152,11 @@ public void fill(Object data, FillConfig fillConfig) { } } - private void shiftCellsIfNecessary(FillConfig fillConfig, Collection collectionData, List analysisCellList) { - if (WriteDirectionEnum.VERTICAL.equals(fillConfig.getDirection()) && CollectionUtils.isNotEmpty(collectionData) && collectionData.size() > 1) { + private void shiftCellsIfNecessary( + FillConfig fillConfig, Collection collectionData, List analysisCellList) { + if (WriteDirectionEnum.VERTICAL.equals(fillConfig.getDirection()) + && CollectionUtils.isNotEmpty(collectionData) + && collectionData.size() > 1) { Sheet sheet = writeContext.writeSheetHolder().getCachedSheet(); Object item = collectionData.iterator().next(); Class itemClass = item.getClass(); @@ -166,29 +167,39 @@ private void shiftCellsIfNecessary(FillConfig fillConfig, Collection collecti dynamicFieldMap.put(declaredField.getName(), declaredField); } } - analysisCellList.stream().sorted(Comparator.comparingInt(AnalysisCell::getColumnIndex).reversed()).forEach(analysisCell -> { - int rowIndex = analysisCell.getRowIndex(); - int columnIndex = analysisCell.getColumnIndex(); - Row row = sheet.getRow(rowIndex); - List variableList = analysisCell.getVariableList(); - for (String fieldName : dynamicFieldMap.keySet()) { - for (String variable : variableList) { - int dotIndex = variable.indexOf('.'); - if (dotIndex <= 0) { - continue; - } - String variableFieldName = variable.substring(0, dotIndex); - if (StringUtils.equals(fieldName, variableFieldName)) { - List headers = fillConfig.getDynamicColumnInfo(fieldName).getKeys(); - Integer columnGroupSize = fillConfig.getDynamicColumnInfo(fieldName).getGroupSize(); - row.shiftCellsRight(columnIndex + columnGroupSize, row.getLastCellNum(), headers.size() - 1); - analysisCellList.stream().filter(ac -> ac.getColumnIndex() > (columnIndex + columnGroupSize - 1)).forEach(ac -> { - ac.setColumnIndex(ac.getColumnIndex() + headers.size() - 1); - }); + analysisCellList.stream() + .sorted(Comparator.comparingInt(AnalysisCell::getColumnIndex) + .reversed()) + .forEach(analysisCell -> { + int rowIndex = analysisCell.getRowIndex(); + int columnIndex = analysisCell.getColumnIndex(); + Row row = sheet.getRow(rowIndex); + List variableList = analysisCell.getVariableList(); + for (String fieldName : dynamicFieldMap.keySet()) { + for (String variable : variableList) { + int dotIndex = variable.indexOf('.'); + if (dotIndex <= 0) { + continue; + } + String variableFieldName = variable.substring(0, dotIndex); + if (StringUtils.equals(fieldName, variableFieldName)) { + List headers = fillConfig + .getDynamicColumnInfo(fieldName) + .getKeys(); + Integer columnGroupSize = fillConfig + .getDynamicColumnInfo(fieldName) + .getGroupSize(); + row.shiftCellsRight( + columnIndex + columnGroupSize, row.getLastCellNum(), headers.size() - 1); + analysisCellList.stream() + .filter(ac -> ac.getColumnIndex() > (columnIndex + columnGroupSize - 1)) + .forEach(ac -> { + ac.setColumnIndex(ac.getColumnIndex() + headers.size() - 1); + }); + } + } } - } - } - }); + }); } } @@ -313,12 +324,18 @@ private void doFill( Optional.ofNullable(collectionFieldStyleCache.get(currentUniqueDataFlag)) .map(collectionFieldStyleMap -> collectionFieldStyleMap.get(analysisCell)) .ifPresent(style -> { - if (cellWriteHandlerContext.getCellMap() != null && cellWriteHandlerContext.getCellMap().size() > 1) { - cellWriteHandlerContext.getCellMap().values().forEach(cell -> cell.getFirstCellData().setOriginCellStyle(style)); + if (cellWriteHandlerContext.getCellMap() != null + && cellWriteHandlerContext.getCellMap().size() > 1) { + cellWriteHandlerContext + .getCellMap() + .values() + .forEach(cell -> + cell.getFirstCellData().setOriginCellStyle(style)); } else { if (fillConfig.getDirection() == WriteDirectionEnum.HORIZONTAL) { Integer orginColumnIndex = analysisCell.getColumnIndex(); - Sheet sheet = writeContext.writeSheetHolder().getSheet(); + Sheet sheet = + writeContext.writeSheetHolder().getSheet(); int columnWidth = sheet.getColumnWidth(orginColumnIndex); sheet.setColumnWidth(cellWriteHandlerContext.getColumnIndex(), columnWidth); } @@ -392,8 +409,9 @@ private void doFill( .ifPresent(cell::setCellStyle); } } - if (cellWriteHandlerContext.getCellMap() != null && cellWriteHandlerContext.getCellMap().size() > 1) { - //trigger afterCellDispose for every dynamicColumns + if (cellWriteHandlerContext.getCellMap() != null + && cellWriteHandlerContext.getCellMap().size() > 1) { + // trigger afterCellDispose for every dynamicColumns cellWriteHandlerContext.getCellMap().values().forEach(WriteHandlerUtils::afterCellDispose); } else { WriteHandlerUtils.afterCellDispose(cellWriteHandlerContext); @@ -486,7 +504,8 @@ private void createCell( cellWriteHandlerContext.getCellMap().put(lastRowIndex + "_" + lastColumnIndex, cellWriteHandlerContext); DynamicColumnInfo dynamicColumnInfo = fillConfig.getDynamicColumnInfo(field.getName()); if (null == dynamicColumnInfo || CollectionUtils.isEmpty(dynamicColumnInfo.getKeys())) { - throw new ExcelGenerateException(String.format("Please set dynamic column keys for %s in fillConfig", field.getName())); + throw new ExcelGenerateException( + String.format("Please set dynamic column keys for %s in fillConfig", field.getName())); } for (int i = 1; i < dynamicColumnInfo.getKeys().size(); i++) { switch (fillConfig.getDirection()) { @@ -499,7 +518,8 @@ private void createCell( default: throw new ExcelGenerateException("The wrong direction."); } - Row newRow = createRowIfNecessary(sheet, cachedSheet, lastRowIndex, fillConfig, analysisCell, false, rowWriteHandlerContext); + Row newRow = createRowIfNecessary( + sheet, cachedSheet, lastRowIndex, fillConfig, analysisCell, false, rowWriteHandlerContext); CellWriteHandlerContext cloneContext = cellWriteHandlerContext.clone(); cloneContext.setColumnIndex(lastColumnIndex); cloneContext.setRowIndex(row.getRowNum()); @@ -513,7 +533,8 @@ private void createCell( Map collectionFieldStyleMap = collectionFieldStyleCache.computeIfAbsent(currentUniqueDataFlag, key -> MapUtils.newHashMap()); collectionFieldStyleMap.put(analysisCell, cell.getCellStyle()); - if (cellWriteHandlerContext.getCellMap() != null && cellWriteHandlerContext.getCellMap().size() > 1) { + if (cellWriteHandlerContext.getCellMap() != null + && cellWriteHandlerContext.getCellMap().size() > 1) { cellWriteHandlerContext.getCellMap().forEach((k, cellContext) -> { Integer currentColumnIndex = cellContext.getColumnIndex(); int columnWidth = sheet.getColumnWidth(cellWriteHandlerContext.getColumnIndex()); diff --git a/fesod/src/main/java/org/apache/fesod/excel/write/handler/context/CellWriteHandlerContext.java b/fesod/src/main/java/org/apache/fesod/excel/write/handler/context/CellWriteHandlerContext.java index e6efee542..c7b9303d1 100644 --- a/fesod/src/main/java/org/apache/fesod/excel/write/handler/context/CellWriteHandlerContext.java +++ b/fesod/src/main/java/org/apache/fesod/excel/write/handler/context/CellWriteHandlerContext.java @@ -19,6 +19,8 @@ package org.apache.fesod.excel.write.handler.context; +import java.util.List; +import java.util.Map; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; @@ -35,9 +37,6 @@ import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; -import java.util.List; -import java.util.Map; - /** * cell context * @@ -79,7 +78,7 @@ public class CellWriteHandlerContext implements Cloneable { * cellMap use by DynamicColumn * key rowIndex_columnIndex */ - private Map cellMap; + private Map cellMap; /** * index */ @@ -159,8 +158,7 @@ public CellWriteHandlerContext clone() { this.cellDataList, this.firstCellData, this.head, - this.excelContentProperty - ); + this.excelContentProperty); return cellWriteHandlerContext; } diff --git a/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/DynamicColumnInfo.java b/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/DynamicColumnInfo.java index d9e7c2282..2bbf62a83 100644 --- a/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/DynamicColumnInfo.java +++ b/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/DynamicColumnInfo.java @@ -19,13 +19,12 @@ package org.apache.fesod.excel.write.metadata.fill; +import java.util.List; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; -import java.util.List; - @Getter @Setter @AllArgsConstructor @@ -41,5 +40,4 @@ public class DynamicColumnInfo { * dynamic column group size * */ private Integer groupSize; - } diff --git a/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/FillConfig.java b/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/FillConfig.java index 5ee15a6c9..f68615d6c 100644 --- a/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/FillConfig.java +++ b/fesod/src/main/java/org/apache/fesod/excel/write/metadata/fill/FillConfig.java @@ -19,6 +19,9 @@ package org.apache.fesod.excel.write.metadata.fill; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.EqualsAndHashCode; @@ -27,10 +30,6 @@ import lombok.Setter; import org.apache.fesod.excel.enums.WriteDirectionEnum; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - /** * Fill config * @@ -65,7 +64,7 @@ public class FillConfig { /** * dynamic column info * */ - private Map dynamicColumnInfoMap; + private Map dynamicColumnInfoMap; /** * get dynamic column info @@ -82,7 +81,7 @@ public DynamicColumnInfo getDynamicColumnInfo(String fieldName) { } if (null == fieldName || !dynamicColumnInfoMap.containsKey(fieldName)) { return dynamicColumnInfoMap.get(DEFAULT_DYNAMIC_INFO_KEY); - }else{ + } else { return dynamicColumnInfoMap.get(fieldName); } } @@ -119,6 +118,5 @@ public FillConfigBuilder addDefaultDynamicInfo(List keys) { public FillConfigBuilder addDefaultDynamicInfo(List keys, Integer groupSize) { return addDynamicInfo(keys, groupSize, DEFAULT_DYNAMIC_INFO_KEY); } - } }