几种JAVA表达式语言计算工具
测试表达式工具分类
这里测试了几种方式,MS excel,Spring SEPL,MVEL,Google aviator
import com.googlecode.aviator.AviatorEvaluator;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.junit.jupiter.api.Test;
import org.mvel2.MVEL;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import java.io.*;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
public class ExcelTest {
@Test
public void testExcelFormula() throws IOException {
// 加载 Excel 文件
InputStream fis = this.getClass().getResourceAsStream("/formula.xlsx");
Workbook workbook = new XSSFWorkbook(fis);
Sheet sheet = workbook.getSheetAt(0);
// 读取公式计算后的值
Cell formulaCell1 = sheet.getRow(1).getCell(1); // 假设公式在第2行第2列
System.out.println("公式计算前的值: " + formulaCell1.getNumericCellValue());
// 修改单元格值
Row row = sheet.getRow(1); // 假设修改第2行
Cell cell = row.getCell(0); // 假设修改第1列
cell.setCellValue(15); // 设置新值
// 重新计算公式
FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
for (Row r : sheet) {
for (Cell c : r) {
if (c.getCellType() == CellType.FORMULA) {
evaluator.evaluateFormulaCell(c); // 重新计算公式
}
}
}
// 读取公式计算后的值
Cell formulaCell = sheet.getRow(1).getCell(1); // 假设公式在第2行第2列
System.out.println("公式计算后的值: " + formulaCell.getNumericCellValue());
// 保存修改后的文件(可选)
FileOutputStream fos = new FileOutputStream("example_updated.xlsx");
workbook.write(fos);
fos.close();
// 关闭资源
fis.close();
workbook.close();
}
@Test
public void testSELFormula() throws IOException {
ExpressionParser parser = new SpelExpressionParser();
// 使用Spring EL计算订单项的总价(虽然这里可以直接调用方法,但为了展示EL,我们依然使用它)
StandardEvaluationContext context = new StandardEvaluationContext();
Map<String, Object> cartItem = new HashMap<>();
cartItem.put("price", new BigDecimal("20.56"));
cartItem.put("quantity", 2);
context.setVariable("cartItem", cartItem);
// BigDecimal totalPrice = parser.parseExpression("#cartItem['price'] = 0; #cartItem['quantity'] = 0; #cartItem['price'] * #cartItem['quantity']")
// .getValue(context, BigDecimal.class);
BigDecimal totalPrice = parser.parseExpression("#cartItem['price'] * #cartItem['quantity']")
.getValue(context, BigDecimal.class);
// 这里只是为了演示EL,实际上可以直接使用orderItem.getTotalPrice()
System.out.println("Order item total price calculated by Spring EL: " + totalPrice);
}
/*
<groupId>org.apache.commons</groupId>
<artifactId>commons-jexl3</artifactId>
<version>3.2</version>
*/
@Test
public void testMvELFormula() throws IOException {
Map<String, Object> context = new HashMap<>();
Map<String, Object> cartItem = new HashMap<>();
// cartItem.put("price", new BigDecimal("20.56"));
// cartItem.put("quantity", 2);
context.put("cartItem", cartItem);
// String expression = "cartItem.price=cartItem.price==null?15:cartItem.price; cartItem.quantity=cartItem.quantity==null?1:cartItem.quantity; cartItem.price*cartItem.quantity";
// Corrected expression using bracket notation
String expressions = "cartItem['price'] = cartItem['price'] == null ? new java.math.BigDecimal('15') : cartItem['price']; " +
"cartItem['quantity'] = cartItem['quantity'] == null ? 2 : cartItem['quantity']; " +
"cartItem['price'] * cartItem['quantity']";
Object res = MVEL.eval(expressions, context);
System.out.println(res.getClass());
System.out.println("res: " + res); // 输出: John
}
/*
<groupId>com.googlecode.aviator</groupId>
<artifactId>aviator</artifactId>
<version>5.3.1</version>
*/
@Test
public void testAviator() {
// Create a context with variables
// Map<String, Object> context = new HashMap<>();
// context.put("price", 20.5);
// context.put("quantity", 3);
// Define multiple expressions
// String expressions = "total = price * quantity; discount = total > 50 ? 5 : 0; finalPrice = total - discount; finalPrice";
Map<String, Object> context = new HashMap<>();
Map<String, Object> cartItem = new HashMap<>();
// cartItem.put("price", new BigDecimal("20.56"));
// cartItem.put("quantity", 2);
context.put("cartItem", cartItem);
String expression = "cartItem.price = cartItem.price == nil ? 15 : cartItem.price;" +
"cartItem.quantity = cartItem.quantity == nil ? 2 : cartItem.quantity;" +
"cartItem.price * cartItem.quantity";
Object result = AviatorEvaluator.execute(expression, context);
System.out.println(result.getClass());
// Print the result
System.out.println("Final price: " + result); // Output: Final price: 56.5
}
}
测试结果

使用推荐
推荐使用MVEL,易于java开发理解,功能强大,性能优秀
几种JAVA表达式语言计算工具的更多相关文章
- 四种java代码静态检查工具
[转载]常用 Java 静态代码分析工具的分析与比较 转载自 开源中国社区 http://www.oschina.net/question/129540_23043 1月16日厦门 OSC ...
- Java 高精度浮点数计算工具
说起编程中的高精度数值,我第一反应就是double类型了.的确,double阶码11位,尾数52位,几乎能应对任何苛刻的要求......然而,当我天真地尝试用double来算泰勒展开式的函数值,离散代 ...
- JAVA简单精确计算工具类
1 public class ArithUtil { 2 3 // 默认除法运算精度 4 private static final int DEF_DIV_SCALE = 10; 5 6 privat ...
- java表达式语言mvel2/ognl/spring-expression
<!-- https://mvnrepository.com/artifact/org.mvel/mvel2 --><dependency> <groupId>or ...
- Spring学习总结(四)——表达式语言 Spring Expression Language
SpEL简介与功能特性 Spring表达式语言(简称SpEL)是一个支持查询并在运行时操纵一个对象图的功能强大的表达式语言.SpEL语言的语法类似于统一EL,但提供了更多的功能,最主要的是显式方法调用 ...
- Spring ——表达式语言 Spring Expression Language (转载)
目录 SpEL简介与功能特性 一.为什么需要Spring表达式语言 二.SpEL表达式Hello World! 三.SpEL表达式 3.1.文字表达式 3.2.SPEL语言特性 3.2.1.属性 3. ...
- Java EE之表达式语言EL(上)
1.了解表达式语言 表达式语言(EL)用于在不使用脚本.声明或者表达式的情况下,在JSP页面中渲染数据. EL曾是JSTL 1.0规范(与JSP 1.2)中的一部分,并且只可以用作JSTL标签的特性. ...
- Java Web----EL(表达式语言)详解
Java Web中的EL(表达式语言)详解 表达式语言(Expression Language)简称EL,它是JSP2.0中引入的一个新内容.通过EL可以简化在JSP开发中对对象的引用,从而规范页面 ...
- Java堆栈的应用2----------中缀表达式转为后缀表达式的计算Java实现
1.堆栈-Stack 堆栈(也简称作栈)是一种特殊的线性表,堆栈的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置进行插入和删除操作,而堆栈只允许在固定一端进行插入和删除 ...
- 应用AXIS开始Web服务之旅(soap web services)——使用三种不同的语言访问创建的Web服务,分别是JAVA、VB、VC
一. 介绍 本文并不是想介绍Web服务的原理.系统架构等,我们假设您已经了解了关于Web服务的一些基本的概念.原理等知识.本文主要是针对那些已经了解Web服务概念,但是还没有亲身体会Web服务所带来令 ...
随机推荐
- Kotlin:【数字类型】安全转换函数
- Nodify学习 四:预先连接
前置 预先连接 可以从连接器创建预先连接,并可以放置在ItemContainer或Connector上(如果AllowOnlyConnectors为false). 预先连接的Content可以使用Co ...
- 天翼云重磅升级边缘WAF能力,助力企业高效应对Web安全威胁!
"2022年,网络高危漏洞数量同比增长了13%:Q2遭受攻击的API数量月均超过了25万:物联网的普及大大降低了DDoS的攻击成本,大流量攻击指数显著提升:恶意Bot流量仍在持续增长,202 ...
- Q: 如何实现右键选择打开文件的应用程序
1.win+R打开cmd窗口,输入regedit,打开注册表 2.依次找到HKEY_CLASSESS_ROOT->*->Shell,下面新建项 "用notepad打开" ...
- Java 中堆内存和栈内存上的数据分布和特点
博客:https://www.emanjusaka.com 博客园:https://www.cnblogs.com/emanjusaka 公众号:emanjusaka的编程栈 by emanjusak ...
- 在 GitLab CI/CD 中使用内置的容器镜像库
配置 Docker-in-Docker Docker-in-Docker (dind) means: 你应该注册一个 Docker executor 或 Kubernetes executor 执行器 ...
- 【忍者算法】从入环点到相遇点:深入理解环形链表 II|LeetCode第142题 环形链表 II
[忍者算法]从入环点到相遇点:深入理解环形链表 II|LeetCode第142题 问题升级:不止要找环,还要找入环点 在上一题中,我们讨论了如何判断链表是否有环.现在让我们更进一步:如果确定链表中有环 ...
- 并发编程 - 线程同步(九)之信号量Semaphore
前面对自旋锁SpinLock进行了详细学习,今天我们将学习另一个种同步机制--信号量Semaphore. 01.信号量是什么? 在 C# 中,信号量(Semaphore)是一种用于线程同步的机制,能够 ...
- DeepSeek崛起:程序员“饭碗”被抢,还是职业进化新起点?
2025年伊始,Meta创始人扎克伯格的一则声明引发全球程序员热议:"AI将在今年达到中级工程师水平,逐步接管编程工作."与此同时,国产AI大模型DeepSeek的爆火,让一名8岁 ...
- Linux 宝塔常用命令教程
一.引言 在 Linux 服务器管理中,宝塔面板是一款非常实用的工具.然而,了解一些相关的命令可以让我们在特定情况下更高效地进行操作和管理.本文将为您介绍一些常用的 Linux 宝塔相关命令. 二.安 ...