公式解析器
Library提供了一个Parser评估excel和数学公式的类。
安装
安装Formula Parser的推荐方法是使用以下命令通过NPM:
$ npm install hot-formula-parser
Node.js中使用:
// 此处以es6规范为例子
import { Parser, ERROR_REF, error as isFormulaError } from 'hot-formula-parser';
var parser = new Parser();
parser.parse('SUM(1, 6, 7)'); // returns `Object {error: null, result: 14}`
浏览器中使用:
<script src="/node_modules/hot-formula-parser/dist/formula-parser.min.js"></script>
<script>
var parser = new formulaParser.Parser();
parser.parse('SUM(1, 6, 7)'); // returns `Object {error: null, result: 14}`
</script>
特征
它支持:
- 任何数字,负数和正数,如浮点数或整数;
- 支持的运算符:
+
,-
,/
,*
,%
,^
; - 支持的逻辑运算符:
AND()
,OR()
,NOT()
,XOR()
; - 支持的比较运算符:
=
,>
,>=
,<
,<=
,<>
; - 常用的数学常数:
PI()
,E()
,LN10()
,LN2()
,LOG10E()
,LOG2E()
,SQRT1_2()
,SQRT2()
; - 字符串操作符
&
,(parser.parse(’-(2&5)’);将返回-25) - 定义了所有的Excel公式;
- 相对和绝对单元格的坐标:
A1
,$A1
,A$1
,$A$1
; - 内置变量:
TRUE
,FALSE
,NULL
; - 自定义变量;
- 自定义函数/公式;
- Node和浏览器环境;
API 方法
var parser = new formulaParser.Parser();
.parse(expression)
解析并计算传入表达式。返回带有result
和error
属性的对象。result为计算的结果。如果发生错误,error将会被设定为指定的错误类型,如下:
#ERROR!
一般错误;#DIV/0!
除以零误差;#NAME?
未识别的函数名称或变量名称;#N/A
表示值不可用于公式;#NUM!
当公式遇到无效数字时发生;#VALUE!
当其中一个公式参数的类型错误时发生。
parser.parse('(1 + 5 + (5 * 10)) / 10'); // returns `Object {error: null, result: 5.6}`
parser.parse('SUM(MY_VAR)'); // returns `Object {error: "#NAME?", result: null}`
parser.parse('1;;1'); // returns `Object {error: "#ERROR!", result: null}`
.setVariable(name,value)
设置在解析公式表达式时出现的预定义变量名称。
parser.setVariable('MY_VARIABLE', 5);
parser.setVariable('fooBar', 10);
parser.parse('(1 + MY_VARIABLE + (5 * fooBar)) / fooBar'); // returns `5.6`
.getVariable(name)
获取使用。.setVariable()
设置的常量。
parser.setVariable('fooBar', 10);
parser.getVariable('fooBar'); // returns `10`
.setFunction(name,fn)
设置自定义函数,在解析公式表达式时会根据自定义逻辑实现。
parser.setFunction('ADD_5', function(params) {
return params[0] + 5;
});
parser.setFunction('GET_LETTER', function(params) {
var string = params[0];
var index = params[1] - 1;
return string.charAt(index);
});
parser.parse('SUM(4, ADD_5(1))'); // returns `10`
parser.parse('GET_LETTER("Some string", 3)'); // returns `m`
.getFunction(name)
获取使用.setFunction()
定义的函数功能。
parser.setFunction('ADD_5', function(params) {
return params[0] + 5;
});
parser.getFunction('ADD_5')([1]); // returns `6`
.SUPPORTED_FORMULAS
所有支持的公式功能列表。
require('hot-formula-parser').SUPPORTED_FORMULAS; // 公式名称数组
API 函数
‘callVariable’(name,done)
检索变量时被触发。如果先前使用变量定义setVariable,则可以通过此函数覆盖它。
parser.on('callVariable', function(name, done) {
if (name === 'foo') {
done(Math.PI / 2);
}
});
parser.parse('SUM(SIN(foo), COS(foo))'); // returns `1`
‘callFunction’(name,params,done)
在调用函数时触发。如果之前使用setFunction
定义了函数,则可以通过此函数覆盖它的结果。您也可以使用它来覆盖内置公式。
parser.on('callFunction', function(name, params, done) {
if (name === 'ADD_5') {
done(params[0] + 5);
}
});
parser.parse('ADD_5(3)'); // returns `8`
‘callCellValue’(cellCoord,done)
通过次函数可以检索单元格元素,并替换(例如:B3
,B$3
,B$3
,$B$3
)
parser.on('callCellValue', function(cellCoord, done) {
// 使用匹配到的原始值
if(cellCoord.label === 'B$6') {
done('hello');
}
// 或者使用索引
if(cellCoord.row.index === 5 && cellCoord.row.isAbsolute && cellCoord.column.index === 1 && !cellCoord.column.isAbsolute) {
done('hello');
}
if (cellCoord.label === 'C6') {
done(0.75);
}
});
parser.parse('B$6'); // returns `"hello"`
parser.parse('B$6&" world"'); // returns `"hello world"`
parser.parse('FISHER(C6)'); // returns `0.9729550745276566`
‘callRangeValue’(startCellCoord,endCellCoord,done)
通过次函数可以检索一个范围的单元格元素,并替换(例如:A1:B3
,$A1:B$3
,A$1:B$3
,$A$1:$B$3
)
parser.on('callRangeValue', function(startCellCoord, endCellCoord, done) {
var data = [
[1, 2, 3, 4, 5],
[6, 7, 8, 9, 10],
[11, 12, 13, 14, 15],
[16, 17, 18, 19, 20],
];
var fragment = [];
for (var row = startCellCoord.row.index; row <= endCellCoord.row.index; row++) {
var rowData = data[row];
var colFragment = [];
for (var col = startCellCoord.column.index; col <= endCellCoord.column.index; col++) {
colFragment.push(rowData[col]);
}
fragment.push(colFragment);
}
if (fragment) {
done(fragment);
}
});
parser.parse('SUM(A1:B2)'); // returns `16`
parser.parse('JOIN(A1:E2)'); // returns `"1,2,3,4,5,6,7,8,9,10"`
parser.parse('COLUMNS(A1:E2)'); // returns `5`
parser.parse('ROWS(A1:E2)'); // returns `2`
parser.parse('COUNT(A1:E2)'); // returns `10`
parser.parse('COUNTIF(A1:E2, ">5")'); // returns `5`
参考:官方文档