文档首页 / 报表基本语法

报表基本语法

报表表达式的语法规则:单元格、数据集字段和参数的引用写法,字面量,运算符与优先级,文本与数值运算规则,类型转换,空值和真假判断。

概述

报表表达式是一段写在单元格、条件或参数里的小程序,算出一个值。语法与 JavaScript 接近,加上了报表特有的引用写法:A1(单元格)、$name(参数)、$$record.字段(数据集字段)。本文说明这些写法本身;表达式可以放在哪些位置见 表达式概述,可调用的函数见 内置函数总览,多行脚本见 脚本使用指南。

在单元格或公式栏中直接输入时,以 = 开头才会成为公式单元格(= 不属于表达式,保存时被去掉);「数据」标签的「内容公式」输入框直接写表达式,不带 =。见 单元格基础。

一段只含一个表达式的脚本,其值自动作为结果返回;含多条语句时必须用 return 明确返回。

1 + 2                     // 结果 3
var a = 10; return a * 2  // 多条语句,需要 return,结果 20

单元格引用

在公式里写单元格名称即可取得该单元格计算后的值。名称由 1 到 3 个大写字母加数字组成,如 A1、B12、AA3,后面不能紧跟标识符字符。

写法 含义 返回
A1 单元格 A1 的值 只有一个值时是该值本身;A1 向下或向右扩展出多个值时是包含全部值的列表
A1:B5 矩形区域内所有单元格 展平后的列表
A1[!0] A1 扩展出的全部值,覆盖整张报表,不受当前所在分组限制 始终是列表,即使只有一个值
&A1 A1 展开后的迭代序号,从 1 开始;找不到时为 0 整数

要点:

  • 列表参与 sum、avg、count 等聚合函数时被展开计算,sum(B2) 就是 B2 扩展列的合计。
  • A1[!0] 只有这一种精确写法,必须紧跟单元格名、中间不能有空格;[!1]、[! 0] 等其他形式会报错「组引用只支持 [!0] 写法」。
  • 在自己所属的扩展关系内引用某格(同一行的另一个数据格)得到本行的单个值,跨关系引用得到全部值。扩展关系的规则见 父子格与数据绑定。
  • 引用的单元格值为空时得到 null。

示例:合计行的占比列写 B2 / sum(B2[!0]),其中 B2 是本行的值,sum(B2[!0]) 是整列合计。给数据行编序号写 &B2。

数据集字段引用

数据绑定的单元格,其「数据字段」下的「计算表达式」里,用 $$record 表示当前记录:

写法 含义
$$record.数量 当前记录的「数量」字段
$$record['单价'] 同上,字段名含空格、连字符或特殊字符时使用

示例:金额列的计算表达式写 $$record.数量 * $$record.单价。

要在其他位置读取数据集的整列数据,使用函数 dataset('数据集名', '字段名'),返回该字段所有行的列表,见 报表与数据集函数。

参数引用

报表参数用 $ 加参数名引用:

写法 含义
$startDate 报表参数 startDate 的值
$$config.名称 「系统」>「自定义参数」中配置的全局参数
$$reportVars.名称 报表设置「报表变量」中定义的变量

规则:

  • 参数名请使用英文字母、数字和下划线:在下文「文本中的参数」(不加引号的文字里直接嵌 $参数)里,$ 之后只识别这些字符,中文会被当作普通文字;参数值是对象时,. 之后的成员名可以是中文。
  • 引用未定义的参数,不报错,值为 null。
  • 参数的声明、类型与默认值见 报表参数。

文本中的参数

在文本、标题、页眉等以「文本」形式输入的位置,可以直接把参数嵌进文字里,系统会先把它改写成拼接表达式:

写法 效果
就诊日期从$startDate至$endDate 文字与参数拼接为一段文本
合计:${sum(B2)} ${} 内可以写任意表达式

内置变量

以 $$ 开头的是系统提供的变量,只在特定位置有值,详见 脚本使用指南。

变量 含义 可用位置
$$value 当前单元格的值。数字文本自动转为数值,以 0 开头的编码(如 001)保持文本 条件渲染
$$record 当前数据记录 数据绑定单元格的计算表达式
$$data 数据集的记录列表 数据集后处理脚本
$$config 自定义参数 各处表达式
$$reportVars 报表变量 各处表达式
$$line $$lines $$isFirstLine $$isLastLine 按行拆分打印的当前行、总行数、是否首行、是否末行;默认 0、1、true、true 按行拆分打印

字面量

类型 写法 示例
整数、小数 数字 42、3.14
带类型后缀的数字 b 字节,s 短整型,L 长整型,f 单精度,d 双精度,m BigDecimal 10L、2.5m
十六进制 0x 开头 0xFF
文本 单引号或双引号;双引号内不能换行 '内科'、"内科"
模板文本 反引号,${} 内嵌表达式,可换行 `共${n}行`
多行文本 三个双引号 """多行"""
布尔 true、false
空值 null
列表 方括号 [1, 2, 3]
键值对 花括号 {'k': 1}

注释:// 单行 与 /* 多行 */。

保留关键字:import as var let const return break continue if for in new true false null else try catch finally async while exit and or throw,不能用作变量名。

运算符与优先级

从低到高:

优先级 运算符 说明
1(最低) ? : 三元条件,条件 ? 值1 : 值2
2 =、复合赋值 += -= 等 赋值(= 略低于复合赋值)
3 || or 逻辑或
4 && and 逻辑与
5 | 按位或
6 ^ 按位异或
7 & 按位与
8 == != === !== 相等比较
9 < <= > >= instanceof 大小比较
10 + - 加减、文本连接
11 移位 位移
12 * / % 乘除取余
13(最高) 一元 - + ! ~ ++ -- 单目运算

说明:

  • 用 () 明确顺序,不要依赖优先级记忆。
  • && 与 || 短路求值,返回决定结果的那个操作数本身,不一定是布尔值:'' \|\| '默认' 得 '默认'。
  • 没有 ?: 空值合并写法(Elvis)和 ??,用 ifNull(a, b) 或 a ? a : b。有 ?. 安全导航:a?.b 在 a 为 null 时得 null。
  • <> 只能用于 select ... from 查询语法内;在普通表达式里写 <> 会报错「<> 只能在Linq中使用」,不等于请写 !=。
  • = 是赋值,== 才是相等比较。条件里写 $$value = 1 会把 1 赋给变量,不是比较。

算术与文本连接

加号

+ 有两种含义,按两侧的值决定:

情形 行为 示例 结果
任一侧明确是文本(文本字面量、模板文本、返回文本的函数) 连接文本 '1' + 2 "12"
两侧的值都能解析为数字(如单元格里存的文本 "1" 和 "2") 数值相加 A1 + B1,A1、B1 为 "1"、"2" 3
其他 连接文本 '总计' + A1 总计 加 A1 的文本

需要强制按文本连接时写成 A1::string + B1::string,强制按数值相加写成 A1::double + B1::double。

减、乘、除、取余

- * / % 总是数值运算:

  • 文本先转成数值:"1,234" 得 1234,"12%" 和 "¥1,234.5" 这类带千分位、百分号、货币符号的文本也能解析;空白文本按 null 处理。
  • 文本不是数字(如 'abc')时该运算无法计算,最终结果为 null(默认的严格模式,配置项 app.report.formula.strict-numeric-text,默认 true)。
  • null 作被减数、被除数按 0;作乘数按 1;作除数时(严格模式)结果为 null。
  • 除以 0:/ 得 null;% 抛出错误。
  • 参与运算的一方是列表时,先对列表求和再运算,所以 B2 / 100 在 B2 展开为多个值时,得到列合计除以 100。

比较与逻辑

比较

  • 与 null 比较大小得 false。
  • 文本与数值比较:两边都能解析为数字时按数值比较,'10' > 9 为 true;否则报错。
  • == 只要有一侧是数值,就尝试按数值判等,'1.0' == 1 为 true。
  • 文本之间的 == 按文本判等。

真假判断

条件表达式(if、三元、&&、||、!)用下面的规则把任意值当作布尔值:

值 真假
null、false 假
文本 非空为真,空文本 '' 为假;注意 'false'、'0' 是非空文本,为真
数值 非 0 为真,0 为假
列表、数组、Map 非空为真,空为假
其他 真

注意:条件渲染的公式条件不使用上面的规则,只有结果恰好是布尔 true 或文本 "true" 才算成立。

类型转换

在值后面用 ::类型 转换:

写法 结果类型
x::int 整数
x::long x::short x::byte 长整型、短整型、字节
x::double x::float 双精度、单精度浮点
x::string 文本
x::date('格式') 日期,必须给出格式串,如 'yyyy-MM-dd'

转换失败时返回 null;数值类转换可以给默认值:x::int(0) 失败时返回 0。

示例:

'12'::int                        // 12
'abc'::int                       // null
'abc'::int(0)                    // 0
'2026-01-05'::date('yyyy-MM-dd') // 日期
amount::int                      // 数据集数值列往往是 BigDecimal,作 substring 等函数的整数参数前先转换

类型不匹配导致函数「找不到」的情形见 内置函数总览 的「调用规则」。

空值处理

需求 写法
为空时用默认值 ifNull(x, 0)、ifEmpty(x, '-'),见 逻辑与空值函数
取第一个非空 coalesce(a, b, c)
判断为空 isNull(x)、isEmpty(x)(null、空文本、空集合均为空)
安全访问成员 a?.b
未定义的参数 自动为 null,不报错

各种运算遇到 null 的行为汇总:

  • 聚合函数:sum、avg、max、min 忽略 null 元素;count 的行为见 聚合与集合函数。
  • 日期函数:year(null) 等把 null 当作当前时间,见 日期函数。
  • 比较:与 null 比较大小得 false。
  • 算术:见上文「减、乘、除、取余」。

语句

多行脚本支持 var/let/const 声明变量,if/else、for、while、try/catch/finally、import、return、break/continue。循环形式:

for (item in list) { ... }
for (index, value in list) { ... }
for (var i = 0; i < 3; i++) { ... }

细节与沙箱限制见 脚本使用指南,可直接套用的写法见 脚本与表达式示例。

联系我们

请填写您的信息,我们将在 1 个工作日内与您联系。