在平时开发和使用过程中,经常会出现要使用excel解析文件,用来处理一些批量业务,比如批量创建,批量修改,或者批量入库保存,这类业务的特点是,一般用txt或者excel保存待处理数据,每一行对应N个字段,N个字段有些可为空,有些不为空,N行循环解析完毕后,获取相应的列的值,一个一个处理,其实处理方有很多种,但是如果说,没有一个通用接口去处理这件事,每次都要写很多的解析代码,然后在一行一行一列一列的处理所需字段,这太麻烦了。最近写的项目,也用到了这一块,但是本来的代码有些问题,尝试自己重写了一遍,感觉清楚很多,记录一下, 也方便以后的使用。
正题:
首先,我想实现的效果是,给一个excel文件(xlsx或者xls),然后申明一个xml文件,和一个对象。xml文件负责放一些解析的配置,例如,一个excel文件从第几行开始解析,不解析尾部多少行以后的,以及excel文件中的列的顺序对应对象字段值,例如,第一列的值代表用户名,则xml就可以设置一个item 值为userName,并且对象中也有一个userName,这样解析的时候,就可以,以list的形式,返回行数个userName,对应excel 中的值。
在实际处理过程中,可以理解为,只要把相关参数填好,通用解析方法,能直接返回一个LIST<T>对象,后续处理直接循环集合中的对象参数就可以获取相关参数,省却了大量的重复解析,重复获取row,和cell的过程。
实际结果如图所示
设计思路如下:
1.所需依赖及原因
poi包:由于要解析xls,xlsx文件,目前普遍的使用的工具类是poi
dom4j:由于配置文件选择放在xml中,所以引入xml对文件及其内部节点进行解析
fastJson:内部处理时,是先解析成List<Map<String,Object>>的形式。可由,该形式返回,同时在提供一个接口,
把解析的List<Map<String,Object>> 通过fastJson的方法转成了List<T>的形式
2. 逻辑
《1》首先,先创建一个和解析列有对应关系的xml文件,这个文件中存放解析规则:
1.解析字段放在map,或对应对象中的字段名字
2.起始解析行(一般为1,因为第零行一般是excel文件的中文标示,例如,名字,账号等,一行开始才是数据)
3.结束截止行数(一般为零,如果某些文件有汇总行,比如有两行汇总行,就可以写2,这样最后两行就不解析)
4.解析字段顺序(index,可以不写,不写就默认为按xml的字段顺序进行解析了)
5.有其他想要处理的或者忽略的字段也可以,自己自定义,但是那就要自己再改下了-0-
《2》获取文件路径,获取文件路径,判断是否存在,是否是特定文件尾。通过验证顺便把xls还是xlsx判断了,获取Workbook,并根据接口传值,把所需sheet获取
1.得到sheet后,获取xml解析模板文件, 创建一个内部类,包括一个字段名,和字段对应的列下标。循环xml解析模板中的字段,把解析字段,和index下标(没有则为-1,按默认顺序),组装对象,放在List<内部类> 中,该List为后面的列对应值(cell对应)
2.获取起始解析行,和截止行数,以及获取sheet的有数据总行
3.for循环遍历row,起始i为起始解析行,(总行数-截止行数)为for 终点
4.遍历row的循环内部,遍历List<内部类> 用一个Map<String,Object> 获取单行的:字段名称+值,最终返回一个List<Map<String,Object>>
5.到此,一个public 接口已经完成
6.用以上的接口,加一个想 要转成的对象为一个新的接口,将获取的List<Map<String,Object>> 转成List<所需对象>,其中,所需对象中的字段,等于map的String,等于xml文件配置的字段名
7.结束
《3》 注
因为我这边用的文件,已经事先说明了,并判断了,文件行数不能大于10000行,所以,就没有进行分页处理,直接一个文件可以转成一个List返回解析。
但是,其实也许也有很多需求中,是有上十万,或者百万的数据在一个文件中,在这种情况下,是需要分页解析,分页处理的。这里只说下思路吧
在《2》 .3 中的起始行和结束行这里需要改动一下,新增两个参数,一个参数是起始行,一个参数是遍历数,例如,5000,5000,则表明,从第5000行开始解析,并且再解析5000行,for 那里就成了(i=5000;i<=5000+5000;i++),直到最后一次解析数小于5000时,变为 (i=5000;i<=5000+5000-结束截止行数;i++)即可。
本次写有关代码也是因为,本来的common方法是有bug的,坑了很久,最后改掉以后,想自己重写一遍,学习一下,最后感觉比原来的写法还是清晰多了
3.源码Maven demo链接
https://download.csdn.net/download/zxysshgood/10697773
(直接执行poi包下的test,即可看到结果)