基于 groovy 实现公式库 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
xinQing
V2EX    Java

基于 groovy 实现公式库

  •  
  •   xinQing 2020-05-12 22:24:45 +08:00 2471 次点击
    这是一个创建于 2028 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在工作中基于 groovy 设计的公式库,希望能带给大家帮助。

    项目地址

    Github

    语法

    公式名(参数) 

    比如:

    ECHO(大侠王波波) 

    支持公式嵌套:

    公式名 1(公式名 2(参数), 参数) 

    比如:

    ECHO(UUID)) 

    快速开始

    1. 创建 Formula 对象 formula
    2. 运行 formula.run("script")

    下面是例子:

    package tk.fishfish.formula; import org.junit.Assert; import org.junit.Before; import org.junit.Test; /** * 公式测试 * * @author 奔波儿灞 * @since 1.0 */ public class FormulaTest { private Formula formula; @Before public void setup() { formula = new Formula(); } @Test public void lower() { Object result = formula.run("LOWER(ABC)"); Assert.assertEquals("abc", result); } } 

    默认公式

    这里只是抛砖引玉,实现了如下文本公式:

    • UUID() 返回 uuid
    • LOWER(xxx) 转小写
    • UPPER(xxx) 转大写

    这里未实现丰富文本、时间、数学、逻辑等公式,只是提供一个扩展机制,方便大家定制自己的公式库。

    开发自己的公式

    • 继承 Plugin 接口

      package tk.fishfish.formula.plugin; import tk.fishfish.formula.annotation.FormulaMapping; /** * 自定义公式 * * @author 奔波儿灞 * @since 1.0 */ public class CustomPlugin implements Plugin { /** * 实现自己的公式 * * @param name 参数 * @return 结果 */ @FormulaMapping("ECHO") public String echo(String name) { return "echo: " + name; } } 
    • 自定义方法,增加 @FormulaMapping 注解 映射公式名称

    • 安装插件类,FormulaScript.installPlugin(CustomPlugin.class)

      package tk.fishfish.formula; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import tk.fishfish.formula.plugin.CustomPlugin; import tk.fishfish.formula.script.FormulaScript; import java.math.BigDecimal; /** * 公式测试 * * @author 奔波儿灞 * @since 1.0 */ public class FormulaTest { private Formula formula; @BeforeClass public static void init() { // 安装自己的公式插件 FormulaScript.installPlugin(CustomPlugin.class); } @Before public void setup() { formula = new Formula(); } @Test public void plugin() { Object result = formula.run("ECHO(xxx)"); System.out.println(result); } } 

    注意:

    • 先安装自己的公式,再创建 Formula 对象
    • 公式名全局不可重复

    SPI 扩展

    除了可以手动 FormulaScript.installPlugin(CustomPlugin.class) 安装自定义公式以外,还能通过 SPI 注册。

    在 src/main/resources/META-INF/services 目录下创建名称为 tk.fishfish.formula.plugin.Plugin 的文件,里面是实现类的全类名:

    # custom plugin tk.fishfish.formula.plugin.CustomPlugin 

    此时,会自动通过 SPI 机制发现实现类,自动安装,实现解偶。

    5 条回复    2020-05-13 09:13:56 +08:00
    pkwenda
        1
    pkwenda  
       2020-05-13 01:41:34 +08:00
    看着,如果做财务相关这样用会方便一些,可读性更好,性能方面 [eg:动态编译] 有测试损耗吗?
    pkwenda
        2
    pkwenda  
       2020-05-13 01:41:50 +08:00
    @pkwenda #1 看着不错,吃字了
    w292614191
        3
    w292614191  
       2020-05-13 08:51:44 +08:00
    我们实现了 Excel 公式计算、行列变换、单元格引用计算、函数解析。
    xinQing
        4
    xinQing  
    OP
       2020-05-13 09:12:00 +08:00
    @pkwenda 初略测试下来,单次公式计算在 10ms 以下(主要看实现的代码,内存计算都相当快)。
    xinQing
        5
    xinQing  
    OP
       2020-05-13 09:13:56 +08:00
    @w292614191 我们主要是实现表单公式(比如,表单字段涉及数据变换、依赖),excel 这块到没有涉略噢
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2921 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 13:20 PVG 21:20 LAX 05:20 JFK 08:20
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86