@leankylin-sheet/formula-parser 7.0.23 → 7.0.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/evaluate-by-operator/operator/compare.d.ts +1 -0
- package/dist/helper/cell.d.ts +10 -0
- package/dist/helper/date.d.ts +2 -0
- package/dist/helper/number.d.ts +2 -2
- package/dist/index.esm.js +309 -133
- package/dist/index.js +309 -133
- package/package.json +1 -1
package/dist/helper/cell.d.ts
CHANGED
|
@@ -4,3 +4,13 @@ export function columnLabelToIndex(label: string): number;
|
|
|
4
4
|
export function columnIndexToLabel(column: number): string;
|
|
5
5
|
export function extractLabel(label: string): any[];
|
|
6
6
|
export function toLabel(row: Object, column: Object): string;
|
|
7
|
+
export function isCellReference(value: any): boolean;
|
|
8
|
+
export function toCellValue(value: any): any;
|
|
9
|
+
export function isReferenceFormula(symbol: string): boolean;
|
|
10
|
+
export class CellReference {
|
|
11
|
+
constructor(label: any, value: any);
|
|
12
|
+
label: any;
|
|
13
|
+
value: any;
|
|
14
|
+
valueOf(): any;
|
|
15
|
+
}
|
|
16
|
+
export const REFERENCE_FORMULAS: string[];
|
package/dist/helper/number.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export function toNumber(number: string | number): any;
|
|
2
|
-
export function invertNumber(number: number): number;
|
|
1
|
+
export function toNumber(number: string | number | Date): any;
|
|
2
|
+
export function invertNumber(number: number | Date): number;
|
|
3
3
|
export function toNumberNotNaN(number: any): number;
|
package/dist/index.esm.js
CHANGED
|
@@ -169,10 +169,54 @@ function _nonIterableRest() {
|
|
|
169
169
|
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
+
var MS_PER_DAY = 24 * 60 * 60 * 1000;
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* 1900 日期系统下 Excel 的 0 点(1899-12-31 00:00:00 UTC)。
|
|
176
|
+
*/
|
|
177
|
+
var EXCEL_EPOCH_UTC = Date.UTC(1899, 11, 31, 0, 0, 0);
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Excel 虚构的 1900-02-29 之后的第一天(1900-03-01)。
|
|
181
|
+
* 当天及之后的日期需要补 1 天,才能和 Excel 的序列号对齐。
|
|
182
|
+
*/
|
|
183
|
+
var EXCEL_LEAP_BUG_BASE = new Date(1900, 2, 1, 0, 0, 0);
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* 判断是否为有效的 Date 对象。
|
|
187
|
+
*
|
|
188
|
+
* @param {*} value 待判断的值。
|
|
189
|
+
* @returns {Boolean}
|
|
190
|
+
*/
|
|
191
|
+
function isDate(value) {
|
|
192
|
+
return value instanceof Date && !Number.isNaN(value.getTime());
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* 把 Date 转成 Excel 日期序列号。
|
|
197
|
+
*
|
|
198
|
+
* 与 core 中 modules/format.ts 的 datenum_local 保持完全一致:
|
|
199
|
+
* 取本地年月日时分秒再按 UTC 计算,避免时区和夏令时带来的偏移;
|
|
200
|
+
* 1900-03-01 及之后的日期补 1 天,对齐 Excel 的 1900 闰年 bug。
|
|
201
|
+
*
|
|
202
|
+
* @param {Date} date 待转换的日期。
|
|
203
|
+
* @param {Number} [date1904] 是否使用 1904 日期系统。
|
|
204
|
+
* @returns {Number} Excel 序列号,整数部分为日期,小数部分为时间。
|
|
205
|
+
*/
|
|
206
|
+
function dateToSerialNumber(date, date1904) {
|
|
207
|
+
var epoch = Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds());
|
|
208
|
+
if (date1904) {
|
|
209
|
+
epoch -= 1461 * MS_PER_DAY;
|
|
210
|
+
} else if (date >= EXCEL_LEAP_BUG_BASE) {
|
|
211
|
+
epoch += MS_PER_DAY;
|
|
212
|
+
}
|
|
213
|
+
return (epoch - EXCEL_EPOCH_UTC) / MS_PER_DAY;
|
|
214
|
+
}
|
|
215
|
+
|
|
172
216
|
/**
|
|
173
217
|
* Convert value into number.
|
|
174
218
|
*
|
|
175
|
-
* @param {String|Number} number
|
|
219
|
+
* @param {String|Number|Date} number
|
|
176
220
|
* @returns {*}
|
|
177
221
|
*/
|
|
178
222
|
function toNumber(number) {
|
|
@@ -180,6 +224,10 @@ function toNumber(number) {
|
|
|
180
224
|
if (number === true) {
|
|
181
225
|
return 1;
|
|
182
226
|
}
|
|
227
|
+
// DATE/TODAY/NOW 等函数返回 Date 对象,按 Excel 序列号参与运算
|
|
228
|
+
if (isDate(number)) {
|
|
229
|
+
return dateToSerialNumber(number);
|
|
230
|
+
}
|
|
183
231
|
if (typeof number === 'number') {
|
|
184
232
|
result = number;
|
|
185
233
|
} else if (typeof number === 'string') {
|
|
@@ -191,7 +239,7 @@ function toNumber(number) {
|
|
|
191
239
|
/**
|
|
192
240
|
* Invert provided number.
|
|
193
241
|
*
|
|
194
|
-
* @param {Number} number
|
|
242
|
+
* @param {Number|Date} number Provided number.
|
|
195
243
|
* @returns {Number} Returns inverted number.
|
|
196
244
|
*/
|
|
197
245
|
function invertNumber(number) {
|
|
@@ -203,6 +251,9 @@ function toNumberNotNaN(number) {
|
|
|
203
251
|
if (number === true) {
|
|
204
252
|
return 1;
|
|
205
253
|
}
|
|
254
|
+
if (isDate(number)) {
|
|
255
|
+
return dateToSerialNumber(number);
|
|
256
|
+
}
|
|
206
257
|
if (typeof number === 'number') {
|
|
207
258
|
result = number;
|
|
208
259
|
} else if (typeof number === 'string') {
|
|
@@ -278,9 +329,14 @@ function func$1() {
|
|
|
278
329
|
params[_key] = arguments[_key];
|
|
279
330
|
}
|
|
280
331
|
return params.reduce(function (acc, value) {
|
|
281
|
-
return acc +
|
|
332
|
+
return acc + toString(value);
|
|
282
333
|
}, '');
|
|
283
334
|
}
|
|
335
|
+
|
|
336
|
+
// Date 拼接时取 Excel 序列号,避免出现 "Tue Oct 20 2026 ..." 这类 JS 默认格式
|
|
337
|
+
function toString(value) {
|
|
338
|
+
return isDate(value) ? String(dateToSerialNumber(value)) : value.toString();
|
|
339
|
+
}
|
|
284
340
|
func$1.SYMBOL = SYMBOL$1;
|
|
285
341
|
|
|
286
342
|
var SYMBOL$2 = '/';
|
|
@@ -334,9 +390,23 @@ function compare(exp1, exp2, type) {
|
|
|
334
390
|
return tsValue(exp1) === tsValue(exp2);
|
|
335
391
|
}
|
|
336
392
|
}
|
|
337
|
-
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* 比较前的取值归一化:Date 统一转成 Excel 序列号,
|
|
396
|
+
* 这样 =TODAY()>A1、=TODAY()=TODAY() 才能按日期天数比较。
|
|
397
|
+
*
|
|
398
|
+
* @param {*} value 待归一化的值。
|
|
399
|
+
* @returns {*}
|
|
400
|
+
*/
|
|
401
|
+
function toComparable(value) {
|
|
402
|
+
if (isDate(value)) {
|
|
403
|
+
return dateToSerialNumber(value);
|
|
404
|
+
}
|
|
338
405
|
return value !== null && value !== void 0 ? value : 0;
|
|
339
406
|
}
|
|
407
|
+
function tsValue(value) {
|
|
408
|
+
return toComparable(value);
|
|
409
|
+
}
|
|
340
410
|
|
|
341
411
|
var SYMBOL$3 = '=';
|
|
342
412
|
function func$3(exp1, exp2) {
|
|
@@ -344,6 +414,172 @@ function func$3(exp1, exp2) {
|
|
|
344
414
|
}
|
|
345
415
|
func$3.SYMBOL = SYMBOL$3;
|
|
346
416
|
|
|
417
|
+
/**
|
|
418
|
+
* Convert row label to index.
|
|
419
|
+
*
|
|
420
|
+
* @param {String} label Row label (eq. '1', '5')
|
|
421
|
+
* @returns {Number} Returns -1 if label is not recognized otherwise proper row index.
|
|
422
|
+
*/
|
|
423
|
+
function rowLabelToIndex(label) {
|
|
424
|
+
var result = parseInt(label, 10);
|
|
425
|
+
if (isNaN(result)) {
|
|
426
|
+
result = -1;
|
|
427
|
+
} else {
|
|
428
|
+
result = Math.max(result - 1, -1);
|
|
429
|
+
}
|
|
430
|
+
return result;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* Convert row index to label.
|
|
435
|
+
*
|
|
436
|
+
* @param {Number} row Row index.
|
|
437
|
+
* @returns {String} Returns row label (eq. '1', '7').
|
|
438
|
+
*/
|
|
439
|
+
function rowIndexToLabel(row) {
|
|
440
|
+
var result = "";
|
|
441
|
+
if (row >= 0) {
|
|
442
|
+
result = "".concat(row + 1);
|
|
443
|
+
}
|
|
444
|
+
return result;
|
|
445
|
+
}
|
|
446
|
+
var COLUMN_LABEL_BASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
447
|
+
var COLUMN_LABEL_BASE_LENGTH = COLUMN_LABEL_BASE.length;
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* Convert column label to index.
|
|
451
|
+
*
|
|
452
|
+
* @param {String} label Column label (eq. 'ABB', 'CNQ')
|
|
453
|
+
* @returns {Number} Returns -1 if label is not recognized otherwise proper column index.
|
|
454
|
+
*/
|
|
455
|
+
function columnLabelToIndex(label) {
|
|
456
|
+
var result = 0;
|
|
457
|
+
if (typeof label === "string") {
|
|
458
|
+
label = label.toUpperCase();
|
|
459
|
+
for (var i = 0, j = label.length - 1; i < label.length; i += 1, j -= 1) {
|
|
460
|
+
result += Math.pow(COLUMN_LABEL_BASE_LENGTH, j) * (COLUMN_LABEL_BASE.indexOf(label[i]) + 1);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
--result;
|
|
464
|
+
return result;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* Convert column index to label.
|
|
469
|
+
*
|
|
470
|
+
* @param {Number} column Column index.
|
|
471
|
+
* @returns {String} Returns column label (eq. 'ABB', 'CNQ').
|
|
472
|
+
*/
|
|
473
|
+
function columnIndexToLabel(column) {
|
|
474
|
+
var result = "";
|
|
475
|
+
while (column >= 0) {
|
|
476
|
+
result = String.fromCharCode(column % COLUMN_LABEL_BASE_LENGTH + 97) + result;
|
|
477
|
+
column = Math.floor(column / COLUMN_LABEL_BASE_LENGTH) - 1;
|
|
478
|
+
}
|
|
479
|
+
return result.toUpperCase();
|
|
480
|
+
}
|
|
481
|
+
var simpleSheetName = "[A-Za-z0-9_\u4E00-\u9FFF]+";
|
|
482
|
+
var quotedSheetName = "'(?:(?!').|'')*'";
|
|
483
|
+
var sheetNameRegexp = "(".concat(simpleSheetName, "|").concat(quotedSheetName, ")!");
|
|
484
|
+
var LABEL_EXTRACT_REGEXP = new RegExp("^(?:".concat(sheetNameRegexp, ")?([$])?([A-Za-z]*)([$])?([0-9]*)$"));
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* Extract cell coordinates.
|
|
488
|
+
*
|
|
489
|
+
* @param {String} label Cell coordinates (eq. 'A1', '$B6', '$N$98').
|
|
490
|
+
* @returns {Array} Returns an array of objects.
|
|
491
|
+
*/
|
|
492
|
+
function extractLabel(label) {
|
|
493
|
+
if (typeof label !== "string" || !LABEL_EXTRACT_REGEXP.test(label)) {
|
|
494
|
+
return [];
|
|
495
|
+
}
|
|
496
|
+
var _label$toUpperCase$ma = label.toUpperCase().match(LABEL_EXTRACT_REGEXP),
|
|
497
|
+
_label$toUpperCase$ma2 = _slicedToArray(_label$toUpperCase$ma, 6),
|
|
498
|
+
sheetNameStr = _label$toUpperCase$ma2[1],
|
|
499
|
+
columnAbs = _label$toUpperCase$ma2[2],
|
|
500
|
+
column = _label$toUpperCase$ma2[3],
|
|
501
|
+
rowAbs = _label$toUpperCase$ma2[4],
|
|
502
|
+
row = _label$toUpperCase$ma2[5];
|
|
503
|
+
if (column == null && row == null) return [];
|
|
504
|
+
var sheetName = sheetNameStr == null ? null : label.slice(0, sheetNameStr.length).replace(/^'|'$/g, "").replace(/''/g, "'");
|
|
505
|
+
return [{
|
|
506
|
+
index: rowLabelToIndex(row),
|
|
507
|
+
label: row,
|
|
508
|
+
isAbsolute: rowAbs === "$"
|
|
509
|
+
}, {
|
|
510
|
+
index: columnLabelToIndex(column),
|
|
511
|
+
label: column,
|
|
512
|
+
isAbsolute: columnAbs === "$"
|
|
513
|
+
}, sheetName];
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
/**
|
|
517
|
+
* Convert row and column indexes into cell label.
|
|
518
|
+
*
|
|
519
|
+
* @param {Object} row Object with `index` and `isAbsolute` properties.
|
|
520
|
+
* @param {Object} column Object with `index` and `isAbsolute` properties.
|
|
521
|
+
* @returns {String} Returns cell label.
|
|
522
|
+
*/
|
|
523
|
+
function toLabel(row, column) {
|
|
524
|
+
var rowLabel = (row.isAbsolute ? "$" : "") + rowIndexToLabel(row.index);
|
|
525
|
+
var columnLabel = (column.isAbsolute ? "$" : "") + columnIndexToLabel(column.index);
|
|
526
|
+
return columnLabel + rowLabel;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
/**
|
|
530
|
+
* Cell reference wrapper which keeps both the cell value and its label
|
|
531
|
+
* (eq. `A1`, `Sheet1!$B$3`). Functions like ROW/COLUMN need the position
|
|
532
|
+
* info instead of the value, so the parser must not unwrap it too early.
|
|
533
|
+
*/
|
|
534
|
+
var CellReference = /*#__PURE__*/function () {
|
|
535
|
+
function CellReference(label, value) {
|
|
536
|
+
_classCallCheck(this, CellReference);
|
|
537
|
+
this.label = label;
|
|
538
|
+
this.value = value;
|
|
539
|
+
}
|
|
540
|
+
return _createClass(CellReference, [{
|
|
541
|
+
key: "valueOf",
|
|
542
|
+
value: function valueOf() {
|
|
543
|
+
return this.value;
|
|
544
|
+
}
|
|
545
|
+
}]);
|
|
546
|
+
}();
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
* Check whether the value is a cell reference wrapper.
|
|
550
|
+
*
|
|
551
|
+
* @param {*} value
|
|
552
|
+
* @returns {Boolean}
|
|
553
|
+
*/
|
|
554
|
+
function isCellReference(value) {
|
|
555
|
+
return value instanceof CellReference;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* Get the real value out of a cell reference wrapper.
|
|
560
|
+
*
|
|
561
|
+
* @param {*} value
|
|
562
|
+
* @returns {*}
|
|
563
|
+
*/
|
|
564
|
+
function toCellValue(value) {
|
|
565
|
+
return isCellReference(value) ? value.value : value;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
/**
|
|
569
|
+
* Functions whose arguments are cell references instead of cell values
|
|
570
|
+
*/
|
|
571
|
+
var REFERENCE_FORMULAS = ["ROW", "COLUMN"];
|
|
572
|
+
|
|
573
|
+
/**
|
|
574
|
+
* Check whether the function needs cell references (labels) as params.
|
|
575
|
+
*
|
|
576
|
+
* @param {String} symbol Function name.
|
|
577
|
+
* @returns {Boolean}
|
|
578
|
+
*/
|
|
579
|
+
function isReferenceFormula(symbol) {
|
|
580
|
+
return REFERENCE_FORMULAS.includes(String(symbol).toUpperCase());
|
|
581
|
+
}
|
|
582
|
+
|
|
347
583
|
var SUPPORTED_FORMULAS = Object.keys(formulajs);
|
|
348
584
|
|
|
349
585
|
var SYMBOL$4 = SUPPORTED_FORMULAS;
|
|
@@ -353,11 +589,15 @@ function func$4(symbol) {
|
|
|
353
589
|
for (var _len = arguments.length, _params = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
354
590
|
_params[_key] = arguments[_key];
|
|
355
591
|
}
|
|
592
|
+
if (isReferenceFormula(symbol)) {
|
|
593
|
+
return referenceResult(symbol, _params);
|
|
594
|
+
}
|
|
356
595
|
var params = _params === null || _params === void 0 ? void 0 : _params.map(function (item) {
|
|
357
|
-
|
|
358
|
-
|
|
596
|
+
var value = toCellValue(item);
|
|
597
|
+
if (errors_formula_map[value]) {
|
|
598
|
+
return errors_formula_map[value];
|
|
359
599
|
} else {
|
|
360
|
-
return
|
|
600
|
+
return value;
|
|
361
601
|
}
|
|
362
602
|
});
|
|
363
603
|
var symbolParts = symbol.split(".");
|
|
@@ -395,6 +635,33 @@ function func$4(symbol) {
|
|
|
395
635
|
}
|
|
396
636
|
func$4.isFactory = true;
|
|
397
637
|
func$4.SYMBOL = SYMBOL$4;
|
|
638
|
+
|
|
639
|
+
/**
|
|
640
|
+
* 计算 ROW/COLUMN 一类以单元格引用(而不是单元格的值)作为入参的函数
|
|
641
|
+
*
|
|
642
|
+
* @param {String} fnName Function name.
|
|
643
|
+
* @param {Array} params Function params, may contain cell references.
|
|
644
|
+
* @returns {*}
|
|
645
|
+
*/
|
|
646
|
+
function referenceResult(fnName, params) {
|
|
647
|
+
var first = params[0];
|
|
648
|
+
if (isCellReference(first)) {
|
|
649
|
+
var _extractLabel = extractLabel(first.label),
|
|
650
|
+
_extractLabel2 = _slicedToArray(_extractLabel, 2),
|
|
651
|
+
row = _extractLabel2[0],
|
|
652
|
+
column = _extractLabel2[1];
|
|
653
|
+
var index = fnName === "ROW" ? row === null || row === void 0 ? void 0 : row.index : column === null || column === void 0 ? void 0 : column.index;
|
|
654
|
+
if (typeof index === "number" && index >= 0) {
|
|
655
|
+
return index + 1;
|
|
656
|
+
}
|
|
657
|
+
} else if (errors_formula_map[first]) {
|
|
658
|
+
return errors_formula_map[first];
|
|
659
|
+
} else if (typeof first === "number") {
|
|
660
|
+
// 兼容直接传入行号/列号的情况,如 ROW(3)
|
|
661
|
+
return first;
|
|
662
|
+
}
|
|
663
|
+
return errors_formula_map[ERROR_VALUE];
|
|
664
|
+
}
|
|
398
665
|
function tsParams(fnName, params) {
|
|
399
666
|
if (fnName === "SUMPRODUCT") {
|
|
400
667
|
var _params2;
|
|
@@ -536,7 +803,12 @@ func$a.SYMBOL = SYMBOL$a;
|
|
|
536
803
|
|
|
537
804
|
var SYMBOL$b = '<>';
|
|
538
805
|
function func$b(exp1, exp2) {
|
|
539
|
-
return exp1 !== exp2;
|
|
806
|
+
return normalize(exp1) !== normalize(exp2);
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
// Date 按 Excel 序列号比较,=TODAY()<>TODAY() 才是 FALSE
|
|
810
|
+
function normalize(value) {
|
|
811
|
+
return isDate(value) ? dateToSerialNumber(value) : value;
|
|
540
812
|
}
|
|
541
813
|
func$b.SYMBOL = SYMBOL$b;
|
|
542
814
|
|
|
@@ -600,13 +872,13 @@ registerOperation(func$a.SYMBOL, func$a);
|
|
|
600
872
|
registerOperation(func$b.SYMBOL, func$b);
|
|
601
873
|
registerOperation(func$9.SYMBOL, func$9);
|
|
602
874
|
|
|
603
|
-
var simpleSheetName = "[A-Za-z0-9_\u4E00-\u9FFF]+";
|
|
604
|
-
var quotedSheetName = "'(?:(?!').|'')*'";
|
|
605
|
-
var sheetNameRegexp = "(?:".concat(simpleSheetName, "|").concat(quotedSheetName, ")!");
|
|
606
|
-
var ABSOLUTE_CELL = new RegExp("^(?:".concat(sheetNameRegexp, ")?(?:[$][A-Za-z]+[$][0-9]+)"));
|
|
607
|
-
var MIXED_CELL_COL = new RegExp("^(?:".concat(sheetNameRegexp, ")?(?:[$][A-Za-z]+[0-9]*)"));
|
|
608
|
-
var MIXED_CELL_ROW = new RegExp("^(?:".concat(sheetNameRegexp, ")?(?:[A-Za-z]*[$][0-9]+)"));
|
|
609
|
-
var RELATIVE_CELL = new RegExp("^(?:".concat(sheetNameRegexp, ")?(?:(?:[A-Za-z]+[0-9]*)|(?:[A-Za-z]*[0-9]+))(?!\\d)(?!\\.)"));
|
|
875
|
+
var simpleSheetName$1 = "[A-Za-z0-9_\u4E00-\u9FFF]+";
|
|
876
|
+
var quotedSheetName$1 = "'(?:(?!').|'')*'";
|
|
877
|
+
var sheetNameRegexp$1 = "(?:".concat(simpleSheetName$1, "|").concat(quotedSheetName$1, ")!");
|
|
878
|
+
var ABSOLUTE_CELL = new RegExp("^(?:".concat(sheetNameRegexp$1, ")?(?:[$][A-Za-z]+[$][0-9]+)"));
|
|
879
|
+
var MIXED_CELL_COL = new RegExp("^(?:".concat(sheetNameRegexp$1, ")?(?:[$][A-Za-z]+[0-9]*)"));
|
|
880
|
+
var MIXED_CELL_ROW = new RegExp("^(?:".concat(sheetNameRegexp$1, ")?(?:[A-Za-z]*[$][0-9]+)"));
|
|
881
|
+
var RELATIVE_CELL = new RegExp("^(?:".concat(sheetNameRegexp$1, ")?(?:(?:[A-Za-z]+[0-9]*)|(?:[A-Za-z]*[0-9]+))(?!\\d)(?!\\.)"));
|
|
610
882
|
var NUMONLY = /^(?:[0-9]+$)/;
|
|
611
883
|
var stackCache;
|
|
612
884
|
var o = function o(k, v, _o, l) {
|
|
@@ -2021,118 +2293,6 @@ function trimEdges(string) {
|
|
|
2021
2293
|
return string;
|
|
2022
2294
|
}
|
|
2023
2295
|
|
|
2024
|
-
/**
|
|
2025
|
-
* Convert row label to index.
|
|
2026
|
-
*
|
|
2027
|
-
* @param {String} label Row label (eq. '1', '5')
|
|
2028
|
-
* @returns {Number} Returns -1 if label is not recognized otherwise proper row index.
|
|
2029
|
-
*/
|
|
2030
|
-
function rowLabelToIndex(label) {
|
|
2031
|
-
var result = parseInt(label, 10);
|
|
2032
|
-
if (isNaN(result)) {
|
|
2033
|
-
result = -1;
|
|
2034
|
-
} else {
|
|
2035
|
-
result = Math.max(result - 1, -1);
|
|
2036
|
-
}
|
|
2037
|
-
return result;
|
|
2038
|
-
}
|
|
2039
|
-
|
|
2040
|
-
/**
|
|
2041
|
-
* Convert row index to label.
|
|
2042
|
-
*
|
|
2043
|
-
* @param {Number} row Row index.
|
|
2044
|
-
* @returns {String} Returns row label (eq. '1', '7').
|
|
2045
|
-
*/
|
|
2046
|
-
function rowIndexToLabel(row) {
|
|
2047
|
-
var result = "";
|
|
2048
|
-
if (row >= 0) {
|
|
2049
|
-
result = "".concat(row + 1);
|
|
2050
|
-
}
|
|
2051
|
-
return result;
|
|
2052
|
-
}
|
|
2053
|
-
var COLUMN_LABEL_BASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
2054
|
-
var COLUMN_LABEL_BASE_LENGTH = COLUMN_LABEL_BASE.length;
|
|
2055
|
-
|
|
2056
|
-
/**
|
|
2057
|
-
* Convert column label to index.
|
|
2058
|
-
*
|
|
2059
|
-
* @param {String} label Column label (eq. 'ABB', 'CNQ')
|
|
2060
|
-
* @returns {Number} Returns -1 if label is not recognized otherwise proper column index.
|
|
2061
|
-
*/
|
|
2062
|
-
function columnLabelToIndex(label) {
|
|
2063
|
-
var result = 0;
|
|
2064
|
-
if (typeof label === "string") {
|
|
2065
|
-
label = label.toUpperCase();
|
|
2066
|
-
for (var i = 0, j = label.length - 1; i < label.length; i += 1, j -= 1) {
|
|
2067
|
-
result += Math.pow(COLUMN_LABEL_BASE_LENGTH, j) * (COLUMN_LABEL_BASE.indexOf(label[i]) + 1);
|
|
2068
|
-
}
|
|
2069
|
-
}
|
|
2070
|
-
--result;
|
|
2071
|
-
return result;
|
|
2072
|
-
}
|
|
2073
|
-
|
|
2074
|
-
/**
|
|
2075
|
-
* Convert column index to label.
|
|
2076
|
-
*
|
|
2077
|
-
* @param {Number} column Column index.
|
|
2078
|
-
* @returns {String} Returns column label (eq. 'ABB', 'CNQ').
|
|
2079
|
-
*/
|
|
2080
|
-
function columnIndexToLabel(column) {
|
|
2081
|
-
var result = "";
|
|
2082
|
-
while (column >= 0) {
|
|
2083
|
-
result = String.fromCharCode(column % COLUMN_LABEL_BASE_LENGTH + 97) + result;
|
|
2084
|
-
column = Math.floor(column / COLUMN_LABEL_BASE_LENGTH) - 1;
|
|
2085
|
-
}
|
|
2086
|
-
return result.toUpperCase();
|
|
2087
|
-
}
|
|
2088
|
-
var simpleSheetName$1 = "[A-Za-z0-9_\u4E00-\u9FFF]+";
|
|
2089
|
-
var quotedSheetName$1 = "'(?:(?!').|'')*'";
|
|
2090
|
-
var sheetNameRegexp$1 = "(".concat(simpleSheetName$1, "|").concat(quotedSheetName$1, ")!");
|
|
2091
|
-
var LABEL_EXTRACT_REGEXP = new RegExp("^(?:".concat(sheetNameRegexp$1, ")?([$])?([A-Za-z]*)([$])?([0-9]*)$"));
|
|
2092
|
-
|
|
2093
|
-
/**
|
|
2094
|
-
* Extract cell coordinates.
|
|
2095
|
-
*
|
|
2096
|
-
* @param {String} label Cell coordinates (eq. 'A1', '$B6', '$N$98').
|
|
2097
|
-
* @returns {Array} Returns an array of objects.
|
|
2098
|
-
*/
|
|
2099
|
-
function extractLabel(label) {
|
|
2100
|
-
if (typeof label !== "string" || !LABEL_EXTRACT_REGEXP.test(label)) {
|
|
2101
|
-
return [];
|
|
2102
|
-
}
|
|
2103
|
-
var _label$toUpperCase$ma = label.toUpperCase().match(LABEL_EXTRACT_REGEXP),
|
|
2104
|
-
_label$toUpperCase$ma2 = _slicedToArray(_label$toUpperCase$ma, 6),
|
|
2105
|
-
sheetNameStr = _label$toUpperCase$ma2[1],
|
|
2106
|
-
columnAbs = _label$toUpperCase$ma2[2],
|
|
2107
|
-
column = _label$toUpperCase$ma2[3],
|
|
2108
|
-
rowAbs = _label$toUpperCase$ma2[4],
|
|
2109
|
-
row = _label$toUpperCase$ma2[5];
|
|
2110
|
-
if (column == null && row == null) return [];
|
|
2111
|
-
var sheetName = sheetNameStr == null ? null : label.slice(0, sheetNameStr.length).replace(/^'|'$/g, "").replace(/''/g, "'");
|
|
2112
|
-
return [{
|
|
2113
|
-
index: rowLabelToIndex(row),
|
|
2114
|
-
label: row,
|
|
2115
|
-
isAbsolute: rowAbs === "$"
|
|
2116
|
-
}, {
|
|
2117
|
-
index: columnLabelToIndex(column),
|
|
2118
|
-
label: column,
|
|
2119
|
-
isAbsolute: columnAbs === "$"
|
|
2120
|
-
}, sheetName];
|
|
2121
|
-
}
|
|
2122
|
-
|
|
2123
|
-
/**
|
|
2124
|
-
* Convert row and column indexes into cell label.
|
|
2125
|
-
*
|
|
2126
|
-
* @param {Object} row Object with `index` and `isAbsolute` properties.
|
|
2127
|
-
* @param {Object} column Object with `index` and `isAbsolute` properties.
|
|
2128
|
-
* @returns {String} Returns cell label.
|
|
2129
|
-
*/
|
|
2130
|
-
function toLabel(row, column) {
|
|
2131
|
-
var rowLabel = (row.isAbsolute ? "$" : "") + rowIndexToLabel(row.index);
|
|
2132
|
-
var columnLabel = (column.isAbsolute ? "$" : "") + columnIndexToLabel(column.index);
|
|
2133
|
-
return columnLabel + rowLabel;
|
|
2134
|
-
}
|
|
2135
|
-
|
|
2136
2296
|
/**
|
|
2137
2297
|
* @class Parser
|
|
2138
2298
|
*/
|
|
@@ -2143,16 +2303,24 @@ var Parser$1 = /*#__PURE__*/function (_Emitter) {
|
|
|
2143
2303
|
_this = _callSuper(this, Parser$1);
|
|
2144
2304
|
_this.parser = new Parser();
|
|
2145
2305
|
_this.parser.yy = {
|
|
2146
|
-
toNumber: toNumber
|
|
2306
|
+
toNumber: function toNumber$1(value) {
|
|
2307
|
+
return toNumber(toCellValue(value));
|
|
2308
|
+
},
|
|
2147
2309
|
trimEdges: trimEdges,
|
|
2148
|
-
invertNumber: invertNumber
|
|
2310
|
+
invertNumber: function invertNumber$1(value) {
|
|
2311
|
+
return invertNumber(toCellValue(value));
|
|
2312
|
+
},
|
|
2149
2313
|
throwError: function throwError(errorName) {
|
|
2150
2314
|
return _this._throwError(errorName);
|
|
2151
2315
|
},
|
|
2152
2316
|
callVariable: function callVariable(variable) {
|
|
2153
2317
|
return _this._callVariable(variable);
|
|
2154
2318
|
},
|
|
2155
|
-
|
|
2319
|
+
// ROW/COLUMN 的入参需要引用(label),不能解包成值
|
|
2320
|
+
evaluateByOperator: function evaluateByOperator$1(operator) {
|
|
2321
|
+
var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
2322
|
+
return evaluateByOperator(operator, isReferenceFormula(operator) ? params : params.map(toCellValue));
|
|
2323
|
+
},
|
|
2156
2324
|
callFunction: function callFunction(name, params) {
|
|
2157
2325
|
return _this._callFunction(name, params);
|
|
2158
2326
|
},
|
|
@@ -2205,6 +2373,9 @@ var Parser$1 = /*#__PURE__*/function (_Emitter) {
|
|
|
2205
2373
|
if (result instanceof Error) {
|
|
2206
2374
|
error$1 = error(result.message) || error(ERROR);
|
|
2207
2375
|
result = null;
|
|
2376
|
+
} else {
|
|
2377
|
+
// `=A1` 这类表达式的结果是引用包装对象,对外只返回值本身
|
|
2378
|
+
result = toCellValue(result);
|
|
2208
2379
|
}
|
|
2209
2380
|
return {
|
|
2210
2381
|
error: error$1,
|
|
@@ -2309,15 +2480,18 @@ var Parser$1 = /*#__PURE__*/function (_Emitter) {
|
|
|
2309
2480
|
value: function _callFunction(name) {
|
|
2310
2481
|
var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
2311
2482
|
var fn = this.getFunction(name);
|
|
2483
|
+
var args = params.map(toCellValue);
|
|
2312
2484
|
var value;
|
|
2313
2485
|
if (fn) {
|
|
2314
|
-
value = fn(
|
|
2486
|
+
value = fn(args);
|
|
2315
2487
|
}
|
|
2316
|
-
this.emit("callFunction", name,
|
|
2488
|
+
this.emit("callFunction", name, args, function (newValue) {
|
|
2317
2489
|
if (newValue !== void 0) {
|
|
2318
2490
|
value = newValue;
|
|
2319
2491
|
}
|
|
2320
2492
|
});
|
|
2493
|
+
|
|
2494
|
+
// `params` 里可能带着单元格引用(ROW/COLUMN 需要),由 formula-function 自行解包
|
|
2321
2495
|
return value === void 0 ? evaluateByOperator(name, params) : value;
|
|
2322
2496
|
}
|
|
2323
2497
|
|
|
@@ -2353,7 +2527,9 @@ var Parser$1 = /*#__PURE__*/function (_Emitter) {
|
|
|
2353
2527
|
}, this.options, function (_value) {
|
|
2354
2528
|
value = _value;
|
|
2355
2529
|
});
|
|
2356
|
-
|
|
2530
|
+
|
|
2531
|
+
// 同时保留 label,供 ROW/COLUMN 等需要引用位置的函数使用
|
|
2532
|
+
return new CellReference(label, value);
|
|
2357
2533
|
}
|
|
2358
2534
|
|
|
2359
2535
|
/**
|
package/dist/index.js
CHANGED
|
@@ -197,10 +197,54 @@ function _nonIterableRest() {
|
|
|
197
197
|
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
198
198
|
}
|
|
199
199
|
|
|
200
|
+
var MS_PER_DAY = 24 * 60 * 60 * 1000;
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* 1900 日期系统下 Excel 的 0 点(1899-12-31 00:00:00 UTC)。
|
|
204
|
+
*/
|
|
205
|
+
var EXCEL_EPOCH_UTC = Date.UTC(1899, 11, 31, 0, 0, 0);
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Excel 虚构的 1900-02-29 之后的第一天(1900-03-01)。
|
|
209
|
+
* 当天及之后的日期需要补 1 天,才能和 Excel 的序列号对齐。
|
|
210
|
+
*/
|
|
211
|
+
var EXCEL_LEAP_BUG_BASE = new Date(1900, 2, 1, 0, 0, 0);
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* 判断是否为有效的 Date 对象。
|
|
215
|
+
*
|
|
216
|
+
* @param {*} value 待判断的值。
|
|
217
|
+
* @returns {Boolean}
|
|
218
|
+
*/
|
|
219
|
+
function isDate(value) {
|
|
220
|
+
return value instanceof Date && !Number.isNaN(value.getTime());
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* 把 Date 转成 Excel 日期序列号。
|
|
225
|
+
*
|
|
226
|
+
* 与 core 中 modules/format.ts 的 datenum_local 保持完全一致:
|
|
227
|
+
* 取本地年月日时分秒再按 UTC 计算,避免时区和夏令时带来的偏移;
|
|
228
|
+
* 1900-03-01 及之后的日期补 1 天,对齐 Excel 的 1900 闰年 bug。
|
|
229
|
+
*
|
|
230
|
+
* @param {Date} date 待转换的日期。
|
|
231
|
+
* @param {Number} [date1904] 是否使用 1904 日期系统。
|
|
232
|
+
* @returns {Number} Excel 序列号,整数部分为日期,小数部分为时间。
|
|
233
|
+
*/
|
|
234
|
+
function dateToSerialNumber(date, date1904) {
|
|
235
|
+
var epoch = Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds());
|
|
236
|
+
if (date1904) {
|
|
237
|
+
epoch -= 1461 * MS_PER_DAY;
|
|
238
|
+
} else if (date >= EXCEL_LEAP_BUG_BASE) {
|
|
239
|
+
epoch += MS_PER_DAY;
|
|
240
|
+
}
|
|
241
|
+
return (epoch - EXCEL_EPOCH_UTC) / MS_PER_DAY;
|
|
242
|
+
}
|
|
243
|
+
|
|
200
244
|
/**
|
|
201
245
|
* Convert value into number.
|
|
202
246
|
*
|
|
203
|
-
* @param {String|Number} number
|
|
247
|
+
* @param {String|Number|Date} number
|
|
204
248
|
* @returns {*}
|
|
205
249
|
*/
|
|
206
250
|
function toNumber(number) {
|
|
@@ -208,6 +252,10 @@ function toNumber(number) {
|
|
|
208
252
|
if (number === true) {
|
|
209
253
|
return 1;
|
|
210
254
|
}
|
|
255
|
+
// DATE/TODAY/NOW 等函数返回 Date 对象,按 Excel 序列号参与运算
|
|
256
|
+
if (isDate(number)) {
|
|
257
|
+
return dateToSerialNumber(number);
|
|
258
|
+
}
|
|
211
259
|
if (typeof number === 'number') {
|
|
212
260
|
result = number;
|
|
213
261
|
} else if (typeof number === 'string') {
|
|
@@ -219,7 +267,7 @@ function toNumber(number) {
|
|
|
219
267
|
/**
|
|
220
268
|
* Invert provided number.
|
|
221
269
|
*
|
|
222
|
-
* @param {Number} number
|
|
270
|
+
* @param {Number|Date} number Provided number.
|
|
223
271
|
* @returns {Number} Returns inverted number.
|
|
224
272
|
*/
|
|
225
273
|
function invertNumber(number) {
|
|
@@ -231,6 +279,9 @@ function toNumberNotNaN(number) {
|
|
|
231
279
|
if (number === true) {
|
|
232
280
|
return 1;
|
|
233
281
|
}
|
|
282
|
+
if (isDate(number)) {
|
|
283
|
+
return dateToSerialNumber(number);
|
|
284
|
+
}
|
|
234
285
|
if (typeof number === 'number') {
|
|
235
286
|
result = number;
|
|
236
287
|
} else if (typeof number === 'string') {
|
|
@@ -306,9 +357,14 @@ function func$1() {
|
|
|
306
357
|
params[_key] = arguments[_key];
|
|
307
358
|
}
|
|
308
359
|
return params.reduce(function (acc, value) {
|
|
309
|
-
return acc +
|
|
360
|
+
return acc + toString(value);
|
|
310
361
|
}, '');
|
|
311
362
|
}
|
|
363
|
+
|
|
364
|
+
// Date 拼接时取 Excel 序列号,避免出现 "Tue Oct 20 2026 ..." 这类 JS 默认格式
|
|
365
|
+
function toString(value) {
|
|
366
|
+
return isDate(value) ? String(dateToSerialNumber(value)) : value.toString();
|
|
367
|
+
}
|
|
312
368
|
func$1.SYMBOL = SYMBOL$1;
|
|
313
369
|
|
|
314
370
|
var SYMBOL$2 = '/';
|
|
@@ -362,9 +418,23 @@ function compare(exp1, exp2, type) {
|
|
|
362
418
|
return tsValue(exp1) === tsValue(exp2);
|
|
363
419
|
}
|
|
364
420
|
}
|
|
365
|
-
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* 比较前的取值归一化:Date 统一转成 Excel 序列号,
|
|
424
|
+
* 这样 =TODAY()>A1、=TODAY()=TODAY() 才能按日期天数比较。
|
|
425
|
+
*
|
|
426
|
+
* @param {*} value 待归一化的值。
|
|
427
|
+
* @returns {*}
|
|
428
|
+
*/
|
|
429
|
+
function toComparable(value) {
|
|
430
|
+
if (isDate(value)) {
|
|
431
|
+
return dateToSerialNumber(value);
|
|
432
|
+
}
|
|
366
433
|
return value !== null && value !== void 0 ? value : 0;
|
|
367
434
|
}
|
|
435
|
+
function tsValue(value) {
|
|
436
|
+
return toComparable(value);
|
|
437
|
+
}
|
|
368
438
|
|
|
369
439
|
var SYMBOL$3 = '=';
|
|
370
440
|
function func$3(exp1, exp2) {
|
|
@@ -372,6 +442,172 @@ function func$3(exp1, exp2) {
|
|
|
372
442
|
}
|
|
373
443
|
func$3.SYMBOL = SYMBOL$3;
|
|
374
444
|
|
|
445
|
+
/**
|
|
446
|
+
* Convert row label to index.
|
|
447
|
+
*
|
|
448
|
+
* @param {String} label Row label (eq. '1', '5')
|
|
449
|
+
* @returns {Number} Returns -1 if label is not recognized otherwise proper row index.
|
|
450
|
+
*/
|
|
451
|
+
function rowLabelToIndex(label) {
|
|
452
|
+
var result = parseInt(label, 10);
|
|
453
|
+
if (isNaN(result)) {
|
|
454
|
+
result = -1;
|
|
455
|
+
} else {
|
|
456
|
+
result = Math.max(result - 1, -1);
|
|
457
|
+
}
|
|
458
|
+
return result;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* Convert row index to label.
|
|
463
|
+
*
|
|
464
|
+
* @param {Number} row Row index.
|
|
465
|
+
* @returns {String} Returns row label (eq. '1', '7').
|
|
466
|
+
*/
|
|
467
|
+
function rowIndexToLabel(row) {
|
|
468
|
+
var result = "";
|
|
469
|
+
if (row >= 0) {
|
|
470
|
+
result = "".concat(row + 1);
|
|
471
|
+
}
|
|
472
|
+
return result;
|
|
473
|
+
}
|
|
474
|
+
var COLUMN_LABEL_BASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
475
|
+
var COLUMN_LABEL_BASE_LENGTH = COLUMN_LABEL_BASE.length;
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* Convert column label to index.
|
|
479
|
+
*
|
|
480
|
+
* @param {String} label Column label (eq. 'ABB', 'CNQ')
|
|
481
|
+
* @returns {Number} Returns -1 if label is not recognized otherwise proper column index.
|
|
482
|
+
*/
|
|
483
|
+
function columnLabelToIndex(label) {
|
|
484
|
+
var result = 0;
|
|
485
|
+
if (typeof label === "string") {
|
|
486
|
+
label = label.toUpperCase();
|
|
487
|
+
for (var i = 0, j = label.length - 1; i < label.length; i += 1, j -= 1) {
|
|
488
|
+
result += Math.pow(COLUMN_LABEL_BASE_LENGTH, j) * (COLUMN_LABEL_BASE.indexOf(label[i]) + 1);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
--result;
|
|
492
|
+
return result;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
/**
|
|
496
|
+
* Convert column index to label.
|
|
497
|
+
*
|
|
498
|
+
* @param {Number} column Column index.
|
|
499
|
+
* @returns {String} Returns column label (eq. 'ABB', 'CNQ').
|
|
500
|
+
*/
|
|
501
|
+
function columnIndexToLabel(column) {
|
|
502
|
+
var result = "";
|
|
503
|
+
while (column >= 0) {
|
|
504
|
+
result = String.fromCharCode(column % COLUMN_LABEL_BASE_LENGTH + 97) + result;
|
|
505
|
+
column = Math.floor(column / COLUMN_LABEL_BASE_LENGTH) - 1;
|
|
506
|
+
}
|
|
507
|
+
return result.toUpperCase();
|
|
508
|
+
}
|
|
509
|
+
var simpleSheetName = "[A-Za-z0-9_\u4E00-\u9FFF]+";
|
|
510
|
+
var quotedSheetName = "'(?:(?!').|'')*'";
|
|
511
|
+
var sheetNameRegexp = "(".concat(simpleSheetName, "|").concat(quotedSheetName, ")!");
|
|
512
|
+
var LABEL_EXTRACT_REGEXP = new RegExp("^(?:".concat(sheetNameRegexp, ")?([$])?([A-Za-z]*)([$])?([0-9]*)$"));
|
|
513
|
+
|
|
514
|
+
/**
|
|
515
|
+
* Extract cell coordinates.
|
|
516
|
+
*
|
|
517
|
+
* @param {String} label Cell coordinates (eq. 'A1', '$B6', '$N$98').
|
|
518
|
+
* @returns {Array} Returns an array of objects.
|
|
519
|
+
*/
|
|
520
|
+
function extractLabel(label) {
|
|
521
|
+
if (typeof label !== "string" || !LABEL_EXTRACT_REGEXP.test(label)) {
|
|
522
|
+
return [];
|
|
523
|
+
}
|
|
524
|
+
var _label$toUpperCase$ma = label.toUpperCase().match(LABEL_EXTRACT_REGEXP),
|
|
525
|
+
_label$toUpperCase$ma2 = _slicedToArray(_label$toUpperCase$ma, 6),
|
|
526
|
+
sheetNameStr = _label$toUpperCase$ma2[1],
|
|
527
|
+
columnAbs = _label$toUpperCase$ma2[2],
|
|
528
|
+
column = _label$toUpperCase$ma2[3],
|
|
529
|
+
rowAbs = _label$toUpperCase$ma2[4],
|
|
530
|
+
row = _label$toUpperCase$ma2[5];
|
|
531
|
+
if (column == null && row == null) return [];
|
|
532
|
+
var sheetName = sheetNameStr == null ? null : label.slice(0, sheetNameStr.length).replace(/^'|'$/g, "").replace(/''/g, "'");
|
|
533
|
+
return [{
|
|
534
|
+
index: rowLabelToIndex(row),
|
|
535
|
+
label: row,
|
|
536
|
+
isAbsolute: rowAbs === "$"
|
|
537
|
+
}, {
|
|
538
|
+
index: columnLabelToIndex(column),
|
|
539
|
+
label: column,
|
|
540
|
+
isAbsolute: columnAbs === "$"
|
|
541
|
+
}, sheetName];
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
/**
|
|
545
|
+
* Convert row and column indexes into cell label.
|
|
546
|
+
*
|
|
547
|
+
* @param {Object} row Object with `index` and `isAbsolute` properties.
|
|
548
|
+
* @param {Object} column Object with `index` and `isAbsolute` properties.
|
|
549
|
+
* @returns {String} Returns cell label.
|
|
550
|
+
*/
|
|
551
|
+
function toLabel(row, column) {
|
|
552
|
+
var rowLabel = (row.isAbsolute ? "$" : "") + rowIndexToLabel(row.index);
|
|
553
|
+
var columnLabel = (column.isAbsolute ? "$" : "") + columnIndexToLabel(column.index);
|
|
554
|
+
return columnLabel + rowLabel;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
/**
|
|
558
|
+
* Cell reference wrapper which keeps both the cell value and its label
|
|
559
|
+
* (eq. `A1`, `Sheet1!$B$3`). Functions like ROW/COLUMN need the position
|
|
560
|
+
* info instead of the value, so the parser must not unwrap it too early.
|
|
561
|
+
*/
|
|
562
|
+
var CellReference = /*#__PURE__*/function () {
|
|
563
|
+
function CellReference(label, value) {
|
|
564
|
+
_classCallCheck(this, CellReference);
|
|
565
|
+
this.label = label;
|
|
566
|
+
this.value = value;
|
|
567
|
+
}
|
|
568
|
+
return _createClass(CellReference, [{
|
|
569
|
+
key: "valueOf",
|
|
570
|
+
value: function valueOf() {
|
|
571
|
+
return this.value;
|
|
572
|
+
}
|
|
573
|
+
}]);
|
|
574
|
+
}();
|
|
575
|
+
|
|
576
|
+
/**
|
|
577
|
+
* Check whether the value is a cell reference wrapper.
|
|
578
|
+
*
|
|
579
|
+
* @param {*} value
|
|
580
|
+
* @returns {Boolean}
|
|
581
|
+
*/
|
|
582
|
+
function isCellReference(value) {
|
|
583
|
+
return value instanceof CellReference;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* Get the real value out of a cell reference wrapper.
|
|
588
|
+
*
|
|
589
|
+
* @param {*} value
|
|
590
|
+
* @returns {*}
|
|
591
|
+
*/
|
|
592
|
+
function toCellValue(value) {
|
|
593
|
+
return isCellReference(value) ? value.value : value;
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
/**
|
|
597
|
+
* Functions whose arguments are cell references instead of cell values
|
|
598
|
+
*/
|
|
599
|
+
var REFERENCE_FORMULAS = ["ROW", "COLUMN"];
|
|
600
|
+
|
|
601
|
+
/**
|
|
602
|
+
* Check whether the function needs cell references (labels) as params.
|
|
603
|
+
*
|
|
604
|
+
* @param {String} symbol Function name.
|
|
605
|
+
* @returns {Boolean}
|
|
606
|
+
*/
|
|
607
|
+
function isReferenceFormula(symbol) {
|
|
608
|
+
return REFERENCE_FORMULAS.includes(String(symbol).toUpperCase());
|
|
609
|
+
}
|
|
610
|
+
|
|
375
611
|
var SUPPORTED_FORMULAS = Object.keys(formulajs__namespace);
|
|
376
612
|
|
|
377
613
|
var SYMBOL$4 = SUPPORTED_FORMULAS;
|
|
@@ -381,11 +617,15 @@ function func$4(symbol) {
|
|
|
381
617
|
for (var _len = arguments.length, _params = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
382
618
|
_params[_key] = arguments[_key];
|
|
383
619
|
}
|
|
620
|
+
if (isReferenceFormula(symbol)) {
|
|
621
|
+
return referenceResult(symbol, _params);
|
|
622
|
+
}
|
|
384
623
|
var params = _params === null || _params === void 0 ? void 0 : _params.map(function (item) {
|
|
385
|
-
|
|
386
|
-
|
|
624
|
+
var value = toCellValue(item);
|
|
625
|
+
if (errors_formula_map[value]) {
|
|
626
|
+
return errors_formula_map[value];
|
|
387
627
|
} else {
|
|
388
|
-
return
|
|
628
|
+
return value;
|
|
389
629
|
}
|
|
390
630
|
});
|
|
391
631
|
var symbolParts = symbol.split(".");
|
|
@@ -423,6 +663,33 @@ function func$4(symbol) {
|
|
|
423
663
|
}
|
|
424
664
|
func$4.isFactory = true;
|
|
425
665
|
func$4.SYMBOL = SYMBOL$4;
|
|
666
|
+
|
|
667
|
+
/**
|
|
668
|
+
* 计算 ROW/COLUMN 一类以单元格引用(而不是单元格的值)作为入参的函数
|
|
669
|
+
*
|
|
670
|
+
* @param {String} fnName Function name.
|
|
671
|
+
* @param {Array} params Function params, may contain cell references.
|
|
672
|
+
* @returns {*}
|
|
673
|
+
*/
|
|
674
|
+
function referenceResult(fnName, params) {
|
|
675
|
+
var first = params[0];
|
|
676
|
+
if (isCellReference(first)) {
|
|
677
|
+
var _extractLabel = extractLabel(first.label),
|
|
678
|
+
_extractLabel2 = _slicedToArray(_extractLabel, 2),
|
|
679
|
+
row = _extractLabel2[0],
|
|
680
|
+
column = _extractLabel2[1];
|
|
681
|
+
var index = fnName === "ROW" ? row === null || row === void 0 ? void 0 : row.index : column === null || column === void 0 ? void 0 : column.index;
|
|
682
|
+
if (typeof index === "number" && index >= 0) {
|
|
683
|
+
return index + 1;
|
|
684
|
+
}
|
|
685
|
+
} else if (errors_formula_map[first]) {
|
|
686
|
+
return errors_formula_map[first];
|
|
687
|
+
} else if (typeof first === "number") {
|
|
688
|
+
// 兼容直接传入行号/列号的情况,如 ROW(3)
|
|
689
|
+
return first;
|
|
690
|
+
}
|
|
691
|
+
return errors_formula_map[ERROR_VALUE];
|
|
692
|
+
}
|
|
426
693
|
function tsParams(fnName, params) {
|
|
427
694
|
if (fnName === "SUMPRODUCT") {
|
|
428
695
|
var _params2;
|
|
@@ -564,7 +831,12 @@ func$a.SYMBOL = SYMBOL$a;
|
|
|
564
831
|
|
|
565
832
|
var SYMBOL$b = '<>';
|
|
566
833
|
function func$b(exp1, exp2) {
|
|
567
|
-
return exp1 !== exp2;
|
|
834
|
+
return normalize(exp1) !== normalize(exp2);
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
// Date 按 Excel 序列号比较,=TODAY()<>TODAY() 才是 FALSE
|
|
838
|
+
function normalize(value) {
|
|
839
|
+
return isDate(value) ? dateToSerialNumber(value) : value;
|
|
568
840
|
}
|
|
569
841
|
func$b.SYMBOL = SYMBOL$b;
|
|
570
842
|
|
|
@@ -628,13 +900,13 @@ registerOperation(func$a.SYMBOL, func$a);
|
|
|
628
900
|
registerOperation(func$b.SYMBOL, func$b);
|
|
629
901
|
registerOperation(func$9.SYMBOL, func$9);
|
|
630
902
|
|
|
631
|
-
var simpleSheetName = "[A-Za-z0-9_\u4E00-\u9FFF]+";
|
|
632
|
-
var quotedSheetName = "'(?:(?!').|'')*'";
|
|
633
|
-
var sheetNameRegexp = "(?:".concat(simpleSheetName, "|").concat(quotedSheetName, ")!");
|
|
634
|
-
var ABSOLUTE_CELL = new RegExp("^(?:".concat(sheetNameRegexp, ")?(?:[$][A-Za-z]+[$][0-9]+)"));
|
|
635
|
-
var MIXED_CELL_COL = new RegExp("^(?:".concat(sheetNameRegexp, ")?(?:[$][A-Za-z]+[0-9]*)"));
|
|
636
|
-
var MIXED_CELL_ROW = new RegExp("^(?:".concat(sheetNameRegexp, ")?(?:[A-Za-z]*[$][0-9]+)"));
|
|
637
|
-
var RELATIVE_CELL = new RegExp("^(?:".concat(sheetNameRegexp, ")?(?:(?:[A-Za-z]+[0-9]*)|(?:[A-Za-z]*[0-9]+))(?!\\d)(?!\\.)"));
|
|
903
|
+
var simpleSheetName$1 = "[A-Za-z0-9_\u4E00-\u9FFF]+";
|
|
904
|
+
var quotedSheetName$1 = "'(?:(?!').|'')*'";
|
|
905
|
+
var sheetNameRegexp$1 = "(?:".concat(simpleSheetName$1, "|").concat(quotedSheetName$1, ")!");
|
|
906
|
+
var ABSOLUTE_CELL = new RegExp("^(?:".concat(sheetNameRegexp$1, ")?(?:[$][A-Za-z]+[$][0-9]+)"));
|
|
907
|
+
var MIXED_CELL_COL = new RegExp("^(?:".concat(sheetNameRegexp$1, ")?(?:[$][A-Za-z]+[0-9]*)"));
|
|
908
|
+
var MIXED_CELL_ROW = new RegExp("^(?:".concat(sheetNameRegexp$1, ")?(?:[A-Za-z]*[$][0-9]+)"));
|
|
909
|
+
var RELATIVE_CELL = new RegExp("^(?:".concat(sheetNameRegexp$1, ")?(?:(?:[A-Za-z]+[0-9]*)|(?:[A-Za-z]*[0-9]+))(?!\\d)(?!\\.)"));
|
|
638
910
|
var NUMONLY = /^(?:[0-9]+$)/;
|
|
639
911
|
var stackCache;
|
|
640
912
|
var o = function o(k, v, _o, l) {
|
|
@@ -2049,118 +2321,6 @@ function trimEdges(string) {
|
|
|
2049
2321
|
return string;
|
|
2050
2322
|
}
|
|
2051
2323
|
|
|
2052
|
-
/**
|
|
2053
|
-
* Convert row label to index.
|
|
2054
|
-
*
|
|
2055
|
-
* @param {String} label Row label (eq. '1', '5')
|
|
2056
|
-
* @returns {Number} Returns -1 if label is not recognized otherwise proper row index.
|
|
2057
|
-
*/
|
|
2058
|
-
function rowLabelToIndex(label) {
|
|
2059
|
-
var result = parseInt(label, 10);
|
|
2060
|
-
if (isNaN(result)) {
|
|
2061
|
-
result = -1;
|
|
2062
|
-
} else {
|
|
2063
|
-
result = Math.max(result - 1, -1);
|
|
2064
|
-
}
|
|
2065
|
-
return result;
|
|
2066
|
-
}
|
|
2067
|
-
|
|
2068
|
-
/**
|
|
2069
|
-
* Convert row index to label.
|
|
2070
|
-
*
|
|
2071
|
-
* @param {Number} row Row index.
|
|
2072
|
-
* @returns {String} Returns row label (eq. '1', '7').
|
|
2073
|
-
*/
|
|
2074
|
-
function rowIndexToLabel(row) {
|
|
2075
|
-
var result = "";
|
|
2076
|
-
if (row >= 0) {
|
|
2077
|
-
result = "".concat(row + 1);
|
|
2078
|
-
}
|
|
2079
|
-
return result;
|
|
2080
|
-
}
|
|
2081
|
-
var COLUMN_LABEL_BASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
2082
|
-
var COLUMN_LABEL_BASE_LENGTH = COLUMN_LABEL_BASE.length;
|
|
2083
|
-
|
|
2084
|
-
/**
|
|
2085
|
-
* Convert column label to index.
|
|
2086
|
-
*
|
|
2087
|
-
* @param {String} label Column label (eq. 'ABB', 'CNQ')
|
|
2088
|
-
* @returns {Number} Returns -1 if label is not recognized otherwise proper column index.
|
|
2089
|
-
*/
|
|
2090
|
-
function columnLabelToIndex(label) {
|
|
2091
|
-
var result = 0;
|
|
2092
|
-
if (typeof label === "string") {
|
|
2093
|
-
label = label.toUpperCase();
|
|
2094
|
-
for (var i = 0, j = label.length - 1; i < label.length; i += 1, j -= 1) {
|
|
2095
|
-
result += Math.pow(COLUMN_LABEL_BASE_LENGTH, j) * (COLUMN_LABEL_BASE.indexOf(label[i]) + 1);
|
|
2096
|
-
}
|
|
2097
|
-
}
|
|
2098
|
-
--result;
|
|
2099
|
-
return result;
|
|
2100
|
-
}
|
|
2101
|
-
|
|
2102
|
-
/**
|
|
2103
|
-
* Convert column index to label.
|
|
2104
|
-
*
|
|
2105
|
-
* @param {Number} column Column index.
|
|
2106
|
-
* @returns {String} Returns column label (eq. 'ABB', 'CNQ').
|
|
2107
|
-
*/
|
|
2108
|
-
function columnIndexToLabel(column) {
|
|
2109
|
-
var result = "";
|
|
2110
|
-
while (column >= 0) {
|
|
2111
|
-
result = String.fromCharCode(column % COLUMN_LABEL_BASE_LENGTH + 97) + result;
|
|
2112
|
-
column = Math.floor(column / COLUMN_LABEL_BASE_LENGTH) - 1;
|
|
2113
|
-
}
|
|
2114
|
-
return result.toUpperCase();
|
|
2115
|
-
}
|
|
2116
|
-
var simpleSheetName$1 = "[A-Za-z0-9_\u4E00-\u9FFF]+";
|
|
2117
|
-
var quotedSheetName$1 = "'(?:(?!').|'')*'";
|
|
2118
|
-
var sheetNameRegexp$1 = "(".concat(simpleSheetName$1, "|").concat(quotedSheetName$1, ")!");
|
|
2119
|
-
var LABEL_EXTRACT_REGEXP = new RegExp("^(?:".concat(sheetNameRegexp$1, ")?([$])?([A-Za-z]*)([$])?([0-9]*)$"));
|
|
2120
|
-
|
|
2121
|
-
/**
|
|
2122
|
-
* Extract cell coordinates.
|
|
2123
|
-
*
|
|
2124
|
-
* @param {String} label Cell coordinates (eq. 'A1', '$B6', '$N$98').
|
|
2125
|
-
* @returns {Array} Returns an array of objects.
|
|
2126
|
-
*/
|
|
2127
|
-
function extractLabel(label) {
|
|
2128
|
-
if (typeof label !== "string" || !LABEL_EXTRACT_REGEXP.test(label)) {
|
|
2129
|
-
return [];
|
|
2130
|
-
}
|
|
2131
|
-
var _label$toUpperCase$ma = label.toUpperCase().match(LABEL_EXTRACT_REGEXP),
|
|
2132
|
-
_label$toUpperCase$ma2 = _slicedToArray(_label$toUpperCase$ma, 6),
|
|
2133
|
-
sheetNameStr = _label$toUpperCase$ma2[1],
|
|
2134
|
-
columnAbs = _label$toUpperCase$ma2[2],
|
|
2135
|
-
column = _label$toUpperCase$ma2[3],
|
|
2136
|
-
rowAbs = _label$toUpperCase$ma2[4],
|
|
2137
|
-
row = _label$toUpperCase$ma2[5];
|
|
2138
|
-
if (column == null && row == null) return [];
|
|
2139
|
-
var sheetName = sheetNameStr == null ? null : label.slice(0, sheetNameStr.length).replace(/^'|'$/g, "").replace(/''/g, "'");
|
|
2140
|
-
return [{
|
|
2141
|
-
index: rowLabelToIndex(row),
|
|
2142
|
-
label: row,
|
|
2143
|
-
isAbsolute: rowAbs === "$"
|
|
2144
|
-
}, {
|
|
2145
|
-
index: columnLabelToIndex(column),
|
|
2146
|
-
label: column,
|
|
2147
|
-
isAbsolute: columnAbs === "$"
|
|
2148
|
-
}, sheetName];
|
|
2149
|
-
}
|
|
2150
|
-
|
|
2151
|
-
/**
|
|
2152
|
-
* Convert row and column indexes into cell label.
|
|
2153
|
-
*
|
|
2154
|
-
* @param {Object} row Object with `index` and `isAbsolute` properties.
|
|
2155
|
-
* @param {Object} column Object with `index` and `isAbsolute` properties.
|
|
2156
|
-
* @returns {String} Returns cell label.
|
|
2157
|
-
*/
|
|
2158
|
-
function toLabel(row, column) {
|
|
2159
|
-
var rowLabel = (row.isAbsolute ? "$" : "") + rowIndexToLabel(row.index);
|
|
2160
|
-
var columnLabel = (column.isAbsolute ? "$" : "") + columnIndexToLabel(column.index);
|
|
2161
|
-
return columnLabel + rowLabel;
|
|
2162
|
-
}
|
|
2163
|
-
|
|
2164
2324
|
/**
|
|
2165
2325
|
* @class Parser
|
|
2166
2326
|
*/
|
|
@@ -2171,16 +2331,24 @@ var Parser$1 = /*#__PURE__*/function (_Emitter) {
|
|
|
2171
2331
|
_this = _callSuper(this, Parser$1);
|
|
2172
2332
|
_this.parser = new Parser();
|
|
2173
2333
|
_this.parser.yy = {
|
|
2174
|
-
toNumber: toNumber
|
|
2334
|
+
toNumber: function toNumber$1(value) {
|
|
2335
|
+
return toNumber(toCellValue(value));
|
|
2336
|
+
},
|
|
2175
2337
|
trimEdges: trimEdges,
|
|
2176
|
-
invertNumber: invertNumber
|
|
2338
|
+
invertNumber: function invertNumber$1(value) {
|
|
2339
|
+
return invertNumber(toCellValue(value));
|
|
2340
|
+
},
|
|
2177
2341
|
throwError: function throwError(errorName) {
|
|
2178
2342
|
return _this._throwError(errorName);
|
|
2179
2343
|
},
|
|
2180
2344
|
callVariable: function callVariable(variable) {
|
|
2181
2345
|
return _this._callVariable(variable);
|
|
2182
2346
|
},
|
|
2183
|
-
|
|
2347
|
+
// ROW/COLUMN 的入参需要引用(label),不能解包成值
|
|
2348
|
+
evaluateByOperator: function evaluateByOperator$1(operator) {
|
|
2349
|
+
var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
2350
|
+
return evaluateByOperator(operator, isReferenceFormula(operator) ? params : params.map(toCellValue));
|
|
2351
|
+
},
|
|
2184
2352
|
callFunction: function callFunction(name, params) {
|
|
2185
2353
|
return _this._callFunction(name, params);
|
|
2186
2354
|
},
|
|
@@ -2233,6 +2401,9 @@ var Parser$1 = /*#__PURE__*/function (_Emitter) {
|
|
|
2233
2401
|
if (result instanceof Error) {
|
|
2234
2402
|
error$1 = error(result.message) || error(ERROR);
|
|
2235
2403
|
result = null;
|
|
2404
|
+
} else {
|
|
2405
|
+
// `=A1` 这类表达式的结果是引用包装对象,对外只返回值本身
|
|
2406
|
+
result = toCellValue(result);
|
|
2236
2407
|
}
|
|
2237
2408
|
return {
|
|
2238
2409
|
error: error$1,
|
|
@@ -2337,15 +2508,18 @@ var Parser$1 = /*#__PURE__*/function (_Emitter) {
|
|
|
2337
2508
|
value: function _callFunction(name) {
|
|
2338
2509
|
var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
2339
2510
|
var fn = this.getFunction(name);
|
|
2511
|
+
var args = params.map(toCellValue);
|
|
2340
2512
|
var value;
|
|
2341
2513
|
if (fn) {
|
|
2342
|
-
value = fn(
|
|
2514
|
+
value = fn(args);
|
|
2343
2515
|
}
|
|
2344
|
-
this.emit("callFunction", name,
|
|
2516
|
+
this.emit("callFunction", name, args, function (newValue) {
|
|
2345
2517
|
if (newValue !== void 0) {
|
|
2346
2518
|
value = newValue;
|
|
2347
2519
|
}
|
|
2348
2520
|
});
|
|
2521
|
+
|
|
2522
|
+
// `params` 里可能带着单元格引用(ROW/COLUMN 需要),由 formula-function 自行解包
|
|
2349
2523
|
return value === void 0 ? evaluateByOperator(name, params) : value;
|
|
2350
2524
|
}
|
|
2351
2525
|
|
|
@@ -2381,7 +2555,9 @@ var Parser$1 = /*#__PURE__*/function (_Emitter) {
|
|
|
2381
2555
|
}, this.options, function (_value) {
|
|
2382
2556
|
value = _value;
|
|
2383
2557
|
});
|
|
2384
|
-
|
|
2558
|
+
|
|
2559
|
+
// 同时保留 label,供 ROW/COLUMN 等需要引用位置的函数使用
|
|
2560
|
+
return new CellReference(label, value);
|
|
2385
2561
|
}
|
|
2386
2562
|
|
|
2387
2563
|
/**
|