Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
0a750f2
docs: replace screenshots with inline HTML tables in write/fill docs
nkuprins Jul 28, 2026
32deab3
docs: move spreadsheet grid styles into their own stylesheet
nkuprins Jul 31, 2026
cd89259
docs: shorten result tables in write/style
nkuprins Jul 31, 2026
b5a532a
docs: document placeholder syntax in fill
nkuprins Jul 31, 2026
b75d11c
docs: shorten result table in write/format
nkuprins Jul 31, 2026
27f5c2d
docs: show the result of every header merge strategy
nkuprins Jul 31, 2026
018e489
docs: rewrite write/image around image sources
nkuprins Jul 31, 2026
7d4f0d1
docs: cover include-column order and index gaps in write/pojo
nkuprins Jul 31, 2026
bdb7574
docs: add sheet tabs to write/sheet results
nkuprins Jul 31, 2026
0ec9035
docs: add the result grid to write/simple
nkuprins Jul 31, 2026
2ab289d
docs: replace the last write/extra screenshots with grids
nkuprins Jul 31, 2026
cd481c6
docs: drop the write screenshots replaced by inline grids
nkuprins Jul 31, 2026
5dc0b4d
Merge branch 'main' into docs/inline-spreadsheet-tables
nkuprins Jul 31, 2026
5fd567e
docs: drop the fill screenshots replaced by inline grids
nkuprins Jul 31, 2026
aecc7f4
Merge branch 'main' into docs/inline-spreadsheet-tables
delei Aug 2, 2026
60ff3d0
style: update xl-sheet styles and enhance dark theme support
delei Aug 2, 2026
c664205
docs: update comment text and wrap tables with container div
delei Aug 2, 2026
3dfd9c3
docs: update comment text and wrap tables with container div
delei Aug 2, 2026
1d4c081
chore: update markdownlint configuration formatting and allowed elements
delei Aug 2, 2026
bd4d3f5
style: update colors and refine layout styles
delei Aug 2, 2026
3864f96
docs: enhance image writing documentation and fix formatting issues
delei Aug 2, 2026
35fbac1
Merge branch 'docs/inline-spreadsheet-tables' of https://github.com/n…
delei Aug 2, 2026
7c9ff56
style: update background color styling in table cells
delei Aug 2, 2026
425abf0
style: fix table row class attribute in image markdown files
delei Aug 2, 2026
31d66ce
style: set default text color for table cells
delei Aug 2, 2026
9fc8e9e
Merge branch 'main' into docs/inline-spreadsheet-tables
delei Aug 3, 2026
674d864
docs: remove merged cells from extra information description
delei Aug 3, 2026
70ae2ba
docs: add data list example and update table layout
delei Aug 3, 2026
f7cc3d3
fix: correct typo in image.md
delei Aug 3, 2026
6e0fbf3
Merge branch 'docs/inline-spreadsheet-tables' of https://github.com/n…
delei Aug 3, 2026
77e28bc
chore: remove duplicate img entry from MD033 allowed_elements
nkuprins Aug 3, 2026
f6c5956
fix: replace Chinese commas with ASCII commas in English fill.md
nkuprins Aug 3, 2026
90ebbcc
fix: correct fetch policies wording
nkuprins Aug 3, 2026
4323557
fix: wrap zh-cn image grids in the sheet container
nkuprins Aug 3, 2026
81d1364
style: add border-radius and margin-left styles
delei Aug 4, 2026
34ba77d
Merge branch 'main' into docs/inline-spreadsheet-tables
bengbengbalabalabeng Aug 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 22 additions & 6 deletions website/.markdownlint-cli2.jsonc
Original file line number Diff line number Diff line change
@@ -1,23 +1,39 @@
{
"globs": ["website/**/*.md"],
"globs": [
"website/**/*.md"
],
"config": {
"default": true,
"MD001": true,
"MD003": true,
"MD022": false,
"MD041": false,
"MD013": {
"line_length": 600,
"code_blocks": false,
"tables": false
"line_length": 600,
"code_blocks": false,
"tables": false
},
"MD024": {
"siblings_only": true
"siblings_only": true
},
"MD025": false,
"MD029": true,
"MD033": {
"allowed_elements": ["table", "tr", "td", "a", "img", "sub", "b", "br", "img", "tbody", "mark", "font"]
"allowed_elements": [
"div",
"table",
"tr",
"td",
"a",
"img",
"sub",
"b",
"br",
"tbody",
"mark",
"font",
"p"
]
Comment thread
nkuprins marked this conversation as resolved.
},
"MD036": false,
"MD040": true,
Expand Down
256 changes: 237 additions & 19 deletions website/docs/sheet/fill/fill.md

Large diffs are not rendered by default.

141 changes: 65 additions & 76 deletions website/docs/sheet/write/extra.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ title: 'Extra'

# Extra Information

This chapter introduces how to write extra information such as comments, hyperlinks, formulas, merged cells, etc.
This chapter introduces how to write extra information such as comments, hyperlinks, formulas, etc.

## Comments

Expand All @@ -46,7 +46,7 @@ public class CommentWriteHandler implements RowWriteHandler {
// Create comment in first row, second column
Comment comment = drawingPatriarch.createCellComment(
new XSSFClientAnchor(0, 0, 0, 0, (short) 1, 0, (short) 2, 1));
comment.setString(new XSSFRichTextString("批注内容"));
comment.setString(new XSSFRichTextString("Comments"));
sheet.getRow(0).getCell(1).setCellComment(comment);
}
}
Expand All @@ -63,14 +63,27 @@ public void commentWrite() {
FesodSheet.write(fileName, DemoData.class)
.inMemory(Boolean.TRUE) // Comments must enable in-memory mode
.registerWriteHandler(new CommentWriteHandler())
.sheet("批注示例")
.sheet()
.doWrite(data());
}
```

### Result

![img](/img/docs/write/commentWrite.png)
The comment is attached to `B1` and is only shown when that cell is hovered.

<div class="xl-sheet-container">
<table class="xl-sheet xl-sheet--overlay">
<tbody>
<tr><td class="xl-chrome"></td><td class="xl-chrome">A</td><td class="xl-chrome">B</td><td class="xl-chrome">C</td></tr>
<tr><td class="xl-chrome">1</td><td class="xl-head">String Title</td><td class="xl-head xl-comment-anchor">Date Title<b class="xl-comment">Comments</b></td><td class="xl-head">Number Title</td></tr>
<tr><td class="xl-chrome">2</td><td>String0</td><td class="xl-num">2026-07-31 20:50:23</td><td class="xl-num">0.56</td></tr>
<tr><td class="xl-chrome">3</td><td>String1</td><td class="xl-num">2026-07-31 20:50:23</td><td class="xl-num">0.56</td></tr>
<tr><td class="xl-chrome">⋮</td><td class="xl-muted">…</td><td class="xl-muted">…</td><td class="xl-muted">…</td></tr>
<tr><td class="xl-chrome">11</td><td>String9</td><td class="xl-num">2026-07-31 20:50:23</td><td class="xl-num">0.56</td></tr>
</tbody>
</table>
</div>

---

Expand Down Expand Up @@ -112,7 +125,15 @@ public void writeHyperlinkDataWrite() {

### Result

![img](/img/docs/write/writeCellDataWrite.png)
<div class="xl-sheet-container">
<table class="xl-sheet">
<tbody>
<tr><td class="xl-chrome"></td><td class="xl-chrome">A</td></tr>
<tr><td class="xl-chrome">1</td><td class="xl-head">hyperlink</td></tr>
<tr><td class="xl-chrome">2</td><td><a href="https://example.com">Click to visit</a></td></tr>
</tbody>
</table>
</div>

---

Expand Down Expand Up @@ -155,7 +176,15 @@ public void writeFormulaDataWrite() {

### Result

![img](/img/docs/write/writeCellDataWrite.png)
<div class="xl-sheet-container">
<table class="xl-sheet">
<tbody>
<tr><td class="xl-chrome"></td><td class="xl-chrome">A</td></tr>
<tr><td class="xl-chrome">1</td><td class="xl-head">formulaData</td></tr>
<tr><td class="xl-chrome">2</td><td>=SUM(A1:A10)</td></tr>
</tbody>
</table>
</div>

---

Expand All @@ -182,45 +211,25 @@ public void templateWrite() {

---

## Merged Cells
## Custom Interceptors

### Overview

Supports merged cells through annotations or custom merge strategies.
Implement custom logic (such as adding dropdowns) through interceptor operations.

### Code Example

Annotation approach

```java
@Getter
@Setter
@EqualsAndHashCode
public class DemoMergeData {
@ContentLoopMerge(eachRow = 2) // Merge every 2 rows
@ExcelProperty("字符串标题")
private String string;

@ExcelProperty("日期标题")
private Date date;

@ExcelProperty("数字标题")
private Double doubleData;
}
```

Custom merge strategy
Setting dropdowns

```java
public class CustomMergeStrategy extends AbstractMergeStrategy {
public class DropdownWriteHandler implements SheetWriteHandler {
@Override
protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {
// merge method will be called for each cell, ensuring that the same cell is merged only once
if (relativeRowIndex != null && relativeRowIndex % 2 == 0 && head.getColumnIndex() == 0) {
int startRow = relativeRowIndex + 1; // Row 0 is the header, data starts from row 1
int endRow = startRow + 1; // Merge current row and next row
sheet.addMergedRegion(new CellRangeAddress(startRow, endRow, 0, 0));
}
public void afterSheetCreate(SheetWriteHandlerContext context) {
DataValidationHelper helper = context.getWriteSheetHolder().getSheet().getDataValidationHelper();
CellRangeAddressList range = new CellRangeAddressList(1, 10, 0, 0); // Dropdown area
DataValidationConstraint constraint = helper.createExplicitListConstraint(new String[] {"Option1", "Option2"});
DataValidation validation = helper.createValidation(constraint, range);
context.getWriteSheetHolder().getSheet().addValidationData(validation);
}
}
```
Expand All @@ -229,51 +238,31 @@ Usage

```java
@Test
public void mergeWrite() {
String fileName = "mergeWrite" + System.currentTimeMillis() + ".xlsx";

// Annotation approach
FesodSheet.write(fileName, DemoMergeData.class)
.sheet("合并示例")
.doWrite(data());
public void dropdownWrite() {
String fileName = "dropdownWrite" + System.currentTimeMillis() + ".xlsx";

// Custom merge strategy
FesodSheet.write(fileName, DemoData.class)
.registerWriteHandler(new CustomMergeStrategy())
.sheet("自定义合并")
.registerWriteHandler(new DropdownWriteHandler())
.sheet("Dropdown Example")
.doWrite(data());
}
```

### Result

![img](/img/docs/write/mergeWrite.png)

---

## Custom Interceptors

### Overview

Implement custom logic (such as adding dropdowns) through interceptor operations.

### Code Example

Setting dropdowns

```java
public class DropdownWriteHandler implements SheetWriteHandler {
@Override
public void afterSheetCreate(SheetWriteHandlerContext context) {
DataValidationHelper helper = context.getWriteSheetHolder().getSheet().getDataValidationHelper();
CellRangeAddressList range = new CellRangeAddressList(1, 10, 0, 0); // Dropdown area
DataValidationConstraint constraint = helper.createExplicitListConstraint(new String[] {"选项1", "选项2"});
DataValidation validation = helper.createValidation(constraint, range);
context.getWriteSheetHolder().getSheet().addValidationData(validation);
}
}
```

### Result

![img](/img/docs/write/customHandlerWrite.png)
The validation covers `A2:A11`, so every cell in that range offers the list. Selecting one shows the
dropdown button and its options - drawn open here on `A2`.

<div class="xl-sheet-container">
<table class="xl-sheet xl-sheet--overlay">
<tbody>
<tr><td class="xl-chrome"></td><td class="xl-chrome">A</td><td class="xl-chrome">B</td><td class="xl-chrome">C</td></tr>
<tr><td class="xl-chrome">1</td><td class="xl-head">String Title</td><td class="xl-head">Date Title</td><td class="xl-head">Number Title</td></tr>
<tr><td class="xl-chrome">2</td><td class="xl-dropdown">String0<b class="xl-dropdown-btn">▾</b><b class="xl-dropdown-list"><b>Option1</b><b>Option2</b></b></td><td class="xl-num">2026-07-31 20:50:23</td><td class="xl-num">0.56</td></tr>
<tr><td class="xl-chrome">3</td><td>String1</td><td class="xl-num">2026-07-31 20:50:23</td><td class="xl-num">0.56</td></tr>
<tr><td class="xl-chrome">4</td><td>String2</td><td class="xl-num">2026-07-31 20:50:23</td><td class="xl-num">0.56</td></tr>
<tr><td class="xl-chrome">⋮</td><td class="xl-muted">…</td><td class="xl-muted">…</td><td class="xl-muted">…</td></tr>
<tr><td class="xl-chrome">11</td><td>String9</td><td class="xl-num">2026-07-31 20:50:23</td><td class="xl-num">0.56</td></tr>
</tbody>
</table>
</div>
22 changes: 17 additions & 5 deletions website/docs/sheet/write/format.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,15 @@ Supports date, number, or other custom formats through annotations.
@Setter
@EqualsAndHashCode
public class ConverterData {
@ExcelProperty(value = "字符串标题", converter = CustomStringStringConverter.class)
@ExcelProperty(value = "String Title", converter = CustomStringStringConverter.class)
private String string;

@DateTimeFormat("yyyy年MM月dd日HH时mm分ss秒")
@ExcelProperty("日期标题")
@DateTimeFormat("yyyy/MM/dd HH:mm:ss")
@ExcelProperty("Date Title")
private Date date;

@NumberFormat("#.##%")
@ExcelProperty("数字标题")
@ExcelProperty("Number Title")
private Double doubleData;
}
```
Expand All @@ -64,4 +64,16 @@ public void converterWrite() {

### Result

![img](/img/docs/write/converterWrite.png)
<div class="xl-sheet-container">
<table class="xl-sheet">
<tbody>
<tr><td class="xl-chrome"></td><td class="xl-chrome">A</td><td class="xl-chrome">B</td><td class="xl-chrome">C</td></tr>
<tr><td class="xl-chrome">1</td><td class="xl-head">String Title</td><td class="xl-head">Date Title</td><td class="xl-head">Number Title</td></tr>
<tr><td class="xl-chrome">2</td><td>Custom: String0</td><td>2024/12/03 20:50:23</td><td class="xl-num">56.%</td></tr>
<tr><td class="xl-chrome">3</td><td>Custom: String1</td><td>2024/12/03 20:50:23</td><td class="xl-num">56.%</td></tr>
<tr><td class="xl-chrome">4</td><td>Custom: String2</td><td>2024/12/03 20:50:23</td><td class="xl-num">56.%</td></tr>
<tr><td class="xl-chrome">⋮</td><td class="xl-muted">…</td><td class="xl-muted">…</td><td class="xl-muted">…</td></tr>
<tr><td class="xl-chrome">11</td><td>Custom: String9</td><td>2024/12/03 20:50:23</td><td class="xl-num">56.%</td></tr>
</tbody>
</table>
</div>
Loading