EasyExcel使用
官方网站:https://github.com/alibaba/easyexcel
导入依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.7</version>
</dependency>
将Excel文件读取到数据库中
最简单的读
* 1. 创建excel对应的实体对象 参照{@link DemoData}
* 2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoDataListener}
* 3. 直接读即可
实体类,根据Excel创建 index的值为该属性在第一列的序号
@Data
public class SubjectData {
@ExcelProperty(index = 0)
private String oneSubjectName;
@ExcelProperty(index = 1)
private String twoSubjectName;
}
创建监听器 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去
@Data
@NoArgsConstructor
@AllArgsConstructor
public class SubjectExclListener extends AnalysisEventListener<SubjectData> {
//因为SubjectExclListener不能交给spring进行管理,需要自己new,不能住人其他对象
//不能实现数据库操作
public IEduSubjectService subjectService;
@Override
public void invoke(SubjectData subjectData, AnalysisContext analysisContext) {
if (subjectData==null){
}
//一行一行读取的.第一个值为一级分类(例如:后端) ,第二个值为二级分类(例如:Java)
EduSubject oneSubject = this.existOneSubject(subjectService, subjectData.getOneSubjectName());
if (oneSubject==null){ //判断数据库中该一级分类有没有
oneSubject=new EduSubject();
oneSubject.setParentId("0");
oneSubject.setTitle(subjectData.getOneSubjectName());
subjectService.save(oneSubject);
}
//如果表中有这个一级分类,那么oneSubject就可以获得他的id
//如果表中没有这个一级分类,那么通过上面的set方法,新加入了数据库,且oneSubject属性被注入了,因此也可以获取值
//因为是一行一行的读取,因此下面的二级分类一定是对应着上面查询的或者注入的一级分类
String pid=oneSubject.getId();
//二级分类
EduSubject twoSubject = this.existTwoSubject(subjectService, subjectData.getTwoSubjectName(), pid);
if (twoSubject==null){//判断数据库中该二级分类有没有
twoSubject=new EduSubject();
twoSubject.setParentId(pid);
twoSubject.setTitle(subjectData.getTwoSubjectName());
subjectService.save(twoSubject);
}
}
//一级分类不能重复添加
private EduSubject existOneSubject(IEduSubjectService subjectService,String name){
QueryWrapper<EduSubject> wrapper = new QueryWrapper<>();
wrapper.eq("title",name);
wrapper.eq("parent_id","0");
EduSubject oneSubject = subjectService.getOne(wrapper);
return oneSubject;
}
//二级分类不能重复添加
private EduSubject existTwoSubject(IEduSubjectService subjectService,String name,String pid){
QueryWrapper<EduSubject> wrapper = new QueryWrapper<>();
wrapper.eq("title",name);
wrapper.eq("parent_id",pid);
EduSubject twoSubject = subjectService.getOne(wrapper);
return twoSubject;
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
}
}
控制层: 为了让监听器可以操控数据库,因此在控制层中将service通过监听器的构造函数进行注入,由于使用的mybatis-plus代码生成器因此dao层并没有交给spring管理,因此有两种方法
1.使用service 通过@Autowired自动装配,然后作为参数注入
2.使用dao 通过new一个dao,但是使用mybatis来操作数据库dao层只有一个接口文件和一个xml文件,无法实例化,因此此方法不行
@Autowired
private IEduSubjectService subjectService;
@PostMapping("addSubject")
public R addSubject(MultipartFile file){
subjectService.saveSubject(file,subjectService);
return R.ok();
}
业务层中:通过EasyExcel.read(文件流 , Excel的实体类.class , 监听器).sheet().doRead();
因为用到了Mybatis-plus因此service层封装的CRUD,不用自己写
@Service
public class EduSubjectServiceImpl extends ServiceImpl<EduSubjectMapper, EduSubject> implements IEduSubjectService {
//添加课程分类
@Override
public void saveSubject(MultipartFile file,IEduSubjectService subjectService) {
try {
//文件输入流
InputStream in =file.getInputStream();
//调用方法进行读取
EasyExcel.read(in, SubjectData.class,new SubjectExclListener(subjectService)).sheet().doRead();
}catch (Exception e){
e.printStackTrace();
}
}
}