本库解析 Microsoft Excel 工作表公式的一个子集,并生成 PostgreSQL 风格的标量表达式。解析使用 ANTLR 4,翻译通过解析树 Visitor 实现。
模块路径: github.com/SolaTyolo/pg-formula — 代码仓库:https://github.com/SolaTyolo/pg-formula。
在 PostgreSQL 生成列或表达式列场景中,真实的表/列在公式里用输入侧的 {{…}} 表示(如 {{a1}}、{{table.a1}}),会编译成不加引号的 SQL 片段(a1、table.a1)。裸标识符 table.a1(无花括号)则生成一个双引号标识符 "table.a1"(名字里带点的单列名),适用于 CONCAT 等“整段字面名”语义,而不是 table 表上的 a1 列。
- Go 1.22+
- 修改
grammar/ExcelFormula.g4后重新生成词法/语法分析器:- Java 运行环境
- ANTLR 4.13.2 的 JAR,见
tools/antlr-4.13.2-complete.jar - 在仓库根目录执行:
go generate ./internal/parser/...(会调用scripts/gen-antlr.sh)
out, err := formula.ToPostgres(`=IF({{orders.qty}}>0,SUM({{orders.amount}},{{orders.tax}}),0)`)- 开头的
=可选,会被去掉。 - 输入
{{name}}:{{a1}}→ SQLa1;{{table.a1}}→ SQLtable.a1(表.列)。名称内不得再嵌套{{/}}。 - 裸标识符:
table.a1→ SQL"table.a1"。对比CONCAT({{table.a1}},2)→(table.a1::text)||(2::text)与CONCAT(table.a1,2)→("table.a1"::text)||(2::text)。 - Excel 字符串(公式外层双引号):
"orders.amount"→ PostgreSQL'orders.amount'。 - Go 辅助:
formula.BracedColumnContent、formula.SQLDoubleQuotedIdent。
本库只登记一份精简的 Excel 风格函数清单(见 pkg/formula/formulajs_catalog.txt):常见数学、文本、日期、逻辑与部分财务函数;能翻译的生成 PostgreSQL 表达式,不能的返回 ErrNotTranspilable;不在清单中的名字视为未知函数。
IF、SUM、CONCAT等手写实现会在pkg/formula/formulajs_registry.go中覆盖同名通用发射逻辑。
对外错误语义:
| 错误 | 含义 |
|---|---|
ErrUnknownFunction |
名称不在 catalog(也不属于手写覆盖集合)。 |
ErrArity |
已知函数,但实参个数与当前已实现的签名不符。 |
ErrNotTranspilable |
名称在 catalog 中,但尚无稳妥的 PostgreSQL 标量翻译(例如 NORM.DIST、FV / PV / PMT)。这不等于「未知函数」。 |
ErrNotTranspilable 与 ErrArity 的回归用例见 pkg/formula/formulajs_test.go。
- 字面量:数字、
"字符串"(Excel 中""转义 → PostgreSQL 中单引号与''规则)、TRUE/FALSE/NULL - 运算符:
+ - * / ^、一元+/-、比较= <> < > <= >=、字符串连接&(映射为||;CONCAT等场景下按需使用::text) - 核心工作表函数(专用 Visitor 路径):
IF、AND、OR、NOT、SUM、AVERAGE、MIN、MAX、COUNT、CONCAT、TEXTJOIN(分隔符拼接为最小实现;第二个参数会接受但未完整模拟 Excel 行为) - formulajs 发射器(见各
formulajs_emit*.go):常用数学/三角一元与二元(如ABS、POWER、ROUND、MOD、LOG等)、文本(LEN、LOWER、MID、FIND等)、日期时间片段(DATE、YEAR、EDATE等)、变参聚合(PRODUCT、GCD、LCM、MEDIAN、STDEV.S/STDEV.P等)、扩展数学(INT、CEILING/FLOOR、ROUNDDOWN/ROUNDUP、CHOOSE)、逻辑扩展(IFS、SWITCH、XOR、IFNA、IFERROR,部分与 Excel 行为仅有 SQL 侧近似,详见代码注释),以及少量财务函数(RRI、EFFECT、NOMINAL、SLN、SYD)。catalog 中尚无发射器的名称统一返回ErrNotTranspilable。
- NULL 与算术:PostgreSQL 的空值传播与 Excel 不同;
SUM当前展开为裸+链,未加COALESCE,除非你在 Visitor 中扩展。 - COUNT:按每个参数用
CASE WHEN (expr) IS NULL THEN 0 ELSE 1 END再相加(在该编码下表示非空个数)。 - AVERAGE:对参数列表取算术平均,除数为
n.0。
BSD-3-Clause(请与 ANTLR 运行时及贵司策略保持一致。)