欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2024-03-21 16:23:52
...

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

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

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

构思

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

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

> 模板定义: 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: )

> 其实这个博客在电脑上看效果是最好的,但是大家平时还是看手机比较多,所以微信公众号随后也会完成更新推送,欢迎关注留言讨论(*~~留言了我也不一定回复~~*)。睡,晚安各位。dbeaver导入excel文件_使用POI封装工具类处理Excel表格文件导入篇