前言

在做后台管理的时候经常会用到excel导入的问题,就是将excel中的内容批量导入到数据库中,正好在新项目中我也做了excel导入的功能,来分享给大家,也给自己做个记录。

核心思想

excel导入的核心思想很简单,就是读取单元格里的内容然后塞到JavaBean中,把每一个JavaBean再添加到list中再循环insert就可以了。

具体实现

前台怎么上传文件我就不在这里赘述了,我只讲后台的实现。这里我们使用poi来进行导入操作

文件导入

###导入判断

上传到后台肯定得需要一系列的判断,例如文件或者其内容是否为空,上传文件格式是否正确等等

    /**
     * 导入判断
     *
     * @param mfile
     * @return map
     */
    public Map<String, Object> lockExcelImport(MultipartFile mfile) {
        Map<String, Object> result = new HashMap<String, Object>();
        //判断文件是否为空
        if (mfile == null) {
            result.put("result", "error");
            result.put("msg", "文件不能为空!");
            return result;
        }

        //获取文件名
        String fileName = mfile.getOriginalFilename();

        //验证文件名是否合格
        if (!ExcelImportUtils.validateExcel(fileName)) {
            result.put("result", "error");
            result.put("msg", "文件必须是excel格式!");
            return result;
        }

        //进一步判断文件内容是否为空(即判断其大小是否为0或其名称是否为null)
        long size = mfile.getSize();
        if (StringUtils.isEmpty(fileName) || size == 0) {
            result.put("result", "error");
            result.put("msg", "文件不能为空!");
            return result;
        }

        try {
            File uploadDir = new File("E:\\fileupload");
            //创建一个目录 (它的路径名由当前 File 对象指定,包括任一必须的父路径。)
            if (!uploadDir.exists()) uploadDir.mkdirs();
            //新建一个文件
            File tempFile = new File("E:\\fileupload\\" + new Date().getTime() + ".xlsx");
            //初始化输入流
            InputStream is = null;

            //将上传的文件写入新建的文件中

            mfile.transferTo(tempFile);

            //根据新建的文件实例化输入流
            is = new FileInputStream(tempFile);

            //根据版本选择创建Workbook的方式
            Workbook wb = null;
            //根据文件名判断文件是2003版本还是2007版本
            if (ExcelImportUtils.isExcel2007(fileName)) {
                wb = new XSSFWorkbook(is);
            } else {
                wb = new HSSFWorkbook(is);
            }
            //根据excel里面的内容读取知识库信息
            result.put("result", "success");
            result.put("msg", readExcelValue(wb, tempFile));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }

读取excel内容

进行完文件判断之后我们来进行读取excel中的内容,并将数据塞到JavaBean中,里面的每行代码我都注释的很详细,大概就是先获取到当前sheet页,之后获取行数来循环行,因为一般第一行是标题所以我们从第二行开始循环,之后获取每行的单元格,因为这里每个单元格内容都是特定的,所以我们直接获取指定单元格的值塞到对象中,再将每一个对象添加到list中去,这就是我们用来导入的数据。这里我返回的是封装好的map集合,大家直接返回map就可以

/**
 * 解析Excel里面的数据
 *
 * @param wb
 * @param tempFile
 * @param userId
 * @return
 */
private Map<String, Object> readExcelValue(Workbook wb, File tempFile, Integer userId) {
   //返回结果
   int reslutNum = 0;
   //对象
   List<LockHistoryEntity> lockImportList = new ArrayList<>();
   //获取sheet页数
   int pages = wb.getNumberOfSheets();
   // 循环Excel的sheet页数,获取每个sheet表
   for (int i = 0; i < pages; i++) {
      // 取得工作表
      Sheet sheet = wb.getSheetAt(i);
      // 获取行数
      int rows = sheet.getPhysicalNumberOfRows();
      //循环Excel的行数,从第二行开始
      for (int r = 1; r < rows; r++) {
         LockHistoryEntity lockImport = new LockHistoryEntity();
         //获得每一行
         Row row = sheet.getRow(r);
          //判断每个单元格是否为空
         if (row.getCell(0) != null || row.getCell(1) != null || row.getCell(2) != null || row.getCell(3) != null) {
            // 客户卡号
            lockImport.setCustCode(row.getCell(0).getStringCellValue().trim());
            // 客户姓名
            lockImport.setCustName(row.getCell(1).getStringCellValue().trim());
         }
          //进行一下判断,防止将空对象添加到了list中,当然每个业务的判断条件肯定不同,因情景而仪
         if (!StringUtils.isEmpty(lockImport.getCustCode())) {
            // 加入数据队列
            lockImportList.add(lockImport);
         }
         // 没有明细数据时,直接结束程序
         if (lockImportList.size() == 0) {
            return ServiceUtil.generateResponseMap(null, Constants.STATE_FAILED);
         }
      }
      reslutNum = impLockHistory(lockImportList);
   }
   //删除上传的临时文件
   if (tempFile.exists()) {
      tempFile.delete();
   }
   return ServiceUtil.generateResponseMap(null, reslutNum > 0 ? Constants.STATE_SUCCESS : Constants.STATE_FAILED);
}

数据DB插入更新

已经到了最后一步数据插入,这里我用的是mybatis的foreach插入,直接将数据集合传过去就🆗了

    /**
     * 数据DB插入更新
     *
     * @param lockImportList
     * @return
     */
    private int impLockHistory(List<LockHistoryEntity> lockImportList) {
        //录入结果
        int insetLock = 0;
        //再进行判断集合中是否有数据
        if (lockImportList.size() == 0) {
            return Constants.STATE_FAILED;
        }
        insetLock = clientMstMapper.insertLock(lockImportList);
        return insetLock > 0 ? Constants.STATE_SUCCESS : Constants.STATE_FAILED;
    }

到这里poi导入excel就实现完了,如果读完有收获的话还请点个底部推荐🙇‍♂️