标签:

在平时开发和使用过程中,经常会出现要使用excel解析文件,用来处理一些批量业务,比如批量创建,批量修改,或者批量入库保存,这类业务的特点是,一般用txt或者excel保存待处理数据,每一行对应N个字段,N个字段有些可为空,有些不为空,N行循环解析完毕后,获取相应的列的值,一个一个处理,其实处理方有很多种,但是如果说,没有一个通用接口去处理这件事,每次都要写很多的解析代码,然后在一行一行一列一列的处理所需字段,这太麻烦了。最近写的项目,也用到了这一块,但是本来的代码有些问题,尝试自己重写了一遍,感觉清楚很多,记录一下, 也方便以后的使用。

正题:

首先,我想实现的效果是,给一个excel文件(xlsx或者xls),然后申明一个xml文件,和一个对象。xml文件负责放一些解析的配置,例如,一个excel文件从第几行开始解析,不解析尾部多少行以后的,以及excel文件中的列的顺序对应对象字段值,例如,第一列的值代表用户名,则xml就可以设置一个item 值为userName,并且对象中也有一个userName,这样解析的时候,就可以,以list的形式,返回行数个userName,对应excel 中的值。

在实际处理过程中,可以理解为,只要把相关参数填好,通用解析方法,能直接返回一个LIST对象,后续处理直接循环集合中的对象参数就可以获取相关参数,省却了大量的重复解析,重复获取row,和cell的过程。

实际结果如图所示

Java期待是空返回是有值的_Java期待是空返回是有值的

设计思路如下:

1.所需依赖及原因

poi包:由于要解析xls,xlsx文件,目前普遍的使用的工具类是poi

dom4j:由于配置文件选择放在xml中,所以引入xml对文件及其内部节点进行解析

fastJson:内部处理时,是先解析成List>的形式。可由,该形式返回,同时在提供一个接口,

把解析的List> 通过fastJson的方法转成了List的形式

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 获取单行的:字段名称+值,最终返回一个List>

5.到此,一个public 接口已经完成

6.用以上的接口,加一个想 要转成的对象为一个新的接口,将获取的List> 转成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链接

(直接执行poi包下的test,即可看到结果)