目录
最近做项目时遇到这样一个需求,将数据库表的含有公式的信息导出为Excel文件并且需要计算其结果,由于上网查询资料后未能完美解决,故将此踩坑过程记录下来以供参考。本文将以若依项目演示,并且将分为两部分,第一部分为使用若依的@Excel注解进行导出并计算公式,适合于不要求自定义模板导出,而第二部分将使用EasyExcel实现以自定义模板导出并自动计算公式方式来实现。
环境要求
若依Cloud 3.6.3
此处也可使用若依分离版,本文主要涉及内容为@Excel注解。
功能预览
方便起见,本文以若依用户管理的导出功能为示例,做一个简单的公式计算的验证,大家可根据自己需求修改相应代码。
首先本地启动若依微服务版本,登录后台,依次选择系统管理 —> 用户管理菜单,进入如下页面
点击该页面的导出按钮
获取如下导出文件
现在如果我们想要在第四行计算第二和第三行用户编号的和,可以直接在B4单元格输入"=A2+A3"这样的公式来实现,可以注意到此时B4单元格中的公式颜色已经发生变化,并且自动选中了A2和A3单元格,但实际上我们的需求为从数据库表中导出的单元格实现自动计算结果,接下来将通过若依前端页面来实现该功能验证。
需求分析
利用用户管理页面新增用户功能,可以添加如下用户信息来模拟公式计算结果导出(此处填写=A2+A3原因是A1为表头)。
添加完毕后再次点击导出结果如下图,但是B4并没有计算导出结果,而是变成了普通字符串,选中后也没有颜色变化,可以猜测需要从后端代码入手解决问题。
源码跟踪
通过F12下的网络可以找到当前导出接口位于/system/user/export下
后端Controller层如下,可以看出整个导出使用了三行代码,第一行为查询用户信息,第二行创建ExcelUtil实例,第三行调用该实例的exportExcel方法进行导出。
需要注意的是,第一行查询的SysUser对象中对导出列的属性添加了@Excel注解,用于标识导出的表头,并且可以对导出数据格式进行设置。
自定义数据处理器
结合官方文档 后台手册 | RuoYi 提到的自定义数据处理器,我们可以对导出单元格属性进行调整,通过文档可知@Excel注解具有一个Handler属性,该属性允许我们自定义一个数据处理器来处理数据,官方文档中所提示的为修改单元格颜色,同理我们可以通过该方法实现公式的设置。默认的Handler的为 ExcelHandlerAdapter 接口,我们需要实现该接口的format方法。在此之前请检查你的项目中该接口下的format方法是否如下图所示包含了4个参数
若不是请升级若依版本,或参考该文件的提交记录修改 ExcelHandlerAdapter 和 ExcelUtil 下的相关代码。 登录 - Gitee.com
新建ExcelFormulaHandler类并实现ExcelHandlerAdapter接口的format方法
public class ExcelFormulaHandler implements ExcelHandlerAdapter{
@Override
public Object format(Object value, String[] args, Cell cell, Workbook wb) {
// 判断是否是公式,例如以 "=" 开头
if (value != null && value.toString().startsWith("=")) {
cell.setCellFormula(value.toString());
}
return value;
}
}
在SysUser对象的userName属性上的@Excel中添加自定义的Handler类
再次点击导出即可发现公式已经可以自动计算。
通过跟踪源码可以发现,我们自定义的公式处理类从util实例对象调用 exportExcel 方法后将进入ExcelUtil工具类中,通过对传入的查询对象筛选,最终获取到每个类对象属性上的@Excel参数,并判断是否具有handler属性,最终进入ExcelUtil的dataFormatHandlerAdapter方法中,在这里通过反射获取到我们重写后的类对象进而调用其format方法,从而实现数据格式化。
总结
若导出时不需要使用模板填充,则可直接使用@Excel注解进行导出,对于公式计算可通过实现ExcelHandlerAdapter接口的format方法,设置单元格属性为formula,并将对应的字段上@Excel注解的Handler属性设置为自定义的类即可,下一篇文章将介绍如使用EasyExcel实现自定义模板并自动进行公式计算。