bengbengbalabalabeng commented on code in PR #842:
URL: https://github.com/apache/fesod/pull/842#discussion_r2847562379


##########
website/i18n/zh-cn/docusaurus-plugin-content-docs/current/sheet/fill/fill.md:
##########
@@ -104,6 +120,95 @@ public void listFill() {
 
 ---
 
+## 列表填充合并策略
+
+### 概述
+
+在处理列表数据填充时,模板中可能定义了复杂的跨行或跨列合并结构。默认情况下,Fesod 不会自动合并跨行跨列单元格。但是,您可以使用 
`mergeStrategy` 参数来控制合并行为。
+
+### 合并策略
+
+- **NONE**: 不进行任何自动合并(默认)。
+- **AUTO**: Fesod 会参照模板行的合并结构,自动对生成的每一行数据应用相同的合并区域。
+- **MERGE_CELL_STYLE**: 在 `AUTO` 的基础上,将 **锚定单元格(左上角单元格)** 的样式应用到整个合并区域内的所有单元格。
+  - *注意:过多的单元格样式实例可能导致性能问题,并可能超出单元格样式数量限制(.xlsx 格式为 64000 个,.xls 格式为 4000 
个),请在数据量较大时谨慎使用。*

Review Comment:
   Corrected PR description.



##########
fesod-sheet/src/main/java/org/apache/fesod/sheet/write/executor/ExcelWriteFillExecutor.java:
##########
@@ -137,18 +141,116 @@ public void fill(Object data, FillConfig fillConfig) {
                 return;
             }
             Iterator<?> iterator = collectionData.iterator();
+            int rowSpan = calculateRowSpan(analysisCellList);
             if (WriteDirectionEnum.VERTICAL.equals(fillConfig.getDirection()) 
&& fillConfig.getForceNewRow()) {
-                shiftRows(collectionData.size(), analysisCellList);
+                shiftRows(collectionData.size(), rowSpan, analysisCellList);
             }
             while (iterator.hasNext()) {
-                doFill(analysisCellList, iterator.next(), fillConfig, 
getRelativeRowIndex());
+                doFill(analysisCellList, iterator.next(), fillConfig, 
getRelativeRowIndex(), rowSpan);
             }
         } else {
-            doFill(readTemplateData(templateAnalysisCache), realData, 
fillConfig, null);
+            doFill(readTemplateData(templateAnalysisCache), realData, 
fillConfig, null, 0);
         }
     }
 
-    private void shiftRows(int size, List<AnalysisCell> analysisCellList) {
+    private void addMergedRegionIfNecessary(List<AnalysisCell> 
analysisCellList, FillConfig fillConfig) {
+        FillMergeStrategy mergeStrategy = fillConfig.getMergeStrategy();
+        if (FillMergeStrategy.NONE.equals(mergeStrategy)) {
+            return;
+        }
+
+        Set<CellRangeAddress> dataRowMergeRegions = 
determineMergedRegionsForRow(analysisCellList, fillConfig);
+        if (CollectionUtils.isEmpty(dataRowMergeRegions)) {
+            return;
+        }
+
+        Sheet sheet = writeContext.writeSheetHolder().getSheet();
+
+        // Unify the style using anchor cells
+        if (FillMergeStrategy.MERGE_CELL_STYLE.equals(mergeStrategy)) {
+            Sheet cachedSheet = 
writeContext.writeSheetHolder().getCachedSheet();
+            Map<CellCoordinate, Set<CellCoordinate>> cellCoordinateMap = 
indexMergedRegionsMap(dataRowMergeRegions);
+
+            for (Map.Entry<CellCoordinate, Set<CellCoordinate>> entry : 
cellCoordinateMap.entrySet()) {
+                CellCoordinate anchor = entry.getKey();
+                CellStyle anchorStyle =
+                        anchor.getOrCreateCell(sheet, 
cachedSheet).getCellStyle();
+
+                for (CellCoordinate mergedCell : entry.getValue()) {
+                    Cell cell = mergedCell.getOrCreateCell(sheet, cachedSheet);
+                    cell.setCellStyle(anchorStyle);
+                }
+            }
+        }
+
+        // Merge cells
+        for (CellRangeAddress range : dataRowMergeRegions) {
+            sheet.addMergedRegionUnsafe(range.copy());
+        }
+    }
+
+    private Set<CellRangeAddress> 
determineMergedRegionsForRow(List<AnalysisCell> cells, FillConfig fillConfig) {
+        if (CollectionUtils.isEmpty(cells)
+                || 
!WriteDirectionEnum.VERTICAL.equals(fillConfig.getDirection())
+                || 
FillMergeStrategy.NONE.equals(fillConfig.getMergeStrategy())) {
+            return Collections.emptySet();
+        }
+
+        Sheet sheet = writeContext.writeSheetHolder().getSheet();
+        if (sheet.getNumMergedRegions() == 0) {
+            return Collections.emptySet();
+        }
+
+        Set<CellRangeAddress> absoluteRegions = new HashSet<>();
+        Map<AnalysisCell, Integer> collectionLastIndexMap = 
collectionLastIndexCache.get(currentUniqueDataFlag);
+
+        for (AnalysisCell cell : cells) {
+            for (CellRangeAddress range : sheet.getMergedRegions()) {
+                if (range.isInRange(cell.getRowIndex(), 
cell.getColumnIndex())) {
+                    int firstRow = collectionLastIndexMap.get(cell);
+                    int lastRow = firstRow + (range.getLastRow() - 
range.getFirstRow());

Review Comment:
   Corrected PR description.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to