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

【#|用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="https://www.it610.com/article/Subject对象", description="课程科目") public class Subject implements Serializable {private static final long serialVersionUID = 1L; @ApiModelProperty(value = "https://www.it610.com/article/课程类别ID") @TableId(value = "https://www.it610.com/article/id", type = IdType.ID_WORKER_STR) private String id; @ApiModelProperty(value = "https://www.it610.com/article/类别名称") private String title; @ApiModelProperty(value = "https://www.it610.com/article/父ID") private String parentId; @ApiModelProperty(value = "https://www.it610.com/article/排序字段") private Integer sort; @ApiModelProperty(value = "https://www.it610.com/article/创建时间") @TableField(fill = FieldFill.INSERT) private Date gmtCreate; @ApiModelProperty(value = "https://www.it610.com/article/更新时间") @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 {//添加课程分类 void saveSubject(MultipartFile file,SubjectService subjectService); }

因为使读文件EasyExcel中要使用监听器来进行读文件,第四步写监听器
@Service public class SubjectServiceImpl extends ServiceImpl 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 {public SubjectService subjectService; //创建有参无参构造器为了后面能做添加操作, public SubjectExcelListener(SubjectService subjectService) { this.subjectService = subjectService; } public SubjectExcelListener(){}@Override public void invoke(SubjectData subjectData, AnalysisContext analysisContext) { if(subjectData=https://www.it610.com/article/=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 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 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文件并传入数据库
文章图片



    推荐阅读