找回密码
 立即注册

QQ登录

只需一步,快速开始

Richard.HuangSpreadJS 开发认证
超级版主   /  发表于:2024-3-20 16:02:53
12#
Joker0824 发表于 2024-3-20 14:03
你好,这是我在下载的示例中测试结果,大部分都达不到要求。
另外这个公式引用格式的计算,具体策略还有 ...

我详细查看了您提供的demo,我们的格式提示功能确实无法完全满足您的需求,对于您目前所描述的复杂需求来看我们没有一个现成的API可以直接满足您的需求.
如果您确实对这个有所需要,那么您需要自己来进行自定义设计,以下是一个您可以参考的是实现方式:
1. 您通过监听用户键入公式的操作
2. 动态的为用户操作的单元格去设置保留几位小数
以下是一个示例,你可以在这个示例基础上进行拓展,覆盖到您所需要的所有场景
  1. sheet.bind(GC.Spread.Sheets.Events.UserFormulaEntered, function (e, info) {
  2.     var row = info.row;
  3.     var col = info.col;
  4.     var formula = info.formula;
  5.     var sheet = info.sheet;
  6.     var precedentCells = sheet.getPrecedents(0, 2)
  7.     evaluate(formula)
  8.     // 1. 解析公式字符串
  9.     const pattern = /(SUM|SUBTRACT|MULTIPLY|DIVIDE)\(([^)]+)\)/i;
  10.     const match = formula.match(pattern);
  11.     var n = 0;
  12.     // 2. 根据不同公式设置不同的格式
  13.     if (match) {
  14.         switch (match[1].toUpperCase()) {
  15.             case 'SUM':
  16.                 // 加法,以小数位最多的那个为准
  17.                 precedentCells.forEach(cellRange => {
  18.                     for (var i = cellRange.row; i < cellRange.rowCount; i++) {
  19.                         for (var j = cellRange.col; j < cellRange.colCount; j++) {
  20.                             n = Math.max(n, getDecimalLength(sheet.getText(i, j)))
  21.                         }
  22.                     }
  23.                 });
  24.             case 'SUBTRACT':
  25.             // 减法,以小数位最多的那个为准, 同上
  26.             case 'MULTIPLY':
  27.                 // 乘法,以小数位和为结果的小数位
  28.                 precedentCells.forEach(cellRange => {
  29.                     for (var i = cellRange.row; i < cellRange.rowCount; i++) {
  30.                         for (var j = cellRange.col; j < cellRange.colCount; j++) {
  31.                             n = getDecimalLength(sheet.getText(i, j)) + n;
  32.                         }
  33.                     }
  34.                 });
  35.             case 'DIVIDE':
  36.                 // 除法,以小数位和为结果的小数位
  37.                 return 'Division (/)';
  38.             default:
  39.                 return 'Unknown operation';
  40.         }
  41.     }
  42.     sheet.setFormatter(row, col, generateZeros(n))
  43. });

  44. function generateZeros(n) {
  45.     // 检查n是否为正整数
  46.     if (!Number.isInteger(n) || n <= 0) {
  47.         return "0"
  48.     }
  49.     let result = '0.'; // 开始拼接字符串
  50.     // n-1次,循环添加零
  51.     for (let i = 1; i < n; i++) {
  52.         result += '0';
  53.     }
  54.     return result;
  55. }

  56. function getDecimalLength(num) {
  57.     if (!Number.isFinite(num)) return 0; // 对非有限数返回0
  58.     let e = 1, p = 0;
  59.     while (Math.round(num * e) / e !== num) { e *= 10; p++; }
  60.     return p;
  61. }
复制代码
API:

回复 使用道具 举报
Joker0824
注册会员   /  发表于:2024-3-20 18:13:54
13#
Richard.Huang 发表于 2024-3-20 16:02
我详细查看了您提供的demo,我们的格式提示功能确实无法完全满足您的需求,对于您目前所描述的复杂需求来 ...

感谢,那我这边参考您的方案,看看是否能实现。
回复 使用道具 举报
Richard.HuangSpreadJS 开发认证
超级版主   /  发表于:2024-3-21 09:24:28
14#
Joker0824 发表于 2024-3-20 18:13
感谢,那我这边参考您的方案,看看是否能实现。

回复 使用道具 举报
Joker0824
注册会员   /  发表于:2024-3-26 16:45:54
15#

版主好,简单的纯加减法,还可以模拟进行解析,但是复杂的四则运算,或 带函数的四则运算,例如(a*b)/(常量+常量*(b-常量))或MIN((a-b)/b,(c-b)/b,(d-b)/b,(e-b)/b) , 这种的我们这边不好解析。
咨询下,spreadjs 是怎么用js去解析公式的?如何能按步骤和顺序获取到每个运算的关系,是否有API可以参考?
回复 使用道具 举报
Richard.HuangSpreadJS 开发认证
超级版主   /  发表于:2024-3-26 17:40:54
16#
Joker0824 发表于 2024-3-26 16:45
版主好,简单的纯加减法,还可以模拟进行解析,但是复杂的四则运算,或 带函数的四则运算,例如(a*b)/(常 ...

SpreadJS底层有个专门设计的公式引擎来解析公式和进行计算,这一块是封装起来的,不会让用户感知到组合计算中每一层计算的过程的,因此我们没有对应的API去获取这个过程。
解析公式和计算公式属于SpreadJS的底层设计,不属于技术支持的范畴。
因此您只能在上面我提供的方法的基础上进行解析和处理,或者您如果有其他更好地方法来处理,也欢迎分享和交流
回复 使用道具 举报
Joker0824
注册会员   /  发表于:2024-3-27 10:04:46
17#
Richard.Huang 发表于 2024-3-26 17:40
SpreadJS底层有个专门设计的公式引擎来解析公式和进行计算,这一块是封装起来的,不会让用户感知到组合计 ...

好的,感谢。
回复 使用道具 举报
Richard.HuangSpreadJS 开发认证
超级版主   /  发表于:2024-3-27 11:39:03
18#

好的,本帖子的问题解决,这里就先结帖了。后续如果您有新的问题,也欢迎创建新的求助帖。
回复 使用道具 举报
12
您需要登录后才可以回帖 登录 | 立即注册
返回顶部