springboot 导入excel(数据批量导入)

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
好的,我可以帮你解答这个问题。 首先,你需要在你的Spring Boot项目中添加EasyExcel的依赖: ```xml <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>2.2.4</version> </dependency> ``` 然后,你需要编写一个类来表示你的Excel数据模型,可以像这样: ```java @Data public class ExcelData { private String name; private Integer age; // 其他字段... } ``` 接下来,你需要编写一个Excel导入的Controller,可以像这样: ```java @RestController @RequestMapping("/excel") public class ExcelController { @PostMapping("/import") public String importExcel(@RequestParam("file") MultipartFile file) throws Exception { EasyExcel.read(file.getInputStream(), ExcelData.class, new ExcelDataListener()).sheet().doRead(); return "导入成功"; } private static class ExcelDataListener extends AnalysisEventListener<ExcelData> { private List<ExcelData> list = new ArrayList<>(); @Override public void invoke(ExcelData data, AnalysisContext context) { list.add(data); } @Override public void doAfterAllAnalysed(AnalysisContext context) { // 批量保存数据 } } } ``` 这个Controller中,我们使用`@PostMapping`注解来处理POST请求,使用`@RequestParam`注解来接收文件上传参数。然后,我们通过EasyExcel的`EasyExcel.read(...)`方法来读取Excel文件,使用`ExcelData.class`表示我们要读取的Excel数据模型类,使用`new ExcelDataListener()`来指定数据解析的监听器。在`ExcelDataListener`中,我们使用`List`来保存解析出来的数据,然后在`doAfterAllAnalysed`方法中批量保存数据。 最后,你可以向`/excel/import`发送POST请求,上传Excel文件,即可批量导入数据。 希望我的回答能够帮助到你。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值