Skip to content

Commit 74eb525

Browse files
committed
feat: introduce HeaderMergeStrategy for flexible header merging and fix issue #666
1 parent b8035d2 commit 74eb525

File tree

7 files changed

+6
-88
lines changed

7 files changed

+6
-88
lines changed

fesod/src/main/java/org/apache/fesod/excel/enums/HeaderMergeStrategy.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ public enum HeaderMergeStrategy {
4343

4444
/**
4545
* Only vertical merge (same cells in the same column).
46-
* Note: This strategy does not check context consistency (unlike AUTO strategy).
4746
*/
4847
VERTICAL_ONLY,
4948

@@ -54,7 +53,6 @@ public enum HeaderMergeStrategy {
5453

5554
/**
5655
* Auto merge (default behavior for backward compatibility).
57-
* Includes context consistency validation to prevent incorrect merges.
5856
*/
5957
AUTO
6058
}

fesod/src/main/java/org/apache/fesod/excel/write/property/ExcelWriteHeadProperty.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ public List<CellRange> headCellRangeList(HeaderMergeStrategy mergeStrategy) {
181181
}
182182
}
183183

184-
// For AUTO strategy, also check context consistency (above cells)
184+
// For AUTO strategy, also check context consistency
185185
if (canMerge && mergeStrategy == HeaderMergeStrategy.AUTO) {
186186
canMerge = canMergeVertically(headList, j, k, i, lastCol, headName);
187187
}

fesod/src/test/java/org/apache/fesod/excel/head/HeaderMergeStrategyTest.java

Lines changed: 1 addition & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ public class HeaderMergeStrategyTest {
4646
private static File fileVerticalOnly;
4747
private static File fileFullRectangle;
4848
private static File fileAuto;
49-
private static File fileIssue666;
5049

5150
@BeforeAll
5251
public static void init() {
@@ -55,53 +54,6 @@ public static void init() {
5554
fileVerticalOnly = TestFileUtil.createNewFile("headerMergeStrategyVerticalOnly.xlsx");
5655
fileFullRectangle = TestFileUtil.createNewFile("headerMergeStrategyFullRectangle.xlsx");
5756
fileAuto = TestFileUtil.createNewFile("headerMergeStrategyAuto.xlsx");
58-
fileIssue666 = TestFileUtil.createNewFile("headerMergeStrategyIssue666.xlsx");
59-
}
60-
61-
/**
62-
* Test issue #666 scenario: dynamic head with same cell name but different context
63-
* Expected: C2 and D2 should not be merged
64-
*/
65-
@Test
66-
public void testIssue666() {
67-
List<List<String>> multiHeader = new ArrayList<>();
68-
multiHeader.add(new ArrayList<>(Arrays.asList("head10")));
69-
multiHeader.add(new ArrayList<>(Arrays.asList("head20", "head21")));
70-
multiHeader.add(new ArrayList<>(Arrays.asList("head30", "head31")));
71-
multiHeader.add(new ArrayList<>(Arrays.asList("head40", "head31")));
72-
multiHeader.add(new ArrayList<>(Arrays.asList("head40", "head41")));
73-
74-
// Test with FULL_RECTANGLE strategy - should not merge C2 and D2
75-
FastExcel.write(fileIssue666)
76-
.head(multiHeader)
77-
.headerMergeStrategy(HeaderMergeStrategy.FULL_RECTANGLE)
78-
.sheet()
79-
.doWrite(createTestData());
80-
81-
// Verify that C2 and D2 are not merged
82-
try (org.apache.poi.ss.usermodel.Workbook workbook =
83-
org.apache.poi.ss.usermodel.WorkbookFactory.create(fileIssue666)) {
84-
Sheet sheet = workbook.getSheetAt(0);
85-
int mergedRegionCount = sheet.getNumMergedRegions();
86-
87-
// Check all merged regions
88-
boolean c2AndD2Merged = false;
89-
for (int i = 0; i < mergedRegionCount; i++) {
90-
CellRangeAddress region = sheet.getMergedRegion(i);
91-
// C2 is row 1, col 2; D2 is row 1, col 3
92-
// If they are merged, there should be a region covering both
93-
if (region.getFirstRow() == 1 && region.getLastRow() == 1
94-
&& region.getFirstColumn() == 2 && region.getLastColumn() == 3) {
95-
c2AndD2Merged = true;
96-
break;
97-
}
98-
}
99-
100-
// Assert that C2 and D2 are NOT merged
101-
Assertions.assertFalse(c2AndD2Merged, "C2 and D2 should not be merged in issue #666 scenario");
102-
} catch (Exception e) {
103-
throw new RuntimeException("Failed to verify merged regions", e);
104-
}
10557
}
10658

10759
@Test
@@ -213,7 +165,7 @@ public void testAutoStrategy() {
213165
.sheet()
214166
.doWrite(createTestData());
215167

216-
// AUTO strategy should work similar to the old behavior but with context validation
168+
// AUTO strategy should work similar to the old behavior
217169
try (org.apache.poi.ss.usermodel.Workbook workbook =
218170
org.apache.poi.ss.usermodel.WorkbookFactory.create(fileAuto)) {
219171
Sheet sheet = workbook.getSheetAt(0);

website/docs/help/parameter.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ The `headerMergeStrategy` parameter provides fine-grained control over how heade
181181
- **HORIZONTAL_ONLY**: Only merges cells horizontally (same row).
182182
- **VERTICAL_ONLY**: Only merges cells vertically (same column).
183183
- **FULL_RECTANGLE**: Only merges complete rectangular regions where all cells have the same name.
184-
- **AUTO**: Automatic merging (default behavior for backward compatibility), with improved context validation to prevent incorrect merges.
184+
- **AUTO**: Automatic merging (default behavior for backward compatibility).
185185

186186
**Example**:
187187
```java

website/docs/write/head.md

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ By default, FastExcel automatically merges header cells with the same name. Howe
9090
- **HORIZONTAL_ONLY**: Only merges cells horizontally (same row).
9191
- **VERTICAL_ONLY**: Only merges cells vertically (same column).
9292
- **FULL_RECTANGLE**: Only merges complete rectangular regions where all cells have the same name.
93-
- **AUTO**: Automatic merging (default), with improved context validation.
93+
- **AUTO**: Automatic merging (default).
9494

9595
### Code Example
9696

@@ -114,22 +114,6 @@ public void dynamicHeadWriteWithStrategy() {
114114

115115
### Common Use Cases
116116

117-
**Prevent incorrect merges**: When you have cells with the same name but different contexts (e.g., different parent headers), use `FULL_RECTANGLE` or `HORIZONTAL_ONLY`:
118-
119-
```java
120-
List<List<String>> multiHeader = new ArrayList<>();
121-
multiHeader.add(new ArrayList<>(Arrays.asList("head10")));
122-
multiHeader.add(new ArrayList<>(Arrays.asList("head20", "head21")));
123-
multiHeader.add(new ArrayList<>(Arrays.asList("head30", "head31")));
124-
multiHeader.add(new ArrayList<>(Arrays.asList("head40", "head31"))); // Same name "head31" but different context
125-
126-
FastExcel.write(fileName)
127-
.head(multiHeader)
128-
.headerMergeStrategy(HeaderMergeStrategy.FULL_RECTANGLE) // Prevents incorrect vertical merge
129-
.sheet()
130-
.doWrite(data());
131-
```
132-
133117
**Disable merging**: Use `NONE` to completely disable automatic merging:
134118

135119
```java

website/i18n/zh-cn/docusaurus-plugin-content-docs/current/help/parameter.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ WriteWorkbook --|> WriteBasicParameter
181181
- **HORIZONTAL_ONLY**: 仅水平合并(同一行内的相同单元格)。
182182
- **VERTICAL_ONLY**: 仅垂直合并(同一列内的相同单元格)。
183183
- **FULL_RECTANGLE**: 仅合并完整的矩形区域(所有单元格名称相同)。
184-
- **AUTO**: 自动合并(默认行为,向后兼容),增强了上下文验证以防止错误的合并
184+
- **AUTO**: 自动合并(默认行为,向后兼容)。
185185

186186
**示例**:
187187
```java

website/i18n/zh-cn/docusaurus-plugin-content-docs/current/write/head.md

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public void dynamicHeadWrite() {
9090
- **HORIZONTAL_ONLY**: 仅水平合并(同一行内的相同单元格)。
9191
- **VERTICAL_ONLY**: 仅垂直合并(同一列内的相同单元格)。
9292
- **FULL_RECTANGLE**: 仅合并完整的矩形区域(所有单元格名称相同)。
93-
- **AUTO**: 自动合并(默认),增强了上下文验证
93+
- **AUTO**: 自动合并(默认)。
9494

9595
### 代码示例
9696

@@ -114,22 +114,6 @@ public void dynamicHeadWriteWithStrategy() {
114114

115115
### 常见使用场景
116116

117-
**防止错误合并**: 当您有名称相同但上下文不同的单元格(例如,不同的父级表头)时,使用 `FULL_RECTANGLE``HORIZONTAL_ONLY`
118-
119-
```java
120-
List<List<String>> multiHeader = new ArrayList<>();
121-
multiHeader.add(new ArrayList<>(Arrays.asList("head10")));
122-
multiHeader.add(new ArrayList<>(Arrays.asList("head20", "head21")));
123-
multiHeader.add(new ArrayList<>(Arrays.asList("head30", "head31")));
124-
multiHeader.add(new ArrayList<>(Arrays.asList("head40", "head31"))); // 相同的名称 "head31" 但上下文不同
125-
126-
FastExcel.write(fileName)
127-
.head(multiHeader)
128-
.headerMergeStrategy(HeaderMergeStrategy.FULL_RECTANGLE) // 防止错误的垂直合并
129-
.sheet()
130-
.doWrite(data());
131-
```
132-
133117
**禁用合并**: 使用 `NONE` 完全禁用自动合并:
134118

135119
```java

0 commit comments

Comments
 (0)