QLExpress:GitHub - alibaba/QLExpress: QLExpress is a powerful, lightweight, dynamic language for the Java platform aimed at improving developers’ productivity in different business scenes.
public static void main(String[] args) {
// 统计时,会传递日期和数据板块id,数据板块id的用处就是获取计算公式
// 假如这就是我们获取到的某一个数据板块的公式
String str = "avg(item_code_f,item_code_b) +item_code_a ÷ item_code_k - 100";
// 处理一下÷和×,毕竟是以*和/作为乘法除法符号的
str = str.replace("÷","/");
str = str.replace("×","*");
// 定义一个正则表达式,过滤掉计算符号
String regex = "[()*+/-]";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(str);
List<String> list = new ArrayList<>();
// 这里注意要先转成Set然后再转成List,因为有可能计算的时候要使用一个数据项的值多次,但是其实都是同一个值
list.addAll(Arrays.asList(m.replaceAll(" ").split(" ")).stream().filter(s->{
// 通过流来单独过滤avg和数字
return !s.equals("avg")&&!s.equals("")&&!isNumeric(s);
}).collect(Collectors.toSet()));
// 输出一下结果:[item_code_f,item_code_b,item_code_a,item_code_k],这样就成功的将数据项编码给分离出来
System.out.println(list.toString());
// 然后通过数据项编码可以把对应的统计日期下,对应的数据项编码的数量或者金额获取到,然后通过replace()方法替换调即可
// 具体从数据库里取值和替换的代码省略。。。嘿嘿,偷个懒 >_<|||
// 最后得到大概这样的数据:avg(1000,2000)+30/2-100
String express = "avg(1000,2000)+30/2-100";
// 接下来就是使用QLExpress了
ExpressRunner runner = new ExpressRunner();
// 先定义我们需要的avg函数
runner.addFunction("avg",new Operator(){
@Override
public Object executeInner(Object[] objArray) throw Exception{
Double total=0.0;
Double average=0.0;
for(Double obj: objArray){
Double num=Double.valueOf(obj.toString());
total = total + num;
}
average = total/objArray.length;
return average;
}
});
// 计算结果,这里是一个重载方法,没有log
Object result = runner.execute(express,null, null, false,false);
// 顺利拿到结果:1415
Double resultNum = Double.valueOf(result.toString());
}
/**
* 判断是否是数字
*/
public static boolean isNumeric(String str){
Pattern pattern = Pattern.compile("[0-9]*");
Matcher isNum = pattern.matcher(str);
if( !isNum.matches() ){
return false;
}
return true;
}
使用QLExpress动态制定计算公式_佛祖保佑永不宕机的博客-CSDN博客_qlexpress表达式