脚本与表达式示例
按场景整理的表达式与脚本写法:汇总与占比、序号与排名、文本拼接与脱敏、日期与年龄、参数默认值、与上一行比较、后处理脚本、计算字段和 SQL 模板。
概述
本篇按场景给出可直接套用的写法。每个示例写明放在哪里、怎么写、得到什么结果。示例里的单元格名称(B2、C2)和数据集字段请换成自己报表里的。语法与函数说明见 报表基本语法 和 内置函数总览。
假设有一张门诊报表:A2 是科室,B2 是金额,都是绑定数据集后向下扩展的单元格;第 1 行是表头。
| 科室 | 金额 |
|---|---|
| 内科 | 300 |
| 外科 | 500 |
| 口腔 | 200 |
汇总与占比
合计
位置:合计行的单元格,类型选「公式」。
sum(B2)
结果:1000。
平均与个数
sum(B2) / count(B2)
结果:约 333.33。要保留两位小数,再套 round(参数类型要求见 数学函数),或在单元格格式里设置小数位数。
占比
位置:数据行的第三列。
B2 / sum(B2[!0])
结果:0.3、0.5、0.2。B2 是本行金额,B2[!0] 是整列金额,格式设为百分比后显示 30%、50%、20%。
最大值
max(B2[!0])
结果:500。
序号与排名
行序号
位置:数据行左侧的公式单元格。
&B2
结果:1、2、3。&B2 是 B2 展开后的序号,比 seq() 稳定。
金额排名
位置:数据行第三列。
rank(B2[!0], B2)
结果:3、1、2(金额大的名次靠前)。改成升序:rank(B2[!0], B2, 'asc')。并列同名次,之后跳号。
文本
拼接
A2 + ':' + B2 + ' 元'
结果:内科:300 元。
为空显示横杠
ifEmpty(A2, '-')
取前几位、姓名脱敏
位置:姓名格。
left(A2::string, 1) + '**'
结果:姓名 张三 显示 张**。
手机号中间四位隐藏
left(A2::string, 3) + '****' + right(A2::string, 4)
结果:13812345678 显示 138****5678。
多个字段用分隔符连接,忽略空值
joinIfNotEmpty('-', A2, B2, C2)
结果:A2 为 内科,B2 为空,C2 为 1 时得 内科-1。
金额大写
toChineseAmount(B2)
结果:B2 为 123.45 时得 壹佰贰拾叁元肆角伍分。
日期
标题里的日期范围
位置:标题单元格,报表有参数 startDate、endDate(日期类型)。
'就诊日期:' + formatDate($startDate, 'yyyy-MM-dd') + ' 至 ' + formatDate($endDate, 'yyyy-MM-dd')
结果:就诊日期:2026-01-01 至 2026-01-31。
制表日期
'制表日期:' + date()
年龄
位置:C2 是出生日期(日期类型)。
betweenYears(C2, now())
结果:满几周岁。
本月月初到今天
formatDate(monthStart(now()), 'yyyy-MM-dd') + ' 至 ' + date()
参数默认值
位置:「查询参数设置」,默认值模式选「表达式」。
| 需求 | 表达式 |
|---|---|
| 开始日期默认为 7 天前 | addDays(now(), -7) |
| 开始日期默认为本月月初 | monthStart(now()) |
| 结束日期默认为今天 | 日期预设选「当天」,无需表达式 |
| 用户默认为当前登录人 | userAccount() |
详见 报表参数。
与其他行、其他单元格对比
与上一行比较、算环比
位置:数据行第三列。
(B2 - cellOffset('B2', -1, 0)) / cellOffset('B2', -1, 0)
结果:第一行的上一行是表头,得空值;第二行 (500 - 300) / 300,约 0.667。上一行为 0 时除法得空值。cellOffset 见 报表与数据集函数。
按科室汇总某数据集的金额
sum(datasetSelect('门诊', '金额', '科室', A2))
结果:数据集「门诊」中,与 A2 同科室的金额之和。
数据集行数
dataset('门诊').size()
条件
三元取值
B2 >= 400 ? '高' : '低'
多分支
B2 >= 400 ? '高' : (B2 >= 250 ? '中' : '低')
结果:300 得 中,500 得 高,200 得 低。
多行脚本写法
if (B2 >= 400) {
return '高'
} else if (B2 >= 250) {
return '中'
} else {
return '低'
}
多行脚本必须用 return。
条件渲染中的公式条件
各条件渲染的写法(隔行变色、负数标红、隐藏行、脱敏)见 条件渲染。
数据集后处理脚本
位置:数据集编辑页「后处理脚本」,SQL 或 API 数据集。
只保留成年人,按金额从高到低排序
return $$data.filter(item => item.age >= 18).sort((a, b) => b.amount - a.amount);
按参数筛选
数据集有参数 dept:
return $$data.filter(item => item.dept == $dept)
汇总检查
import log
var total = 0
for (item in $$data) { total = total + item.amount }
log.info('本次取数金额合计 {}', total)
return $$data
返回原数据,同时把合计写到服务端日志。完整说明见 后处理脚本与计算字段。
数据集计算字段
位置:数据集编辑页「计算字段」。受限语法,只能用加减乘除和白名单函数,见 脚本使用指南。
| 字段名 | 表达式 | 说明 |
|---|---|---|
| 金额 | $$record.数量 * $$record.单价 |
乘法 |
| 全名 | concat($$record.姓, $$record.名) |
拼接 |
| 折后价 | round($$record.单价 * (1 - ifNull($$record.折扣, 0)), 2) |
空折扣按 0 |
| 年份 | year($$record.就诊日期) |
取年 |
SQL 模板
位置:SQL 数据集。
日期范围与科室多选
select * from 门诊
where 就诊日期 >= $startDate
and 就诊日期 <= $endDate
and 科室 in ($deptList)
deptList 是集合参数,展开为 ?,?,...;没选任何科室时展开为 NULL,条件不命中任何行。
动态排序列
select * from 门诊 order by #{$sortField}
#{} 把内容直接拼进 SQL,只用于表名、列名这类无法绑定的位置,且内容来自可信来源,避免 SQL 注入。详见 SQL 参数与动态语法。
页脚页码
页脚文本:
'第 ' + page() + ' 页,共 ' + pageCount() + ' 页'
分页导出(PDF、Word)后为真实页码;网格预览恒为 1 和 1。