Skip to content

Commit a501139

Browse files
liugddxdeleiCopilotpsxjoygdliu3
authored
feat: introduce header merge strategy for Excel writing (#674)
* feat: introduce header merge strategy for Excel writing * feat: enhance header merge strategy with context validation and improved documentation * feat: enhance header merge strategy with context validation and improved documentation * feat: introduce HeaderMergeStrategy for flexible header merging and fix issue #666 * feat: introduce HeaderMergeStrategy for flexible header merging and fix issue #666 * Update fesod/src/test/java/org/apache/fesod/excel/head/HeaderMergeStrategyTest.java Co-authored-by: Copilot <[email protected]> * Update fesod/src/test/java/org/apache/fesod/excel/head/HeaderMergeStrategyTest.java Co-authored-by: Copilot <[email protected]> * feat: simplify canMergeVertically method by removing unused parameter * doc: add line breaks for better readability in parameter documentation --------- Co-authored-by: DeleiGuo <[email protected]> Co-authored-by: Copilot <[email protected]> Co-authored-by: Shuxin Pan <[email protected]> Co-authored-by: gdliu3 <[email protected]>
1 parent 945b543 commit a501139

File tree

12 files changed

+632
-26
lines changed

12 files changed

+632
-26
lines changed

fesod/src/main/java/org/apache/fesod/sheet/context/WriteContextImpl.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import java.util.Map;
2626
import java.util.UUID;
2727
import lombok.extern.slf4j.Slf4j;
28+
import org.apache.fesod.sheet.enums.HeaderMergeStrategy;
2829
import org.apache.fesod.sheet.enums.WriteTypeEnum;
2930
import org.apache.fesod.sheet.exception.ExcelGenerateException;
3031
import org.apache.fesod.sheet.metadata.CellRange;
@@ -296,8 +297,9 @@ public void initHead(ExcelWriteHeadProperty excelWriteHeadProperty) {
296297
}
297298
int newRowIndex = writeSheetHolder.getNewRowIndexAndStartDoWrite();
298299
newRowIndex += currentWriteHolder.relativeHeadRowIndex();
299-
if (currentWriteHolder.automaticMergeHead()) {
300-
addMergedRegionToCurrentSheet(excelWriteHeadProperty, newRowIndex);
300+
HeaderMergeStrategy mergeStrategy = currentWriteHolder.headerMergeStrategy();
301+
if (mergeStrategy != null && mergeStrategy != HeaderMergeStrategy.NONE) {
302+
addMergedRegionToCurrentSheet(excelWriteHeadProperty, newRowIndex, mergeStrategy);
301303
}
302304
for (int relativeRowIndex = 0, i = newRowIndex;
303305
i < excelWriteHeadProperty.getHeadRowNumber() + newRowIndex;
@@ -321,9 +323,11 @@ public void initHead(ExcelWriteHeadProperty excelWriteHeadProperty) {
321323
*
322324
* @param excelWriteHeadProperty The header property for writing.
323325
* @param rowIndex The starting row index for merging.
326+
* @param mergeStrategy The merge strategy to use.
324327
*/
325-
private void addMergedRegionToCurrentSheet(ExcelWriteHeadProperty excelWriteHeadProperty, int rowIndex) {
326-
for (CellRange cellRangeModel : excelWriteHeadProperty.headCellRangeList()) {
328+
private void addMergedRegionToCurrentSheet(
329+
ExcelWriteHeadProperty excelWriteHeadProperty, int rowIndex, HeaderMergeStrategy mergeStrategy) {
330+
for (CellRange cellRangeModel : excelWriteHeadProperty.headCellRangeList(mergeStrategy)) {
327331
writeSheetHolder
328332
.getSheet()
329333
.addMergedRegionUnsafe(new CellRangeAddress(
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.apache.fesod.sheet.enums;
21+
22+
/**
23+
* Header merge strategy for Excel writing.
24+
* <p>
25+
* When {@code headerMergeStrategy} is not set (null), the behavior is determined by
26+
* {@code automaticMergeHead} for backward compatibility:
27+
* {@code automaticMergeHead == true} → {@code AUTO}, {@code automaticMergeHead == false} → {@code NONE}.
28+
* </p>
29+
*
30+
* @see org.apache.fesod.excel.write.metadata.WriteBasicParameter#getHeaderMergeStrategy()
31+
* @see org.apache.fesod.excel.write.builder.AbstractExcelWriterParameterBuilder#headerMergeStrategy(HeaderMergeStrategy)
32+
*/
33+
public enum HeaderMergeStrategy {
34+
/**
35+
* No automatic merge
36+
*/
37+
NONE,
38+
39+
/**
40+
* Only horizontal merge (same cells in the same row)
41+
*/
42+
HORIZONTAL_ONLY,
43+
44+
/**
45+
* Only vertical merge (same cells in the same column).
46+
*/
47+
VERTICAL_ONLY,
48+
49+
/**
50+
* Only full rectangle merge (all cells must form a complete rectangle with the same name)
51+
*/
52+
FULL_RECTANGLE,
53+
54+
/**
55+
* Auto merge (default behavior for backward compatibility).
56+
*/
57+
AUTO
58+
}

fesod/src/main/java/org/apache/fesod/sheet/write/builder/AbstractExcelWriterParameterBuilder.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import java.util.ArrayList;
2323
import java.util.Collection;
24+
import org.apache.fesod.sheet.enums.HeaderMergeStrategy;
2425
import org.apache.fesod.sheet.metadata.AbstractParameterBuilder;
2526
import org.apache.fesod.sheet.write.handler.WriteHandler;
2627
import org.apache.fesod.sheet.write.metadata.WriteBasicParameter;
@@ -88,6 +89,18 @@ public T automaticMergeHead(Boolean automaticMergeHead) {
8889
return self();
8990
}
9091

92+
/**
93+
* Set header merge strategy.
94+
* If not set, the behavior is determined by {@link #automaticMergeHead} for backward compatibility.
95+
*
96+
* @param strategy Header merge strategy
97+
* @return this
98+
*/
99+
public T headerMergeStrategy(HeaderMergeStrategy strategy) {
100+
parameter().setHeaderMergeStrategy(strategy);
101+
return self();
102+
}
103+
91104
/**
92105
* Ignore the custom columns.
93106
*/

fesod/src/main/java/org/apache/fesod/sheet/write/metadata/WriteBasicParameter.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import lombok.EqualsAndHashCode;
2626
import lombok.Getter;
2727
import lombok.Setter;
28+
import org.apache.fesod.sheet.enums.HeaderMergeStrategy;
2829
import org.apache.fesod.sheet.metadata.BasicParameter;
2930
import org.apache.fesod.sheet.write.handler.WriteHandler;
3031

@@ -57,6 +58,11 @@ public class WriteBasicParameter extends BasicParameter {
5758
* Whether to automatically merge headers.Default is true.
5859
*/
5960
private Boolean automaticMergeHead;
61+
/**
62+
* Header merge strategy.
63+
* If null, the behavior is determined by {@link #automaticMergeHead} for backward compatibility.
64+
*/
65+
private HeaderMergeStrategy headerMergeStrategy;
6066
/**
6167
* Ignore the custom columns.
6268
*/

fesod/src/main/java/org/apache/fesod/sheet/write/metadata/holder/AbstractWriteHolder.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import org.apache.fesod.sheet.converters.ConverterKeyBuild;
3838
import org.apache.fesod.sheet.converters.DefaultConverterLoader;
3939
import org.apache.fesod.sheet.enums.HeadKindEnum;
40+
import org.apache.fesod.sheet.enums.HeaderMergeStrategy;
4041
import org.apache.fesod.sheet.event.NotRepeatExecutor;
4142
import org.apache.fesod.sheet.metadata.AbstractHolder;
4243
import org.apache.fesod.sheet.metadata.Head;
@@ -92,6 +93,11 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ
9293
* Whether to automatically merge headers.Default is true.
9394
*/
9495
private Boolean automaticMergeHead;
96+
/**
97+
* Header merge strategy.
98+
* If null, the behavior is determined by {@link #automaticMergeHead} for backward compatibility.
99+
*/
100+
private HeaderMergeStrategy headerMergeStrategy;
95101

96102
/**
97103
* Ignore the custom columns.
@@ -201,6 +207,17 @@ public AbstractWriteHolder(WriteBasicParameter writeBasicParameter, AbstractWrit
201207
this.automaticMergeHead = writeBasicParameter.getAutomaticMergeHead();
202208
}
203209

210+
if (writeBasicParameter.getHeaderMergeStrategy() == null) {
211+
if (parentAbstractWriteHolder == null) {
212+
// Backward compatibility: if headerMergeStrategy is not set, use automaticMergeHead
213+
this.headerMergeStrategy = null;
214+
} else {
215+
this.headerMergeStrategy = parentAbstractWriteHolder.getHeaderMergeStrategy();
216+
}
217+
} else {
218+
this.headerMergeStrategy = writeBasicParameter.getHeaderMergeStrategy();
219+
}
220+
204221
if (writeBasicParameter.getExcludeColumnFieldNames() == null && parentAbstractWriteHolder != null) {
205222
this.excludeColumnFieldNames = parentAbstractWriteHolder.getExcludeColumnFieldNames();
206223
} else {
@@ -517,6 +534,15 @@ public boolean automaticMergeHead() {
517534
return getAutomaticMergeHead();
518535
}
519536

537+
@Override
538+
public HeaderMergeStrategy headerMergeStrategy() {
539+
// Backward compatibility: if headerMergeStrategy is null, determine based on automaticMergeHead
540+
if (headerMergeStrategy == null) {
541+
return automaticMergeHead ? HeaderMergeStrategy.AUTO : HeaderMergeStrategy.NONE;
542+
}
543+
return headerMergeStrategy;
544+
}
545+
520546
@Override
521547
public boolean orderByIncludeColumn() {
522548
return getOrderByIncludeColumn();

fesod/src/main/java/org/apache/fesod/sheet/write/metadata/holder/WriteHolder.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
package org.apache.fesod.sheet.write.metadata.holder;
2121

2222
import java.util.Collection;
23+
import org.apache.fesod.sheet.enums.HeaderMergeStrategy;
2324
import org.apache.fesod.sheet.metadata.ConfigurationHolder;
2425
import org.apache.fesod.sheet.write.property.ExcelWriteHeadProperty;
2526

@@ -59,6 +60,14 @@ public interface WriteHolder extends ConfigurationHolder {
5960
*/
6061
boolean automaticMergeHead();
6162

63+
/**
64+
* Get header merge strategy.
65+
* If null, the behavior is determined by {@link #automaticMergeHead()} for backward compatibility.
66+
*
67+
* @return Header merge strategy
68+
*/
69+
HeaderMergeStrategy headerMergeStrategy();
70+
6271
/**
6372
* Writes the head relative to the existing contents of the sheet. Indexes are zero-based.
6473
*

0 commit comments

Comments
 (0)