springboot excel数据批量导入

参考博客: https://blog.csdn.net/u013322876/article/details/72859089

1、pom.xml 引入poi依赖
	<!--poi-->
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi</artifactId>
			<version>4.1.0</version>
		</dependency>
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi-ooxml</artifactId>
			<version>4.1.0</version>
		</dependency>
2、controller 方法
     /**
     * 批量导入学生
     * @param file  文件
     * @param request
     * @return
     * @throws Exception
     */
    @Transactional
    @RequestMapping("/importStu")
    public ApiJsonRes importStu(MultipartFile file, HttpServletRequest request) throws Exception{
        //响应数据
        ApiJsonRes apiJsonRes=new ApiJsonRes("201","导入失败");

        if(file == null){
            apiJsonRes.setApiResCodeDesc("导入文件不能为空");
            return apiJsonRes;
        }
        
        //读取文件流
        InputStream is = file.getInputStream();
        //文件名
        String fileName=file.getOriginalFilename();
        
        boolean notNull = false;
        if (!fileName.matches("^.+\\.(?i)(xls)$") && !fileName.matches("^.+\\.(?i)(xlsx)$")) {
            apiJsonRes.setApiResCodeDesc("上传文件格式不正确");
            return apiJsonRes;
        }
        Workbook wb = null;
        if (fileName.matches("^.+\\.(?i)(xlsx)$")) {
            //xlsx格式
            wb = new XSSFWorkbook(is);
        } else {
            //xls格式
            wb = new HSSFWorkbook(is);
        }
        if (wb != null) {
            //默认读取第一个sheet
            Sheet sheet = wb.getSheetAt(0);
            if (sheet != null) {
                //最先读取首行
                boolean firstRow = true;
                List<Student> studentList = new ArrayList<>();
                boolean isThrow = false;
                
                
                /*根据手机号判断文件是否包含重复的学生,
                如果需要多个字段唯一确定一条数据可以使用List<Map<String, Object>>,
                下面同样使用contains判断是否已经包含同一条数据*/
                List<String> phoneList=new ArrayList<>();
                try {
                    if (sheet.getLastRowNum() > 0) {
                        for (int i = sheet.getFirstRowNum(); i <= sheet.getLastRowNum(); i++) {
                            //循环行
                            Student student = new Student();
                            Row row = sheet.getRow(i);
                            //首行  提取注解
                            if (firstRow) {
                                if (row.getCell(0).getStringCellValue().equals("姓名")
                                        && row.getCell(2).getStringCellValue().equals("性别")
                                        && row.getCell(3).getStringCellValue().equals("手机号")
                                        && row.getCell(5).getStringCellValue().equals("年级班级")) {
                                } else { apiJsonRes.setApiResCodeDesc("格式不正确,请下载模板进行参考");
                                    return apiJsonRes;
                                }
                                firstRow = false;
                            } else {
                                //忽略空白行
                                if (row == null || ToolHelp.isRowEmpty(row)) {
                                    continue;
                                }
                                int theRow = i + 1;
                                if (row.getCell(0) != null) {
                                    row.getCell(0).setCellType(CellType.STRING);
                                    String stuName = row.getCell(0).getStringCellValue();
                                    if (StringUtils.isEmpty(stuName)) {
                                        isThrow = true;
                                        apiJsonRes.setApiResCodeDesc("导入失败(第" + theRow + "行,姓名不能为空)");
                                        throw new RuntimeException("导入失败(第" + theRow + "行,姓名不能为空)");
                                    } else {
                                        student.setName(stuName);
                                    }
                                } else {
                                    isThrow = true;
                                    apiJsonRes.setApiResCodeDesc("导入失败(第" + theRow + "行,学员姓名不能为空)");
                                    throw new RuntimeException("导入失败(第" + theRow + "行,学员姓名不能为空)");
                                }

                                if (row.getCell(1) != null) {
                                    row.getCell(1).setCellType(CellType.STRING);
                                    String stuSex = row.getCell(1).getStringCellValue();
                                    if (StringUtils.isEmpty(stuSex)) {
                                        isThrow = true;
                                        apiJsonRes.setApiResCodeDesc("导入失败(第" + theRow + "行,性别不能为空)");
                                        throw new RuntimeException("导入失败(第" + theRow + "行,性别不能为空)");
                                    } else {
                                        int sex = 1;
                                        if (stuSex.equals("女")) {
                                            sex = 2;
                                        }
                                        student.setSex(sex);
                                    }
                                } else {
                                    isThrow = true;
                                    apiJsonRes.setApiResCodeDesc("导入失败(第" + theRow + "行,性别不能为空)");
                                    throw new RuntimeException("导入失败(第" + theRow + "行,性别不能为空)");
                                }

                                if (row.getCell(2) != null) {
                                    row.getCell(2).setCellType(CellType.STRING);
                                    String stuPhone = row.getCell(2).getStringCellValue();
                                    if (StringUtils.isEmpty(stuPhone) || stuPhone.length() != 11) {
                                        isThrow = true;
                                        apiJsonRes.setApiResCodeDesc("导入失败(第" + theRow + "行,手机号有误)");
                                        throw new RuntimeException("导入失败(第" + theRow + "行,手机号有误)");
                                    } else {
                                        if (!phoneList.isEmpty() && phoneList.size() > 0) {
                                            //判断手机号是否重复
                                            if (phoneList.contains(stuPhone)) {
                                                isThrow = true;
                                                apiJsonRes.setApiResCodeDesc("导入失败(第" + theRow + "行,手机号" + stuPhone + "有重复)");
                                                throw new RuntimeException("导入失败(第" + theRow + "行,手机号" + stuPhone + "有重复)");
                                            } else {
                                                phoneList.add(stuPhone);
                                                student.setPhone(stuPhone);
                                            }
                                        } else {
                                            student.setPhone(stuPhone);
                                        }
                                    }
                                } else {
                                    isThrow = true;
                                    apiJsonRes.setApiResCodeDesc("导入失败(第" + theRow + "行,手机号有误)");
                                    throw new RuntimeException("导入失败(第" + theRow + "行,手机号有误)");
                                }


                                if (row.getCell(3) != null) {
                                    row.getCell(3).setCellType(CellType.STRING);
                                    String stuGrade = row.getCell(3).getStringCellValue();
                                    if (StringUtils.isEmpty(stuGrade)) {
                                        isThrow = true;
                                        apiJsonRes.setApiResCodeDesc("导入失败(第" + theRow + "行,年级班级不能为空)");
                                        throw new RuntimeException("导入失败(第" + theRow + "行,年级班级不能为空)");
                                    } else {
                                        student.setGrade(stuGrade);
                                    }
                                } else {
                                    isThrow = true;
                                    apiJsonRes.setApiResCodeDesc("导入失败(第" + theRow + "行,年级班级不能为空)");
                                    throw new RuntimeException("导入失败(第" + theRow + "行,年级班级不能为空)");
                                }
                                student.setCreateTime(new Date());
                                studentList.add(student);
                            }
                            if (isThrow) {
                                break;
                            }
                        }
                    } else {
                        isThrow = true;
                        apiJsonRes.setApiResCodeDesc("导入失败,数据为空");
                        throw new RuntimeException("导入失败,数据为空");
                    }
                }catch (Exception e) {
                    e.printStackTrace();
                }

                if (isThrow) {
                    return apiJsonRes;
                } else {
                    if(!studentList.isEmpty() && studentList.size() > 0){
                        int addRes=studentService.addList(studentList);
                        if(addRes > 0){
                            apiJsonRes.setApiResCode("200");
                            apiJsonRes.setApiResCodeDesc("导入成功");
                        }
                    }else{
                        return apiJsonRes;
                    }
                }
            } else {
                apiJsonRes.setApiResCodeDesc("导入失败,数据为空");
            }
        } else {
            apiJsonRes.setApiResCodeDesc("导入失败,数据为空");
        }
            
        return apiJsonRes;
    }
2.1判断空行
    public static boolean isRowEmpty(Row row) {
        for (int c = row.getFirstCellNum(); c < row.getLastCellNum(); c++) {
            Cell cell = row.getCell(c);
            if (cell != null && cell.getCellType() != CellType.BLANK)
                return false;
        }
        return true;
    }
2.2时间处理
    //excel中的数据格式必须是yyyy-MM-dd(如:2020-10-12)
    if (row.getCell(4) != null) {
        row.getCell(4).setCellType(CellType.STRING);
        String sTime = row.getCell(4).getStringCellValue();
        if (StringUtils.isEmpty(sTime)) {
            isThrow = true;
            apiJsonRes.setApiResCodeDesc("导入失败(第" + theRow + "行,时间不能为空)");
            throw new RuntimeException("导入失败(第" + theRow + "行,时间不能为空)");
        } else {
            Date s=TimeHelp.stringToDate("yyyy-MM-dd",sTime);
            enroll.setCourseStartTime(s);
        }
    } else {
        isThrow = true;
        apiJsonRes.setApiResCodeDesc("导入失败(第" + theRow + "行,时间不能为空)");
        throw new RuntimeException("导入失败(第" + theRow + "行,时间不能为空)");
    }
2.3string 类型日期转Date
    /**
     * string 类型日期转Date
     * @param patterm string 格式
     * @param str 时间
     * @return
     * @throws ParseException
     */
    public static Date stringToDate(String patterm,String str) throws ParseException {
        DateFormat format1 = new SimpleDateFormat(patterm);
        Date date = null;
        date = format1.parse(str);
        return date;
    }
2.4捕获异常
     /*
        注意:
        手动抛出异常,放在try ...里才会执行接下来的代码
            throw new RuntimeException("导入失败,数据为空");
        try catch嵌套:
            内层不能捕获时,会考虑外层内否捕获,内层能捕获,则外层catch不执行。
    */
    catch (ParseException e){
        e.printStackTrace();
        apiJsonRes.setApiResCodeDesc("导入失败(第" + theRow + "行,请核对日期)");
        isThrow=true;//用于之后的逻辑处理
    }catch (Exception e) {
        e.printStackTrace();
    }
3、service
  • //service层就不再贴代码了
4、mybatis(StudentMapper.xml)
    <!--1.批量添加-->
    <insert id="addList" parameterType="com.pojo.Student">
        insert into student (id, name,
          grade, phone,sex)
        values
        <foreach collection="studentList" separator="," index="index" item="item">
        (#{item.id,jdbcType=VARCHAR}, 
        #{item.name,jdbcType=VARCHAR},
          #{item.grade,jdbcType=VARCHAR},  
          #{item.phone,jdbcType=VARCHAR},
          #{item.sex,jdbcType=INTEGER})
        </foreach>
    </insert>
    <!--2.如果需要批量修改,参考如下(注意:数据库连接需要加上allowMultiQueries=true-->
    <update id="updList" parameterType="com.pojo.Student">
        <foreach collection="studentList" separator=";" item="item">
          update student
          <set>
            <if test="item.name != null">
              name = #{item.name,jdbcType=VARCHAR},
            </if>
            <if test="item.grade != null">
              grade = #{item.grade,jdbcType=VARCHAR},
            </if>
            <if test="item.phone != null">
              phone = #{item.phone,jdbcType=VARCHAR},
            </if>
            <if test="item.sex != null">
              sex = #{item.sex,jdbcType=INTEGER},
            </if>
          </set>
          where id = #{item.id,jdbcType=VARCHAR}
        </foreach>
    </update>
5、注意
  • 需要批量修改时,数据库连接需要加上allowMultiQueries=true
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐