Derrick.Jiao 发表于 2022-2-28 10:27:04

利用自定义特性实现在单元格上同时设置公式和值

在单元格设置过公式以及设置过值的朋友应该不难发现,我们的单元格上只允许设置公式或数值,如果两者同时设置,那么后设置的会将前面设置的覆盖。在单元格上的操作也是一样,这个也是与Excel相同的。可以简单理解为是一个“互斥”的操作,因为单元格上设置了公式,那么所显示的就是公式计算所返回的值,那如果单元格上是赋值操作,那么就会显示设置的值。就好比单元格上原本有一个公式,我双击进入编辑状态,然后将公式删除再输入我的值;或者是单元格上原本有一个数值,我双击进入编辑状态,然后将值删除输入了我的公式。

那么基于上面这样一种设计,我们应该如果实现这样一个需求呢?当设值为undefined或null时,显示公式的计算结果,当设值为非undefinded或非null时显示设值的结果。我们可以通过自定义单元格来实现。在开始前,我们先来了解一个api:evaluateFormula。



上图是关于这个api参数的一个完整介绍以及demo,那么是用来干什么的呢?这个接口可以直接用来计算我们所需的公式。直接利用我们的计算引擎,从而可以达到“脱离”单元格得到计算结果。什么意思呢?就是通过这个接口,我们可以不需要在单元格上setFormula,就能拿到某些公式计算的值。就像上面的示例那样,传入要计算的表单、公式以及基本行列索引,就可以进行计算并返回结果。这在某些场景下是非常有用的。
GC.Spread.Sheets.CalcEngine.evaluateFormula(sheet, "SUM(A1:A2)", 0, 0);

再往下就是我们自定义单元格的绘制逻辑了,在paint方法中,我们会在里面做一个判断,当单元格的值显示为null时,我们就将公式的结果绘制上去。当单元格的值不为空时,我们就显示原本的数值。
formulaValueCellType.prototype.paint = function (ctx, value, x, y, w, h, style, context) {
                var sheet = context.sheet;
                if (value === null || value === void 0) {
                  try {
                        value = GC.Spread.Sheets.CalcEngine.evaluateFormula(sheet, this.formula);
                  } catch {
                        //do nothing;
                  }
                } else {
                  GC.Spread.Sheets.CellTypes.Text.prototype.paint.apply(this, arguments);
                }
                GC.Spread.Sheets.CellTypes.Text.prototype.paint.apply(this, arguments);
            }

自定义单元格部分的主要逻辑就是上面的代码,比较简单,可以下载附件去看下效果以及完整代码。
页: [1]
查看完整版本: 利用自定义特性实现在单元格上同时设置公式和值