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

Java实现批量导入Excel表格数据到数据库中

程序员文章站 2022-08-13 23:08:22
本文是基于Apache poi类实现的批量导入读取Excel文件,所以要先引入Apache poi的依赖 org.apache.poi poi 4.1.1

本文是基于Apache poi类实现的批量导入读取Excel文件,所以要先引入Apache poi的依赖

<dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>4.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.1.1</version>
        </dependency>

在引入依赖之后,我们就可以开始进行操作了,首先,导入Excel数据,我们要先能够读取Excel每一行每一列的内容,只有读取到内容了,才可以将内容存入数组,最后实现插入数据库。所以我们要先读取Excel表格的数据,我的项目是springboot,我在service定义了一个读取方法,然后在impl里面进行实现,具体代码为

public class ImportOrderDTO {
    private String filePath;

    public String getFilePath() {
        return filePath;
    }

    public void setFilePath(String filePath) {
        this.filePath = filePath;
    }
}    
/**
     * 读取导入数据 excel 内容
     *
     * @param importOrderDTO 导入参数
     * @param rootPath       根路径
     * @return result
     */
    public static final String SEPA = File.separator;//这是下面用到的常量,自己放好位置
    private List<User> readExcel(ImportOrderDTO importOrderDTO, String rootPath) {
        List<User> excelContent = new ArrayList<>();
        try {
            InputStream inputStream = new FileInputStream(rootPath + SEPA + importOrderDTO.getFilePath());
            XSSFWorkbook wb = new XSSFWorkbook(inputStream);
            //遍历所有表,只支持xlsx,xls的是H的类
            XSSFSheet xssfSheet = wb.getSheetAt(0);
            int lastRowNum = xssfSheet.getLastRowNum();
            for (int i = 0; i <= lastRowNum; i++) {
//            通过下标获取行
                XSSFRow row = xssfSheet.getRow(i);
//            从行中获取数据
                if (row.getRowNum() == 0) {
                    continue;
                }

                //第一列为空就跳出
                if (row.getCell(0) == null) {
                    continue;
                }
                /**
                 * getNumericCellValue() 获取数字
                 * getStringCellValue 获取String,设置表格类型为String,可以避免很多问题
                 */
                row.getCell(0).setCellType(CellType.STRING);
                row.getCell(1).setCellType(CellType.STRING);
                row.getCell(3).setCellType(CellType.STRING);
                row.getCell(5).setCellType(CellType.STRING);
               //UserInformPO是我自己定义的数据类,你们导入需要哪些数据就封装哪些,这就不用多讲了吧
                UserInformPO userInformPO = new UserInformPO();
                userInformPO.setAccount(row.getCell(0).getStringCellValue());
                userInformPO.setIdCard(row.getCell(1).getStringCellValue());
                userInformPO.setAvatar(row.getCell(2).getStringCellValue());
                userInformPO.setNickname(row.getCell(3).getStringCellValue());
                userInformPO.setSex(row.getCell(4).getStringCellValue());
                String salt = EncryptUtils.createSalt();
                userInformPO.setSalt(salt);
                //职业类别
                userInformPO.setIntegral(0);
                userInformPO.setVipLevel(0);
                userInformPO.setIsEnabled(0);
                userInformPO.setDelFlag(0);
                //然后将po转到我的实体类entity里面并将实体类加入到数组,方便正式执行批量导入的时候可以用,一些没有的类是我自己定义的加密的(规范)
                User user = new User();
                if (userInformPO.getSex().equals(SexEnum.MAN.getText())) {
                    user.setSex(SexEnum.MAN.getValue());
                } else {
                    user.setSex(SexEnum.WOMAN.getValue());
                }
                user.setAccount(userInformPO.getAccount());
                user.setIdCard(userInformPO.getIdCard());
                user.setAvatar(userInformPO.getAvatar());
                user.setNickname(userInformPO.getNickname());
                user.setPassword(userInformPO.getPassword());
                user.setSalt(userInformPO.getSalt());
                user.setIntegral(userInformPO.getIntegral());
                user.setVipLevel(userInformPO.getVipLevel());
                user.setDepartmentId(31);
                user.setIsEnabled(userInformPO.getIsEnabled());
                user.setDelFlag(userInformPO.getDelFlag());
                user.setUpdateTime(new Timestamp(System.currentTimeMillis()));
                user.setCreateTime(new Timestamp(System.currentTimeMillis()));
                //加入到数组中并且该方法返回该数组
                excelContent.add(user);
            }
        } catch (FileNotFoundException e) {
            throw new ServerException("文件不存在");
        } catch (IOException e) {
            System.out.println(e);
            throw new ServerException("读取文件失败");
        }
        return excelContent;
    }

在上面写完读取Excel表单数据后,就可以开始写插入数据库的方法了,我用的是mybatis plus ,方法直接写到下面,大家不会陌生,返回方法是我封装的类,大家用自己项目的稍加修改就可以

public Result importUserWithExcel(ImportOrderDTO importOrderDTO, String rootPath) {
        try {
            //调用上面的方法,读取前端传过来的参数和文件路径
            List<User> excelContent = readExcel(importOrderDTO, rootPath);
            if (excelContent.isEmpty()) {
                return ResultUtil.error("数据为空");
            }
            //下面都是一些逻辑处理,大家一定看得懂就不多说了
            List<User> userList = userMapper.selectList(new EntityWrapper<User>());
            List<User> sameList = new ArrayList<>();
            List<User> differentList = new ArrayList<>();
            for (User excelStudent : excelContent) {
                //数据不同
                boolean flag = true;
                for (User user : userList) {
                    if (user.getAccount().equals(excelStudent.getAccount())) {
                        //相同的数据
                        flag = false;
                        sameList.add(excelStudent);
                    }
                }
                if (flag) {
                    //如果导入的数据与上面判断的条件相等了,就执行插入操作
                    differentList.add(excelStudent);
                    userMapper.insert(excelStudent);
                }
            }
            if (differentList.size() == 0) {
                //判断如果导入的数据跟当前的数据一致的话
                return ResultUtil.error("导入数据与当前数据一致!");
            }
            return ResultUtil.successWithMessage("数据导入成功");
        } catch (Exception e) {
            System.out.println(e);
            return ResultUtil.error("数据导入失败,请检查导入文件格式与模板文件是否相同!");
        }
    }

service层方法写完了,接着就是controller了,直接上代码,工具类在下面

    @PostMapping(value = "/importExcel")
    public Result importExcel(HttpServletRequest request, @RequestBody ImportOrderDTO importOrderDTO) {
        String rootPath = ExcelUtils.getRootPath(request);
        System.out.println(importOrderDTO.getFilePath());
        return userService.importUserWithExcel(importOrderDTO, rootPath);
    }

这是获取根路径的工具类

public class ExcelUtils {
    /**
     * 获取上传根路径
     *
     * @param request 请求信息
     * @return string
     */
    public static String getRootPath(HttpServletRequest request) {
        return request.getSession().getServletContext().getRealPath(UtilConstant.UPLOAD_PATH);
    }

    public static Workbook getWorkbook(String excelType) {
        try {
            return WorkbookFactory.create(!ExcelTypeEnum.XLS.getVal().equals(excelType));
        } catch (IOException e) {
            throw new ServerException("创建excel文件失败", e);
        }
    }

    /**
     * 创建表
     *
     * @param wb         目标文件
     * @param sheetName  表名
     * @param sheetTitle 表头
     * @return sheet
     */
    public static Sheet createSheet(Workbook wb, String sheetName, String[] sheetTitle) {
        Sheet sheet = wb.createSheet(sheetName);

        Row row = sheet.createRow(0);

        for (int i = 0; i < sheetTitle.length; i++) {
            row.createCell(i).setCellValue(sheetTitle[i]);
        }

        return sheet;
    }


    /**
     * 创建单元格.
     *
     * @param row    行
     * @param column 列
     * @param value  值
     */
    public static void createCell(Row row, int column, String value) {
        Cell cell = row.createCell(column);
        cell.setCellValue(value);
    }
}

好了,一个简单的Excel批量导入数据就完成了,感谢支持,大家有什么问题都可以评论留言哦

本文地址:https://blog.csdn.net/weixin_43250266/article/details/107684036