报表开发之自定义函数

简介:

对于报表开发,很多情况下,自带的函数就能满足大部分用户的报表制作需求,FineReport也不例外。但是在一些特殊领域,可能需要一些特殊的函数,在这种情况下,FineReport提供了自定义函数机制,可以由用户根据业务需要自己来定义一些函数,但这些函数必须满足函数定义规则。

先来了解一下FineReport的函数定义规则:Functionname(Para,Para,...),其中Functionname为函数名,Para为参数。

每一个函数都被定义成一个类,这个类必须要实现Function这个接口,在运算的时候首先通过函数名反射取得这个类,然后调用它的run(Object[] agrs)方法。下面以SUM这个函数为例。

SUM函数原理

由程序可以看到,SUM类用来运算SUM函数,他继承了AbstractFunction类,而AbstractFunction实现了Function这个接口。

当函数运算的时候,先根据函数名取得运算该函数的类,如SUM(2,4,true)这个函数先根据函数名取得SUM这个类,然后调用SUM类的run(Object[] args)方法,args中存放的是SUM函数的参数,运算的时候可以从args中取得参数进行运算。如执行结果为SUM(2,4,true)=2+4+1=7。

SUM函数所使用代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
packagecom.fr.report.script;
importjava.lang.reflect.Array;
importcom.fr.report.script.core.FArray;
importcom.fr.report.script.core.FunctionHelper;
public  class  SUM extendsAbstractFunction {
          public  Object run(Object[] args) {
                    double  result =  0 ;
                    for  ( int  i =  0 ; i < args.length; i++) {
                             if  (args[i] ==  null ) {
                                      continue ;
                             }
                             result += parseObject(args[i]);
                    }
                    returnFunctionHelper.parsePrimitiveDouble(result);
          }
          private  double  parseObject(Object obj) {
                    if  (obj  instanceof  Number) {
                             return  ((Number) obj).doubleValue();
                    else  if  (obj  instanceof  Boolean) {
                             return  ((Boolean) obj).booleanValue() ?  1 0 ;
                    else  if  (obj  instanceof  FArray) {
                             FArray array = (FArray) obj;
                             double  sum =  0 ;
                             for  ( int  i =  0 ; i < array.length();i++) {
                                      sum +=parseObject(array.elementAt(i));
                             }
                             return  sum;
                    else  if  (obj !=  null ) {
                             try  {
                                      returnDouble.parseDouble(obj.toString());
                             catch  (NumberFormatException exp) {
                                      return  0 ;
                             }
                    }
                    return  0 ;
          }
}

实现步骤

编写自定义函数

下面以一个简单的自定义函数例子来说明使用自定义函数。我们定义一个函数StringCat,他的作用是把所有的参数以字符串的形式连接起来。

StringCat函数使用规则为StringCat(Para,Para,Para…….);

其中Para为该函数的参数,个数不限。

由概述可知AbstractFunction实现了Function这个接口,因此StringCat可以直接继承AbstractFunction类,完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package  com.fr.function;
  
importcom.fr.script.AbstractFunction;
  
public  class  StringCatextends AbstractFunction {
          public  Object run(Object[] args) {
                    String result =  "" ;
                    Object para;
                    for  ( int  i =  0 ; i < args.length; i++) {
                             para = args[i];
                             result += para.toString();
                    }
                    return  result;
          }
}

这里要注意,使用函数StringCat(Para,Para,Para…..)时,根据函数名取得运算该函数的类StringCat,并将参数传入类中的args对象数组中,执行该类的run函数。

而在run函数中即实现了将传入的参数以字符串的形式连接起来。并返回最终形成的字符串。

编译自定义函数

将编译后的StringCat.class放到FineReport的安装目录WEB-INF下面的classes目录下,因为StringCat.java属于包com.fr.function,所以StringCat.class需要放到classes\com\fr\function目录下。

注册自定义函数

生成该函数的类后需要在设计器中进行注册,才可以使用该函数。打开服务器|函数管理器,选择刚刚定义好了StringCat类,如下图


函数名称可以自定义,如这边定义为StringCat;

同时可以添加该函数的使用说明,如上图所示的描述

使用自定义函数

注册好自定义函数后,制作报表时便可直接使用了,使用方法与内置的函数是相同的。

新建报表,定义两个报表参数para1、para2,类型分别为字符串型与整形,默认值分别为空字符串与0

在空白报表的任意单元格里写入公式:=StringCat($para1,$para2)(注意:写入公式的时候在参数名前加$,表明这是使用的参数)

点击分页预览在参数控件中,写入参数值如para1为:FineReport,para2为:123。

点击查询可以看到结果

说明StringCat公式可以正常使用啦。



本文转自 雄霸天下啦 51CTO博客,原文链接:http://blog.51cto.com/10549520/1828359,如需转载请自行联系原作者
相关文章
|
存储
【C盘瘦身】如何清理Wechat Files,经常使用电脑微信用户必知的常识!
【C盘瘦身】如何清理Wechat Files,经常使用电脑微信用户必知的常识!
4570 0
【C盘瘦身】如何清理Wechat Files,经常使用电脑微信用户必知的常识!
|
存储 JavaScript Linux
Linux环境下安装nmp(Centos环境)保姆级教学 一步到位
Linux环境下安装nmp(Centos环境)保姆级教学 一步到位
|
9月前
|
传感器 安全 前端开发
如何开发一套EHS健康安全环境管理系统中的风险管理板块?(附架构图+流程图+代码参考)
本文详解企业EHS(健康·安全·环境)系统中的风险管控板块,强调其核心在于构建“识别—评估—巡检—治理—验证”的闭环流程,将风险数据可视化并转化为可落地的行动指引。内容涵盖风险管控的意义、功能边界、系统架构、LEC评估方法、巡检流程、看板设计、开发技巧、落地建议、实现效果及代码参考,帮助技术团队和EHS负责人快速掌握系统搭建要点,提升企业安全管理水平。
|
机器学习/深度学习 人工智能 安全
《昇腾芯片:鸿蒙NEXT人工智能算力体系的核心驱动力》
在人工智能快速发展的背景下,鸿蒙NEXT操作系统与昇腾芯片的结合带来了重大变革。昇腾芯片凭借卓越的计算性能(如昇腾910的320 TFLOPS半精度算力),加速模型训练和推理,缩短训练时间,提升效率。它与鸿蒙NEXT深度融合,实现高效协同,支持多场景应用,从云端到终端提供强大算力,并通过星盾安全架构保障数据安全。这一组合为智能生态的发展奠定了坚实基础。
877 14
|
存储 JSON JavaScript
【HarmonyOS Next之旅】基于ArkTS开发(一) -> Ability开发二
本文档介绍了DataAbility开发、FA卡片开发和WantAgent开发三大模块的内容。DataAbility开发涵盖场景介绍、接口说明及开发步骤,支持数据共享与管理;FA卡片开发包括卡片概述、生命周期回调、接口说明及页面设计,助力应用信息前置展示;WantAgent开发则聚焦行为意图封装,提供启动Ability和发布公共事件的功能。文档详细解析了各模块的实现流程与关键代码示例,为开发者提供了全面指导。
280 20
|
人工智能 自然语言处理 数据挖掘
从行业痛点到AI前沿:揭秘AGI时代企业培训的终极之选
近几年接触到的各类培训合作方越来越多,从国际咨询巨头、互联网科技培训平台,到本土独角兽型的专业培训公司;从专攻新技术与创新场景的培训团队,到深谙传统行业痛点的咨询顾问。作为一名在央企、国企、上市公司人力资源培训条线深耕多年的HR负责人,深知在这片竞争激烈的培训服务蓝海中,寻找高质、高效的合作伙伴并不简单,因为企业培训的逻辑正在悄然改变。
1005 10
|
JavaScript 前端开发 算法
JavaScript 解密技巧大分享
JavaScript 解密技巧大分享
431 2
|
新能源
空间太阳能发电:从太空到地球的清洁能源
【10月更文挑战第12天】空间太阳能发电技术是一项具有革命性意义的清洁能源技术。它结合了航天技术与新能源技术的优势,为地球带来了前所未有的清洁能源革命。尽管在实现过程中面临诸多挑战,但随着技术的不断进步和创新,空间太阳能发电有望成为未来全球电力供应的主要来源之一,为人类的可持续发展贡献更多力量。让我们共同期待空间太阳能发电技术的美好未来!
|
编解码 Linux 开发工具
大牛直播SDK跨平台RTMP直播推送模块技术设计和功能列表
大牛直播SDK是一款跨平台RTMP直播推送模块,支持Windows、Linux(x64_64与aarch64架构)、Android及iOS平台。该SDK功能全面,包括摄像头、屏幕、麦克风等数据采集与推送,并支持编码前后数据对接。其架构设计优秀,确保低延迟与高效率,结合SmartPlayer播放器实现毫秒级延迟体验。具备全自研框架,易于扩展且支持多种数据源接入,如外部YUV/RGB/H.264等格式。此外,各平台支持特性丰富,如Windows平台支持多摄像头合成,Android与iOS平台支持前后摄像头实时切换等。大牛直播SDK还提供了多个示例项目以帮助开发者快速上手。
621 0
|
前端开发 JavaScript 数据库
从零开始搭建创业公司全新技术栈解决方案
创业公司在初期面临的挑战之一就是如何构建一个既能满足当前需求,又能适应未来发展的技术栈。本文将全面探讨从后端到前端,再到云原生技术和AI大模型应用的各个层面,帮助创业者了解如何选择合适的开发语言、框架、工具,以及如何制定有效的开发流程,从而搭建一个强大而稳定的技术体系。
1318 1
从零开始搭建创业公司全新技术栈解决方案