dbeaver导入excel文件_使用POI封装工具类处理Excel表格文件导入篇

使用POI封装工具类处理Excel表格文件--导入篇

有关于系统中导入Excel表格文件,其实大家普遍见过或者使用过。但是相较于网上提供的EasyPOI或者Hutool工具类里面封装好的Excel处理方法(马总推荐使用的工具类),其实在很多情况下不太符合我们的导出或者导入场景,总是需要手动处理下,很是繁琐,毕竟不是所有的表格数据我们都需要,或不是所有的数据都需要我们导出。所以这里手动处理下POI类(其实人家封装的已经很完整了,~~然而还是不太好用~~),让这个处理的方法更贴合实际使用。

> 云中谁寄锦书来?雁字回时,月满西楼。

构思

我们使用Excel导入的目的是什么?

* 通常我们使用Excel导入的目的说白了就是为了获取表格里面的数据,然后整理后提炼出来被我们使用或者存入到数据库中。但是很多情况下,不是所有的列数据都是我们需要的,所以我们首先要明确我们需要什么。我这里处理使用常量来定义了导入的模板。(当然大家还可以使用枚举,或者选择和前端交互,肆意而为,毕竟办法总比困难多-狗头保命:59d8f5160dd48b9767df090c6d857e95.png: )

> 模板定义: 0|备注(属性名)|属性名

 public static class TempLate{        @ConstantAnnotation("001")        public static final String MODE_CONTENT="0|凭证号|voucherNo,1|会计年度|accountYear,2|会计月度|accountMonth,3|数据来源|dataSource,4|存储类型(0. 电子 1. 电子和纸质)|saveType,5|存储类型名称|voucherName,6|摘要|accountAbstract,7|关键字|keyWord,8|凭证类型|voucherTypeId,9|凭证类型名称|voucherTypeName,10|凭证状态0 待装册 1 已装册|voucherState,11|创建时间|creatTime,12|单位编码|orgCode,13|单位名称|orgName";    }

知道了我们要获取的数据有哪些后,我们怎么做匹配?

* 当我们知道了我们需要表格数据的哪一列,我们心中其实也就明白了这列数据对应我们数据模型的哪一个字段,这样在后面处理的时候只要匹配成功即可。

  所以我们需要用到反射的一点点知识,使用好Field,然后简单的做几个判断,就可以完美匹配了。

 T object = instance.newInstance(); Field[] fields= object.getClass().getDeclaredFields();

> 注:instance是一个Class 类型的入参,用来放我们需要储存数据的数据模型类.class   还有就是fields,是我们.class里面的所有属性。(获取私有属性要把accessible赋值true)

* 接下来我们拿到属性数组后,可以循环比较类型或者属性名来操作并赋值。

if (mapHeader.get(s).equals(f.getName())) {     //获取私有变量    f.setAccessible(true);     f.set(object, cell.getStringCellValue());

如何调用?我们该传什么进行处理?

* 首先传一个要处理的Excel文件,然后我们传个模板,再传一个我们想要返回结果集合的类型.class即可。例:

List list=POIUtils.excelToEmployee(file,EaVoucher.class,modeText);

> 模板处理

public static Map stringToMap(String text) throws Exception {        Map mapHeader = new HashMap<>();        String[] decollator = text.split(",");        if (decollator.length > 0) {            for (String s : decollator) {                String[] desc = s.split("\\|");                if (desc.length < 3 || "".equals(desc[0]) || "".equals(desc[2])) {                    throw new Exception("模板格式有误,请检查!");                }                mapHeader.put(desc[0], desc[2]);            }        }        return mapHeader;    }

然后我们就可以使用这个工具类了。源码方法如下:

 /**     * @Description:  excel文件解析成相应类型的List    * @Param: [file, instance, modeText]     * @return: java.util.List    * @Author: ShiDunKai     * @Date: 2020/5/29     */     public static  List excelToEmployee(MultipartFile file, Class instance, String modeText) throws Exception {        //获取导入模板        Map mapHeader = stringToMap(modeText);        //接收list        List tList = new ArrayList<>();        //创建一个workbook对象        HSSFWorkbook workbook = new HSSFWorkbook(file.getInputStream());        //获取workbook中标签页的数量        int numberOfSheets = workbook.getNumberOfSheets();        for (int sheetNumber = 0; sheetNumber < numberOfSheets; sheetNumber++) {            HSSFSheet sheetAt = workbook.getSheetAt(sheetNumber);            //获取行            int physicalNumberOfRows = sheetAt.getPhysicalNumberOfRows();            for (int rowNumber = 0; rowNumber < physicalNumberOfRows; rowNumber++) {                if (0 == rowNumber) {//跳过标题行 因为我们这里不做任何处理,所以有没有continue,效果都是一样的,精简才是王道。                } else {                    //解析第一行,与模板进行匹配                    HSSFRow row = sheetAt.getRow(rowNumber);                    //空行判断                    if (null == row) {                        continue;                    }                    //一行一个对象                    T object = instance.newInstance();                    Field[] fields = object.getClass().getDeclaredFields();                    //获取列                    int physicalNumberOfCells = row.getPhysicalNumberOfCells();                    if (physicalNumberOfCells >= mapHeader.size()) {                        for (String s : mapHeader.keySet()) {                            HSSFCell cell = row.getCell(Integer.parseInt(s));                            for (Field f:fields) {                                if (mapHeader.get(s).equals(f.getName())) {                                    //获取私有变量                                    f.setAccessible(true);                                    f.set(object, cell.getStringCellValue());                                } else {                                    throw new Exception("模板属性名与对象属性不符,请检查模板是否正确配置。");                                }                            }                        }                    } else {                        throw new Exception("表格列数量与实际要导出的列数不符,无法获取某些列数据,请检查模板或者表格文件是否正确。");                    }                    tList.add(object);                }            }        }        return tList;    }

后:

> 是不是很简单,模板我们可以随时调整,如果后期需要做集成,我们完全可以想办法和前端进行交互,使工具类的扩展性再提一个层次。前期业务量小的话完全可以自定义模板,不影响使用效果的。?

> 至于导出我们如何做处理,其实大致思路和上面是一样的,只不过现在已经半夜0:08,早睡保命要紧,明天还要早起吃早点,还要工作。。。那就拖到周六日给大家分享吧(或许拖更久,别急:trollface: )

> 其实这个博客在电脑上看效果是最好的,但是大家平时还是看手机比较多,所以微信公众号随后也会完成更新推送,欢迎关注留言讨论(*~~留言了我也不一定回复~~*)。睡,晚安各位。c874381e08ce993081db8b034e3366f1.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值