做个笔记记录一下前段时间项目中学到的内容,利用EasyExcel将Excel中的数据导入到数据库中。

Excel表:

数据库

表名为edu_subject

在edu_subject表中记录了课程的相关信息,其中id、gmt_create、gmt_modified字段由Mybatis-plus自动生成,sort字段默认为0,title字段记录课程名称,若该字段中某条记录为Excel表中的一级分类,就将parent_id字段设置为0,表示没有父类;若该字段中某条记录为Excel表中的二级分类,就将该记录的parent_id字段设置为数据库中对应的一级分类的id值。

Excel表对应实体类

做一些前期准备工作,首先应该设置数据信息对应的实例类,为EduSubject类,还应该设置Excel表中数据对应的实体类,因为EasyExcel会Excel中数据一行一行进行读取,并将数据封装在实体类中

import com.alibaba.excel.annotation.ExcelProperty;

import lombok.Data;

@Datapublic classSubjectData {

@ExcelProperty(index=0) //表示对应Excel表中第一列,也就是一级分类

privateString oneSubjectName;

@ExcelProperty(index=1)privateString twoSubjectName;

}

Service层

service层代码是由Mybatis-plus自动生成,这里直接重写saveSubject方法,实现需求。

通过调用EasyExcel的read方法实现对Excel文件的读取,该方法需要三个参数,分别是文件输入流,Excel表对应的实体类和监听器对象(业务具体代码由监听器实现)。由于每次调用该方法都需要重新new一个对象,所以无法交给spring托管,所以我们需要在controller层将service类传递到该方法中供监听器使用。

import com.alibaba.excel.EasyExcel;

import com.atzjhydx.eduservice.entity.EduSubject;

import com.atzjhydx.eduservice.entity.excel.SubjectData;

import com.atzjhydx.eduservice.listener.SubjectExcelListener;

import com.atzjhydx.eduservice.mapper.EduSubjectMapper;

import com.atzjhydx.eduservice.service.EduSubjectService;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import org.springframework.stereotype.Service;

import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;

@Servicepublic class EduSubjectServiceImpl extends ServiceImpl implementsEduSubjectService {

@Overridepublic voidsaveSubject(MultipartFile file,EduSubjectService eduSubjectService) {try{//文件输入流

InputStream in =file.getInputStream();//调用方法进行读取,监听器代码在下面

EasyExcel.read(in,SubjectData.class,newSubjectExcelListener(eduSubjectService)).sheet().doRead();

}catch(Exception e){

e.printStackTrace();

}

}

}

监听器

importcom.alibaba.excel.context.AnalysisContext;importcom.alibaba.excel.event.AnalysisEventListener;importcom.atzjhydx.eduservice.entity.EduSubject;importcom.atzjhydx.eduservice.entity.excel.SubjectData;importcom.atzjhydx.eduservice.service.EduSubjectService;importcom.atzjhydx.servicebase.enums.CustomizeErrorCode;importcom.atzjhydx.servicebase.exceptionhandler.CustomizeException;importcom.baomidou.mybatisplus.core.conditions.query.QueryWrapper;public class SubjectExcelListener extends AnalysisEventListener{//因为SubjectExcelListener不能交给spring进行管理,需要自己new,不能注入其他对象//不能实现数据库操作(通过在controller层调用service时将subject的service层传递进来)

publicEduSubjectService subjectService;publicSubjectExcelListener(EduSubjectService subjectService) {this.subjectService =subjectService;

}publicSubjectExcelListener() {

}//读取excel内容,一行一行读取,会将每行的数据封装到SubjectData中

@Overridepublic voidinvoke(SubjectData subjectData, AnalysisContext analysisContext) {if (subjectData == null) {throw newCustomizeException(CustomizeErrorCode.DATA_NOT_FOUND);

}//一行一行读取,每次读取有两个值,第一个值一级分类,第二个值二级分类//判断一级分类是否重复

EduSubject existOneSubject = this.existOneSubject(subjectService, subjectData.getOneSubjectName());if (existOneSubject == null){ //没有相同的一级分类,进行添加

existOneSubject = newEduSubject();

existOneSubject.setParentId("0");

existOneSubject.setTitle(subjectData.getOneSubjectName());//设置一级分类名称

subjectService.save(existOneSubject); //MP会自动为existOneSubject其他属性添加值

}//获取一级分类的id值

String pid =existOneSubject.getId();//添加二级分类//判断二级分类是否重复

EduSubject existTwoSubject = this.existTwoSubject(subjectService, subjectData.getTwoSubjectName(), pid);if (existTwoSubject == null){

existTwoSubject= newEduSubject();

existTwoSubject.setParentId(pid);

existTwoSubject.setTitle(subjectData.getTwoSubjectName());

subjectService.save(existTwoSubject);

}

}/*** 通过title获取一级分类(用于判断是否有重复的一级分类)

*@parameduSubjectService

*@paramname 一级分类名称

*@return传入的一级分类名称在数据库中对应信息的实体类*/

privateEduSubject existOneSubject(EduSubjectService eduSubjectService, String name) {

QueryWrapper wrapper = new QueryWrapper<>();

wrapper.eq("title", name);

wrapper.eq("parent_id", "0");

EduSubject oneSubject=eduSubjectService.getOne(wrapper);returnoneSubject;

}

/*** 通过title获取二级分类(用于判断是否有重复的二级分类)

*@parameduSubjectService

*@paramname 二级分类名称

*@parampid 一级分类名称在数据库中对应的id属性值

*@return传入的二级分类名称在数据库中对应信息的实体类*/

privateEduSubject existTwoSubject(EduSubjectService eduSubjectService, String name, String pid){

QueryWrapper wrapper = new QueryWrapper<>();

wrapper.eq("title",name);

wrapper.eq("parent_id",pid);

EduSubject twoSubject=subjectService.getOne(wrapper);returntwoSubject;

}

@Overridepublic voiddoAfterAllAnalysed(AnalysisContext analysisContext) {

}

}

Controller层

import com.atzjhydx.commonutils.R;

import com.atzjhydx.eduservice.service.EduSubjectService;

import io.swagger.annotations.Api;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.CrossOrigin;

import org.springframework.web.bind.annotation.PostMapping;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import org.springframework.web.multipart.MultipartFile;

@RestController

@RequestMapping("/eduservice/edu-subject")

@CrossOrigin

@Api(value= "课程管理")public classEduSubjectController {

@AutowiredprivateEduSubjectService subjectService;//添加课程分类//获取上传过来的文件

@PostMapping("addSubject")publicR addSubject(MultipartFile file){//上传过来excel文件

subjectService.saveSubject(file,subjectService);returnR.ok();

}

}

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐