poi根据导入的excel数据自动封装成bean对象集合

来源:互联网 发布:浙江国税网络发票系统 编辑:程序博客网 时间:2024/06/04 18:25

又是很久没写博客了,最近在弄一个批量导入的功能,按照古老的做法,当然是一行一行的解析然后根据字段所在的下标或者一列一列的解析依次赋值给bean对象。但是这种古老的方法弊端确实太多,于是想弄一个,根据表头中文名来自动匹配字段,然后根据行数自动创建bean对象的方式,实现标准数据的通用解析。

在具体实现之前,首先得确定一个问题:你了解java的泛型吗?

为什么我会提出这个问题,因为既然是做通用的,那么你的bean对象就一定不是固定的,这就必须用到泛型。

实现(理论):

1、获取前端上传的文件(spring mvc方式)

@RequestParam(value = "file", required = true) MultipartFile file
2、获取输入流
InputStream input = file.getInputStream();
3、定义一个Map,以excel表头作为key,以bean字段名作为value
Map<String, Object> mapper = new HashMap<>();mapper.put("联系人", "linkman");mapper.put("电话", "phone");mapper.put("详细地址", "address");
到这里,大家可能已经看出一点端倪了,没错,原理很简单,读取excel,然后用表头去与map的key进行匹配,能匹配上哪里该单元格的数据就是bean对象对应的字段。至于如何通过字符串获取bean对象与bean字段,这里就需要使用java的反射与泛型机制。
public <T_T> List<T_T> readBean(InputStream inputStream, Map<String, Object> headerMapper, Class<T_T> tClass) throws Exception;
上面一行代码就是转换接口,一个输入流,一个map,一个Class泛型。

到了这里,其实实现方式就多种多样了,大家可以根据自身项目进行解析。我把我的解析方式继续说明一下:

4、创建一个空的list用来装载即将封装的bean

List<T_T> list = new ArrayList<>();
5、将excel数据解析为集合(由于excel表头不一定只是占用第一行,所以可以定义一个表头所在行数,该行最好就是第一条数据行-1):
ArrayList<ArrayList<String>> rows = ExcelIO.readExcel(inputStream, 0);
6、将数据封装为bean
//循环行,然后赋值给bean        for(int k=1;k<rows.size();k++){            T_T t = tClass.newInstance();            for(int num = 0;num<rows.get(0).size();num++){                //循环bean字段(等同循环表头)                for(String header : headerMapper.keySet()){                    if(rows.get(0).get(num).equals(header)){                        PropertyDescriptor propertyDescriptor = BeanUtilsBean.getInstance()                                .getPropertyUtils().getPropertyDescriptor(t, headerMapper.get(header).toString());                        if(propertyDescriptor!=null){                            BeanUtils.setProperty(t, headerMapper.get(header).toString(), ExcelIO.changeType(rows.get(k).get(num), propertyDescriptor.getPropertyType()));                            break;                        }                    }                }            }            list.add(t);        }
这样,不管excel是否字段顺序是乱的,或者中间有其他不需要的数据列与空列之类的,都能够直接排除,最终list中返回的就是我们需要的bean对象,并且是已经赋值完成可以直接写入数据库的数据。

由于解析excel之前已经有了,所以我就偷懒直接用了。其实,更简单的方式就是,直接在解析的时候,读取一行就完成一次bean封装,这样就不用解析完成后再来遍历封装。

这只是个人见解,如有错误,请大家留言指点。

2 0