Skip to content

Commit df08e7f

Browse files
committed
docs: synced via GitHub Actions
1 parent df1cc5c commit df08e7f

18 files changed

+147
-0
lines changed
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
## Excel 图表(Chart)动态数据绑定开发指引
2+
3+
本文介绍如何在 Excel 模板中通过图表的“可选文字”(Alt Text,对应模型字段 description/descr)配置图表的动态数据来源与行为,重点说明:
4+
5+
- 在可选文字中以简洁的 key=value 语法配置动态绑定(dynamicBindings)
6+
- 通过 seriesTestExpr 决定最终生成哪些系列(series),并要求在模板中预先准备“最多可能需要”的系列数
7+
- 在表达式中使用 seriesModel.index 获取当前系列的 0 基索引
8+
- 利用 seriesDataCellRefExpr 等表达式动态计算 Excel 单元格引用;表达式内可直接调用 IXptRuntime.buildCellRef 助手函数
9+
10+
11+
![在图表可选文字里填写动态绑定](./excel-chart/excel-chart-config.png)
12+
13+
14+
## 在 Excel 中写“descr”(可选文字)
15+
16+
右键图表 →“编辑可选文字”,将描述与配置写在同一文本框中:
17+
18+
- “----” 之前的内容为人类可读的描述,将保留到模型的 description 字段
19+
- “----” 之后按多行 key=value 写配置,解析为 ChartModel.dynamicBindings
20+
21+
语法规则(由 MultiLineConfigParser 解析):
22+
23+
- 每行一个配置项,形如 key = value
24+
- 字符串可直接写;如包含换行可用 """ 多行字符串 """ 包裹;或用 `反引号字符串`
25+
26+
最小示例:
27+
28+
```
29+
我的销售图表
30+
----
31+
chartTitleCellRefExpr = `Sheet1!$A$1`
32+
seriesTestExpr = `series.index < 3`
33+
seriesDataCellRefExpr= `xptRt.buildCellRef("Sheet1!$B$2:$B$101", 0, series.index, 0, 0)`
34+
seriesCatCellRefExpr = `Sheet1!$A$2:$A$101`
35+
```
36+
37+
上述配置效果:
38+
39+
- 图表标题引用 Sheet1!$A$1
40+
- 仅生成 index 为 0、1、2 的三个系列
41+
- X 轴分类统一引用 A2:A101
42+
43+
44+
## dynamicBindings 可配置项与签名
45+
46+
可在“----”之后配置以下常用表达式(更多项见 schema:/nop/schema/excel/chart.xdef 的 <dynamicBindings>):
47+
48+
- chartTestExpr: (chartModel) => boolean
49+
- 决定是否生成整个图表
50+
- chartTitleCellRefExpr: (chartModel) => string
51+
- chartTitleExpr: (chartModel) => string
52+
- 标题可用单元格引用或直接文本(二选一)。若 cellRefExpr 返回非空,则优先按单元格;否则尝试 titleExpr 文本
53+
- seriesTestExpr: (seriesModel, chartModel) => boolean
54+
- 决定某个系列是否保留(返回 true 保留)
55+
- seriesNameCellRefExpr | seriesNameExpr: (seriesModel, chartModel) => string
56+
- seriesDataCellRefExpr | seriesDataExpr: (seriesModel, chartModel) => string/any
57+
- seriesCatCellRefExpr | seriesCatExpr: (seriesModel, chartModel) => string/any
58+
- axisDataCellRefExpr: (axisModel, chartModel) => string
59+
- axisTitleCellRefExpr | axisTitleExpr: (axisModel, chartModel) => string
60+
61+
引擎行为(参见 ExpandedSheetChartGenerator):
62+
63+
-*CellRefExpr 返回非空*,则覆盖模板中相应的单元格引用
64+
- 若返回空,则保留模板原值;对于标题/名称,若 cellRef 为空则再尝试 *Expr* 返回直接文本
65+
66+
67+
## seriesTestExpr 与“模板需预置最多的 series 数”
68+
69+
- 运行时不会“新增”系列,只会基于模板中已有系列做“保留/删除”。
70+
- 因此必须在模板中预先设计“最多可能需要”的系列数量(例如最多 5 条线),运行期用 seriesTestExpr 过滤超出的系列。
71+
- 例:若数据集只有 3 条线,且模板预置 5 个系列,则可以配置
72+
73+
74+
75+
## seriesModel.index(从 0 开始)
76+
77+
- 引擎在加载模板时会为系列自动编号:0、1、2、…(详见 ExcelChartModel.init 与 ChartPlotAreaParser)
78+
- 在所有系列相关表达式中可通过 series.index 取得该序号,用于偏移列/行、拼接名称等
79+
80+
81+
## 动态生成单元格引用:xptRt.buildCellRef
82+
83+
表达式中可直接返回:
84+
85+
- A1 或 A1:B10 形式的字符串(可包含 Sheet! 前缀)
86+
- 或返回 IXptRuntime.buildCellRef 的结果对象,系统会自动转为字符串
87+
88+
buildCellRef 签名:
89+
90+
- buildCellRef(cellRefTpl, rowOffset, colOffset, rowSize, colSize) ⇒ ExcelCellRef
91+
92+
典型用法:
93+
94+
1) 按列横向扩展系列(多系列共用一段模板区域,每个系列向右偏移一列)
95+
96+
```
97+
seriesDataCellRefExpr = `xptRt.buildCellRef("Sheet1!$B$2:$B$101", 0, series.index, 0, 0)`
98+
99+
```
100+
101+
2) 按行向下滚动(每个系列向下偏移固定行数)
102+
103+
```
104+
seriesDataCellRefExpr = `xptRt.buildCellRef("Sheet1!$B$2:$B$21", series.index*20, 0, 0, 0)`
105+
```
106+
107+
108+
## 标题与坐标轴的动态绑定
109+
110+
```
111+
chartTitleCellRefExpr = `Sheet1!$D$1`
112+
chartTitleExpr = `销售额走势`
113+
114+
```
115+
116+
注意:当 cellRefExpr 返回非空时,titleExpr 将被忽略。
117+
118+
119+
## 支持的图表示例
120+
121+
以下为部分效果图(模板+绑定后均可用):
122+
123+
- 柱/条形:![clustered-column](./excel-chart/clustered-column-chart.png) ![stacked-column](./excel-chart/stacked-column-chart.png) ![100pct-stacked-column](./excel-chart/100pct-stacked-column-chart.png)
124+
- 折线:![line](./excel-chart/line-chart.png) ![line-markers](./excel-chart/line-with-markers-chart.png)
125+
- 面积:![area](./excel-chart/area-chart.png) ![stacked-area](./excel-chart/stacked-area-chart.png) ![100pct-stacked-area](./excel-chart/100pct-stacked-area-chart.png)
126+
- 饼/环:![pie](./excel-chart/pie-chart.png) ![doughnut](./excel-chart/doughnut-chart.png)
127+
- 雷达/散点:![radar](./excel-chart/radar-chart.png) ![filled-radar](./excel-chart/filled-radar-chart.png) ![scatter](./excel-chart/scatter-chart.png) ![scatter-lines](./excel-chart/scatter-with-lines-chart.png)
128+
129+
130+
## 参考与实现位置
131+
132+
- XDef(schema):`/nop/schema/excel/chart.xdef``<dynamicBindings>` 段定义了所有可用表达式与签名
133+
- 模型与生成:`io.nop.report.core.engine.ExpandedSheetChartGenerator`(动态绑定的执行逻辑)
134+
- “可选文字”解析:`io.nop.report.core.build.ExcelToXptModelTransformer#parseChartModel`(以 "----" 分隔描述与配置;key=value 逐项解析)
135+
- 运行期上下文:`io.nop.report.core.engine.IXptRuntime`(表达式作用域变量名为 `xptRt`;提供 `buildCellRef``ds` 等方法)
136+
- 图表解析/构建(OOXML):`nop-format/nop-ooxml/nop-ooxml-xlsx` 模块下 `io.nop.ooxml.xlsx.chart.*`(Parser/Builder)
137+
138+
139+
## 小贴士(常见问题)
140+
141+
- 必须在模板中预置最多的系列(series),运行时不会创建超过模板数量的新系列
142+
- 返回 null 或空字符串会保留模板中的默认引用/文本
143+
- 返回 ExcelCellRef 或 A1/A1:A10 字符串均可;若需要包含工作表名,建议写 Sheet!$A$1:$A$10
144+
- seriesModel.index 从 0 开始
145+
146+
完成以上配置后,导出时引擎会根据可选文字中的 dynamicBindings 自动计算标题、分类、数据等引用,并按需过滤系列,达到“模板一次设计、运行多场景复用”的效果。
147+
30.2 KB
Loading
18.2 KB
Loading
20.4 KB
Loading
16.1 KB
Loading
18.2 KB
Loading
23.4 KB
Loading
37.9 KB
Loading
32.6 KB
Loading
51.9 KB
Loading

0 commit comments

Comments
 (0)