用EasyExcel读取excel文件并传入数据库

项目要求将excel文件中的课程数据传到数据库中,并且excel中的数据使分类的。

0.前言

整个流程介绍

现在controller中声名路径,通过调用方法saveSubject()来上传excel文件,在service中创建saveSubject()中,在serviceImpl中实现此方法,saveSubject中调用EasyExcel的read方法

,此方法必须实现监听器SubjectExcelListener,在监听器中来读取excel数据,是一行一行的读取的。根据文件的特点,第一分类和第二分类的名字不能重复,传入的名字为空则加入,不为空则拒绝添加。所以,设置一个方法来解决这个问题,设比如前端为第一分类,vue为第二分类,每个名都有一个id和一个parent_id,第一分类的parent_id就是0,第二分类的p_id就是第一分类的id,通过传入的名称和p_id=0通过subjectService.getOne(wrapper);此方法判断第一分类是否为空,判断第二分类同样的方法。添加的时候来调用这两个方法来判断第一分类和第二分类是否添加。

还有因为SubjectExcelListener不能交给spring管理,需要 自己new,不能注入其他对象,所以要自己传入serviceimpl,具体是实现代码中已经写了

 

 1.用代码生成器生成所需要文件夹及java文件

具体在这篇如何使用代码生成器

用代码生成器也创建了与数据库所对应的实体类

注意:时间使用的自动填充机制

@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("edu_subject")
@ApiModel(value="Subject对象", description="课程科目")
public class Subject implements Serializable {

    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "课程类别ID")
    @TableId(value = "id", type = IdType.ID_WORKER_STR)
    private String id;

    @ApiModelProperty(value = "类别名称")
    private String title;

    @ApiModelProperty(value = "父ID")
    private String parentId;

    @ApiModelProperty(value = "排序字段")
    private Integer sort;

    @ApiModelProperty(value = "创建时间")
    @TableField(fill = FieldFill.INSERT)
    private Date gmtCreate;

    @ApiModelProperty(value = "更新时间")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date gmtModfied;


}

2.创建controller

@RestController
@CrossOrigin//跨域问题
@RequestMapping("/eduservice/subject")
public class SubjectController {
    @Autowired
    private SubjectService subjectService;

    //添加课程分类
    //获取上传的文件,把文件内容读出来
    @PostMapping("addSubject")
    public UnResult addSubject(MultipartFile file){
        //上传excel文件
        subjectService.saveSubject(file,subjectService);
        return UnResult.ok();
    }
}

 3.创建与excel表对应的实体类

index=0就是第一列,index=1就是第二列

用EasyExcel读取excel文件并传入数据库

/**
 * @author ZhangTao
 * @date 2021/4/22 15:31
 * @note:创建和excel对应的实体类
 *
 * 就是excel中的表头一级分类,二级分类中的列
 */

@Data
public class SubjectData {
    @ExcelProperty(index = 0)
    private String oneSubjectName;
    @ExcelProperty(index = 1)
    private String twoSubjectName;
}

4.在service中写接口,serviceimpl写实现方法

public interface SubjectService extends IService<Subject> {

    //添加课程分类
    void saveSubject(MultipartFile file,SubjectService subjectService);
}

 因为使读文件EasyExcel中要使用监听器来进行读文件,第四步写监听器

@Service
public class SubjectServiceImpl extends ServiceImpl<SubjectMapper, Subject> implements SubjectService {

    @Override
    public void saveSubject(MultipartFile file,SubjectService subjectService) {
        try {
            //文件输入流
            InputStream in=file.getInputStream();
            //调用方法进行读取
            //吧service直接注入进来为了后面能使用

            //因为在listener中不能注入service所以在这个serviceiimpl中,通过listener使service注入进去,为了在listener中能够使用service中的发方法save/
            EasyExcel.read(in, SubjectData.class,new SubjectExcelListener(subjectService)).sheet().doRead();
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

5.写监听器

/**
 * @author ZhangTao
 * @date 2021/4/22 15:42
 * @note:监听器
 *
 * /因为SubjectExcelListener不能交给spring管理,需要 自己new,不能注入其他对象
 * 不能实现数据库的操作
 *
 *前面service中已经在listener中注入了service,
 */
public class SubjectExcelListener extends AnalysisEventListener<SubjectData> {

    public SubjectService subjectService;
    //创建有参无参构造器为了后面能做添加操作,
    public SubjectExcelListener(SubjectService subjectService) {
        this.subjectService = subjectService;
    }
    public SubjectExcelListener(){

    }

    @Override
    public void invoke(SubjectData subjectData, AnalysisContext analysisContext) {
        if(subjectData==null){
            throw new GuliException(20001,"文件数据为空");
        }
        //从第二行开始读
        //一行一行的读取,每次读取的两个值,第一个值是一级分类,第二个是二级分类
        //判断一级分类是否为空
        Subject existOneSubject = this.existOneSubject(subjectService,subjectData.getOneSubjectName());
        //为空就是没有相同的一级分类,则进行添加
        if(existOneSubject==null){//没有相同的一级分类
            existOneSubject=new Subject();
            existOneSubject.setParentId("0");
            existOneSubject.setTitle(subjectData.getOneSubjectName());//刚传进去的一级分类名
            subjectService.save(existOneSubject);//前面做了很多就是为了能使用subjectService调用save方法,
        }

        //获取一节分类的id值
        //二级分类的pareat——id就是一级分类的id值
        String pid=existOneSubject.getId();
        //添加二级分类
        //判断二级分类是否重复
        Subject existTwoSubject = this.existTwoSubject(subjectService,subjectData.getTwoSubjectName(),pid);
        if(existTwoSubject==null){//没有相同的一级分类
            existTwoSubject=new Subject();
            existTwoSubject.setParentId(pid);
            existTwoSubject.setTitle(subjectData.getTwoSubjectName());//一级分类名
            subjectService.save(existTwoSubject);
        }
    }
    //判断一级分类不能重复添加
    //使根据传进去的name和0(代表着使一级分类)//判断表中是否有值
    //没有值的话返回为null
    private Subject existOneSubject(SubjectService subjectService,String name){
        QueryWrapper<Subject> wrapper=new QueryWrapper<>();
        wrapper.eq("title",name);
        wrapper.eq("parent_id",0);
        Subject oneSubject=subjectService.getOne(wrapper);//getOne根据 Wrapper,查询一条记录
        return oneSubject;
    }
    //    //判断二级分类不能重复添加

    private Subject existTwoSubject(SubjectService subjectService,String name,String pid){
        QueryWrapper<Subject> wrapper=new QueryWrapper<>();
        wrapper.eq("title",name);
        wrapper.eq("parent_id",pid);
        Subject twoSubject=subjectService.getOne(wrapper);
        return twoSubject;
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {

    }
}

测试

用的是swagger来测试

用EasyExcel读取excel文件并传入数据库

用EasyExcel读取excel文件并传入数据库

用EasyExcel读取excel文件并传入数据库

 

 

上一篇:EasyExcel ExcelGenerateException: The index of ‘xx


下一篇:Java 开发必备,EasyExcel 操作详解!