由于之前本人接手了一个企业项目,涉及大量的excel操作,但网上一直没有好的excel orm框架,于是纯手写了一个框架ehui,经过项目的更替,版本已经从1.0更新到了2.2。这里分享一下。下载链接:https://download.csdn.net/download/a729913162/10473073
再附上使用说明:
一, 说明
1,本框架ehui_framework作者本人,联系qq:729913162。
2,首先,您需要了解Ehui的功能有哪些,我们主要开发这个框架,是为了简化您java对excel访问与读写的步骤,提高您开发的效率而做出的贡献,也感谢您的使用,如您发现了有什么不足或使用中发现bug欢迎指正。
二, 使用前的准备
首先您需要导入ehui-2.2.jar包,还需要导入poi相关jar包,支持目前各种poi版本,否则当访问excel时,如果虚拟机找不到class文件,则会引发异常。
三,如何查询Excel表数据
1, 本框架编写,主要采用orm思想,所谓orm思想即,对象关系映射。我们把excel的表抽象成一个java类。列名抽象成该类的属性,这就是我们的核心思想。目前支持的Excel类型文件有:xls,xlsx,csv。
2, 创建好一个普通的JavaBean,给上get/set方法后,那么我们如何让我们的框架能够智能感应excel对应的列呢?我们可以加上注解试一下:
自2.0版本开始,实体类推荐继承Excel类,并且getAll方法已经过期,我们从2.0版本开始使用getAll2方法。
ExcelMapping:即excel文件映射,映射excel表,该注解在类注解上有效。
FieldMapping:即字段映射,与excel列映射,该注解在属性上注解有效。
3, 获得数据:
Java类及映射已配置好,此时,我们只需要调用以下一行代码,即可拿到该表所有数据:
ReflectAgent.getAll2(Class clazz,String path);
第一个参数,即你要实体类的class,第二个参数即你excel文件所在路径。
每一行数据会自动封装成一个实体对象,然后把所有对象以集合的形式返回。如图:
从1.10版本起,如果你使用的是getAll2方法,当发现excel表中有公式,会自动处理计算后的结果。目前只支持简单公式。
我们还提供了第二种方法与excel产生映射关系:
也就是通过excel列名来进行映射。当FieldMapping列索引和列名同时被指定的时候,列名的优先级更高,同一个类中两种方法可以混用。
需要注意的是,我们认为默认excel第0行为字段所在行,如果excel不在第0行,需要指定excel字段所在行,
4,结果处理:
有时,我们可能需要对我们拿到的某一行数据进行处理,假如,我们有一个需求,需要将我们拿到的结果进行修改,
我们可以让实体类实现一个接口:ProcessHandler
并实现他里面的三个方法:
Boolean init():
该方法为初始化方法,只调用一次
返回值为true 或 false ,当返回值为true时才会执行process方法,否则直接调用destory方法。
Boolean process():
每封装成一个实体类对象时,并且init()方法返回值为true时回调一次此方法。
返回值true或false,标志对象是否保存到结果集中.
Void destroy():
死亡方法,只调用一次。
比如,我们把拿到的某个字段值进行修改,怎么办呢?如,我会要在某第一个属性后面加上一个字符串”哈哈”。
第一步:让实体类实现ProcessHandler接口
第二步:将init()方法返回值设置成true
第三步:在process方法中加入如下代码
这样运行后,我们就可以拿到后List集合中的每一个元素就是被修改后的对象。
值得注意的是process方法有一个布尔类型的返回值,false即代表当前对象不保存,直接舍弃。因此我们如何要拿到这个集合,就请把他设置成true。
运行成功,和我们预期结果相同。
小提示:我们如果只需要把当前对象保存到数据库,最高效的做法就是在process方法中保存当前对象,再返回false即可。
Excel表入库代码如下,假如我们要在入库前删除所有表数据,再将所有数据入库,我们如何去实现呢?
是不是很简单,这里又涉及到了一处与Spring整合的问题,当然,你也可以自己拿到这个Dao,至于如何与Spring整合,我们会在后面说到。
5,自动扫描实体类:
假设我们有这样一个需求:我们有很多个实体类,要把他们所有的实体类数据保存到数据库,我们一个类一个类的调用似乎这样写,代码有点冗余,我们也会很累,于是乎,我们也精心考虑到了这样一个情况,故自动扫描实体类功能诞生。
注意:自动扫描的实体类必须实现ProcessHandler接口。
首先,您需要在您想自动扫描的实体类的类注解上添加一个注解,AutoProcess,如图:
这样,运行以下代码
Register这个方法,就是将指定包名注册,在Processor.processAll方法被调用以后,就会在已注册的包名里查找被AutoProcess注解的所有类,查找到的类就会被自动调用对应类的
ReflectAgent.getAll2方法。
这样运行就可以达到效果。
需要注意的是:Processor.processAll有三个参数,最后一个参数为指定的Group名,与类注解AutoProcess上的值匹配,如果值相同才会对扫描,如果不指定第三个参数,则扫描指定包里的所有类。
自2.2版本起,Processor新提供一个processAllForThreadPool方法,可以以线程池的形式多线程处理自动扫描到的类进行加高处理,并且会阻塞io流,直到所有被扫描到的类的回调方法全部回调执行完之后,才会释放阻塞。
6, 与Spring整合
在class目录下的applicationConext.xml中加入以下代码:
只需实例化这一个bean即可,这是我们提供的一个bean工厂类,当然也可以是你自己写的,如果你要重写他,他必须是
BaseEntityFactory的子类。
再在实体类中加入Spring相关注解,让spring扫描:
需要注意的是:实体类是多例的,而Spring默认单例,所以Scope属性不要忘记设置,他可以让Spring对这个类的操作是多例的。
7, 拦截器
如果我们有这样一个需求,每次对Excel操作都有 一定的重复性,如我们导入excel数据到数据库中,如果有几百张表,我们必定想要写一个自动建表的功能,此时拦截器就可以派上用场了。
我们可以写一个类,让他实现EhuiInterceptor接口
这个接口有上图所示的两种方法。Interceptor为每次打开Excel表之前调用,finish为打开后调用。
所以我们自动建库的代码可以写在interceptor中,如果我们需要每次打开excel后清除一些缓存,甚至是删除文件,就可以写在finish代码中。
最后不要忘记,把这个拦截器要实例化一下,装配给实体工厂的ehuiInterceptor属性,这里用到的是一个适配器模式,如下:
8, 转换器
如果我们实体类中我们需要装配一些自定义的类型,亦或是对现有的类型装配加强,我们可以使用转换器。
比如在实体类中我们要装配Date类型,默认情况下是不支持的。那么我们就写个转换器吧。
从此,我们的实体类就支持Date类型的自动装配了。
注意,本框架本身自带对基本数据类型的转换,如果你重写了基本数据类型转换器,会覆盖我们自己提供的方法。
四, 如何操作Excel表数据
我们提供了一个ExcelSession类,可以实现对Excel表的操作。
如,我们需要保存一个Student类对象的数据,类定义如下:
public class Student extends Excel{
private int id;
private int age;
private String name;
//省略get/set
}
再加入同之前一样的注解。
我们现在创建一个Student对象:
Student student = new Student();
student.setId(1);
student.setAge(21);
student.setName("小明");
student.setAddress("安徽省合肥市");
student.setRownum(3);
我们如果需要保存这个student对象,只需要插入以下几行代码即可:
ExcelSession session = new ExcelSession("d://");//excel文件所在绝对路径
session.saveOrUpdate(student);//将对象保存到excel
session.saveTo(“d:/1.xlsx”);//保存文件
我们打开excel文件看一下:
注意,setRownum是父类Excel中的方法,用于设置要保存的excel行号。是不是很简单呢?
其实还有很多小技能,还请读者自行研究。
附上源码地址:https://gitee.com/luhui123/luhui_library/tree/master/ehui