【luckysheet】自定义公式设置

版本:luckysheet@2.1.13

目录

一、源码查看

1.1. 入口

1.2. 自定义公式可能的参数

二、TypeScript定义

三、插入到表格

 3.1. 创建表格

 3.2. 公式定义

四、使用效果


一、源码查看

1.1. 入口

 查看源码入口可知,传入一个自定义函数数组,它会自动注册到全局和仓库,且含有<n>和<f>属性,并且自定义函数设置在创建工作簿的配置中

// 入口:src/core.js 56行
luckysheet.create = function (setting) {
    // 66 行:通用继承,得到新的对象,并继承传入对象的所有可枚举属性
    let extendsetting = common_extend(defaultSetting, setting);
    // 160 行
    functionlist(extendsetting.customFunctions);
}

// 函数详解:src/function/functionlist.js (中文为自己的注释)
const functionlist = function(customFunctions){ // 参数表示传入的自定义函数列表
    let _locale = locale(); // 拿到国际化的语言文本对象
    // internationalization,get function list
    let functionListOrigin = [...getLocalizedFunctionList(_locale.functionlist)]; // 拿到原有的函数列表

    // add new property f
    for (let i = 0; i < functionListOrigin.length; i++) {
        let func = functionListOrigin[i];
        func.f = functionImplementation[func.n];
    }
    // 如果传入了自定义函数数组
    if (customFunctions) {
        functionListOrigin.push(...customFunctions);
    }
    // 将函数数组写到数据仓库
    Store.functionlist = functionListOrigin;
    
    // get n property
    const luckysheet_function = {};

    for (let i = 0; i < functionListOrigin.length; i++) {
        let func = functionListOrigin[i];
        luckysheet_function[func.n] = func;
    }

    window.luckysheet_function = luckysheet_function; //Mount window for eval() calculation formula
    
    Store.luckysheet_function = luckysheet_function;
}

1.2. 自定义公式可能的参数

在文件src/controllers/insertFormula.js搜索luckysheet_functionfunctionlist等内容,可在30行、71行、211行等地方,知道自定义公式可能这样定义

interface customFunctions {
    n: string;
    p: Array<{
        detail: string;
        repeat: 'y' | 'n';
        name: string;
    }>;
    d: string;
    a: string;
    t: string;
}

 另外一个文件的源码

// src/global/formula.js 1060 行

//"n": "AVERAGE",
//"t": "1",
//"d": "返回数据集的算术平均值,对文本忽略不计。",
//"a": "返回数据集的算术平均值",
//"p": [{ "name": "数值1", "example": "A2:A100", "detail": "计算平均值时用到的第一个数值或范围。", "require": "m", "repeat": "n", "type": "rangenumber" },
//    { "name": "数值2", "example": "B2:B100", "detail": "计算平均值时用到的其他数值或范围。", "require": "o", "repeat": "y", "type": "rangenumber" }
//]

 根据上述源码以及页面实际显示的情况,可以完成自定义公式参数的类型定义。

二、TypeScript定义

export type ICustomFunction = {
    /**函数名 */
    n: string;
    /**函数返回类型 */
    t: any;
    /**函数参数个数 */
    m: [number, number];
    /**每个参数的描述 */
    p: Array<ICustomFunctionArgumentDescription>;
    /**
     * 公式执行的函数
     * 
     * `this` 指向与函数同级的自定义对象
     */
    f: Function;
    /**
     * 摘要
     * 
     * 进行公式参数编辑时显示的摘要提示
     */
    d: string;
    /**
     * 描述
     * 
     * 输入 "=公式名"的时候显示的提示
     */
    a: string;
};

export type ICustomFunctionArgumentDescription = {
    /**参数使用示例 */
    example: string;
    require: /**必填 */"m" | /**选填 */ "o";
    /**
     * 是否重复
     * 
     * 重复意味着剩余参数都是如此
     */
    repeat: /**否 */"n" | /**是 */ "y";
    /**参数类型 */
    type: TCellFormat_t | 0;
    /**参数名 */
    name: string;
    /**参数文字说明 */
    detail: string;
};

三、插入到表格

 3.1. 创建表格

import customFunctions from './customFunctions';

const options = {
    container: 'luckysheet',
    title: '标题',
    lang: 'zh',
    gridKey: '35as4d#-a6s54we3f1we5f4f3asd5f4d3',
    myFolderUrl: `myFolderUrl`,
    loadUrl: `server/luckysheet/api/load`,
    allowUpdate: true,
    updateUrl: `ws/url`,
    customFunctions: [
        ...customFunctions,
    ],
};

luckysheet.create(options);

 3.2. 公式定义

// 自定义公式
const customFunctions: Array<ICustomFunction> = [
    TOJSON,
];


/**
 * 自定义公式参数 - 选区类型[区域模式]
 */
export type CustomFunctionArgumentRangeTable = {
    /**单元格连续的列 */
    coll: Exclude<number, 1>;
    /**单元格的数据 */
    data: Array<Array<ICell>>;
    /**单元格连续的行 */
    rowl: Exclude<number, 1>;
    /**单元格所属表格的名称 */
    sheetName: string;
    /**单元格开始位置 */
    startCell: string;
};

export const TOJSON: ICustomFunction = {
    n: "TOJSON",
    t: 0,
    m: [1, 1],
    a: "将指定区域的内容转为JSON字符串",
    d: "转换区域表格为JSON",
    p: [
        {
            example: "\"Sheet2!B2:H11\"",
            require: "m",
            repeat: "n",
            type: 0,
            name: "表格区域",
            detail: "将选区转为JSON",
        },
    ],
    f: function() {
        //必要参数个数错误检测
        if(arguments.length < this.m[0]) {
            return '参数不足';
        }
        if(arguments.length > this.m[1]) {
            return '参数过多';
        }

        const [_range] = (arguments as unknown) as [ CustomFunctionArgumentRangeTable ];

        if(_range.coll === 1 || _range.rowl === 1) {
            return "选区异常";
        }
        // const data_prev = transpose(_range.data);
        const jsonObject = [];
        for(let row = 1; row < _range.data.length; row++) {
            const rowJsonObject: {[key: string]: string} = {};

            // 如果这一行都是空的,就要结束了
            if(_range.data[row].every(col => !col || !col.m)) break;

            for(let col = 0; col < _range.data[row].length; col++) {
                const key = _range.data[0][col] ? _range.data[0][col].m : '';
                const value = _range.data[row][col] ? _range.data[row][col].m : '';
                rowJsonObject[key] = value;
            }
            jsonObject.push(rowJsonObject);
        }
        return JSON.stringify(jsonObject);
    }
}

四、使用效果

图1  输入公式过程提示
图2  公式参数提示
图3  公式执行结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值