1. 课程目录需求
2.EasyExcel入门
2.1 导入坐标
<dependencies>
<!-- easy excel 依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.6</version>
</dependency>
<!--lombok , @Data 等-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--测试起步依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
2.2 封装类
package com.czxy.test.excel;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
/**
* @author 桐叔
* @email [email protected]
*/
@Data
public class Student {
@ExcelProperty("编号")
private String id;
@ExcelProperty("姓名")
private String name;
@ExcelProperty("年龄")
private Integer age;
@ExcelProperty("电话")
private String telephone;
@ExcelProperty("邮箱")
private String email;
@ExcelProperty("生日")
private String birthday;
}
2.3 写操作
package com.czxy.test.excel;
import com.alibaba.excel.EasyExcel;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
/**
* @author 桐叔
* @email [email protected]
*/
public class TestExcelWrite {
private List<Student> getData() {
List<Student> list = new ArrayList<>();
for(int i = 0 ; i < 20 ; i ++) {
Student student = new Student();
student.setId( i + "");
student.setName("jack" + i);
student.setAge(i);
student.setTelephone("13699" + i);
student.setEmail("jack" + i + "@czxy.com") ;
student.setBirthday("2021-12-21");
list.add(student);
}
return list;
}
@Test
public void write() {
String file = "G:/czxy_2019_java34/xls/student_demo.xls";
// 进行写操作,确定表头,表名,内容
EasyExcel.write(file,Student.class).sheet("Java34").doWrite(getData());
}
}
2.4 读操作
-
监听器
package com.czxy.test.excel; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; /** * @author 桐叔 * @email [email protected] */ public class StudentListener extends AnalysisEventListener<Student> { @Override public void invoke(Student student, AnalysisContext analysisContext) { System.out.println(student); } @Override public void doAfterAllAnalysed(AnalysisContext analysisContext) { System.out.println("解析完成"); } }
-
读
package com.czxy.test.excel; import com.alibaba.excel.EasyExcel; import org.junit.Test; /** * @author 桐叔 * @email [email protected] */ public class TestExcelRead { private String getPath() { return TestExcelRead.class.getResource("/").getPath(); } @Test public void testRead() { // 确定文件位置 : E:\workspaces_2019\zx-parent-1228\zx-test-parent\zx-test-excel\target\classes\student_demo.xls String file = getPath() + "student_demo.xls"; // 读取excel文件 EasyExcel.read(file,Student.class, new StudentListener()).sheet("Java78").doRead(); } }
3.课程目录批量导入
3.1 前端实现
- 添加upload组件
<!-- 文件上传 -->
<el-upload
class="upload-demo"
action="http://localhost:10010/v2/course-service/subject/upload"
multiple
:limit="1"
:on-exceed="handleExceed"
:before-upload="beforeAvatarUpload"
:file-list="fileList">
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">只能上传xls/xlsx文件,且不超过2MB</div>
</el-upload>
-
声明变量
data() { return { fileList: [], //上传文件列表 } },
-
定义函数
methods() { handleExceed(files, fileList) { this.$message.warning(`当前限制选择 1 个文件,本次选择了 ${ files.length} 个文件,共选择了 ${ files.length + fileList.length} 个文件`); }, beforeAvatarUpload(file) { const isXls = file.type === 'application/vnd.ms-excel'; const isXlsx = file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'; if (!isXls && !isXlsx) { this.$message.error('上传文件只能是 xls/xlsx 格式!'); } const isLt2M = file.size / 1024 / 1024 < 2; if (!isLt2M) { this.$message.error('上传头像图片大小不能超过 2MB!'); } return (isXls || isXlsx) && isLt2M; } }
-
成功回调
3.2 后端实现:controller页面
-
element-ui upload组件,上传默认字段名为file,后端从头roller中,需要提供一个类型为MultipartFile变量file
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CPX0TxFH-1617869070858)(assets/image-20210311115136873.png)]
@PostMapping("/upload")
public BaseResult upload(MultipartFile file) throws IOException {
System.out.println(file.getInputStream());
return BaseResult.ok("上传成功");
}
4.1 批量导入
4.1.0 前提
- 需要在zuul中放行上传请求
4.1.1 后端excel解析
-
编写SubjectVo,用于封装excel一行数据
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NvyI0O2T-1617869274191)(assets/image-20210312083905919.png)]
package com.czxy.zx.course; import com.alibaba.excel.annotation.ExcelProperty; import lombok.Data; /** * @author 桐叔 * @email [email protected] */ @Data public class SubjectVo { @ExcelProperty("一级分类") private String firstSubject; @ExcelProperty("二级分类") private String secondSubject; }
-
编写controller,用于解析excel
@PostMapping("/upload") public BaseResult upload(MultipartFile file) throws IOException { // 上传文件原始名 // System.out.println(file.getOriginalFilename()); // 获得上传文件内容 // System.out.println(file.getInputStream()); // 解析xls文件 read(流,封装对象,处理类).sheet(表名/表索引).doRead() EasyExcel.read(file.getInputStream(), SubjectVo.class, subjectListener).sheet(0).doRead(); return BaseResult.ok("上传成功"); }
-
编写excel解析处理类 SubjectListener
- 使用@Component交于spring管理处理类
package com.czxy.zx.course.listener; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import com.czxy.zx.course.SubjectVo; import org.springframework.stereotype.Component; /** * @author 桐叔 * @email [email protected] */ @Component public class SubjectListener extends AnalysisEventListener<SubjectVo> { @Override public void invoke(SubjectVo studentVo, AnalysisContext context) { System.out.println(studentVo); } @Override public void doAfterAllAnalysed(AnalysisContext context) { } }
1.1.2 后端处理解析内容
-
需求:
- 一级科目:
- 通过科目名称获得一级科目,parent_id=0表示一级科目(一级名称不能重复)
- 如果不存在,添加一个新的一级科目
- 二级科目:
- 通过二级科目名称从一级科目下查询(在一级科目下,二级科目不能重复)
- 如果不存在,给一级科目添加一个新的二级科目 parent_id=一级科目id
- 一级科目:
-
修改EduSubject
package com.czxy.zx.domain; import com.baomidou.mybatisplus.annotation.*; import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * @author 桐叔 * @email [email protected] */ @TableName("edu_subject") @Data public class EduSubject { @TableId(type = IdType.ASSIGN_UUID) //课程科目ID private String id; //科目名称 private String title; //父ID private String parentId; //排序字段 private Integer sort; //创建时间 @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8") @TableField(fill = FieldFill.INSERT) private Date gmtCreate; //更新时间 @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8") @TableField(fill = FieldFill.INSERT_UPDATE) private Date gmtModified; @TableField(exist = false) private List<EduSubject> children = new ArrayList<>(); }
-
完成填充处理类
package com.czxy.zx.course.handler;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* @author 桐叔
* @email [email protected]
*/
@Component
public class DateMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
// 添加
this.setFieldValByName("gmtCreate", new Date(), metaObject);
this.setFieldValByName("gmtModified", new Date(), metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
// 修改
this.setFieldValByName("gmtModified", new Date(), metaObject);
}
}
-
编写上传监听处理类:一级科目
package com.czxy.zx.course.listener; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.czxy.zx.course.SubjectVo; import com.czxy.zx.course.mapper.EduSubjectMapper; import com.czxy.zx.course.service.EduSubjectService; import com.czxy.zx.domain.EduSubject; import org.springframework.stereotype.Component; import javax.annotation.Resource; /** * @author 桐叔 * @email [email protected] */ @Component public class SubjectListener extends AnalysisEventListener<SubjectVo> { @Resource private EduSubjectService eduSubjectService; @Override public void invoke(SubjectVo studentVo, AnalysisContext context) { System.out.println(studentVo); // 1.一级科目 // 1.1 查询一级科目:父=0 , 名称 QueryWrapper firstQueryWrapper = new QueryWrapper(); firstQueryWrapper.eq("parent_id", "0"); firstQueryWrapper.eq("title",studentVo.getFirstSubject()); EduSubject firstSubject = eduSubjectService.getOne(firstQueryWrapper); // 1.2 不存在,新加 if(firstSubject == null ) { firstSubject = new EduSubject(); // id 随机生成uuid firstSubject.setTitle(studentVo.getFirstSubject()); firstSubject.setParentId("0"); firstSubject.setSort(0); // 创建时间、修改时间 -- MyBatisPlus数据填充 eduSubjectService.save(firstSubject); } // 二级科目 } @Override public void doAfterAllAnalysed(AnalysisContext context) { } }
-
编写上传监听处理类:二级科目
package com.czxy.zx.course.listener; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.czxy.zx.course.SubjectVo; import com.czxy.zx.course.mapper.EduSubjectMapper; import com.czxy.zx.course.service.EduSubjectService; import com.czxy.zx.domain.EduSubject; import org.springframework.stereotype.Component; import javax.annotation.Resource; /** * @author 桐叔 * @email [email protected] */ @Component public class SubjectListener extends AnalysisEventListener<SubjectVo> { @Resource private EduSubjectService eduSubjectService; @Override public void invoke(SubjectVo studentVo, AnalysisContext context) { System.out.println(studentVo); // 1.一级科目 // 1.1 查询一级科目:父=0 , 名称 QueryWrapper firstQueryWrapper = new QueryWrapper(); firstQueryWrapper.eq("parent_id", "0"); firstQueryWrapper.eq("title",studentVo.getFirstSubject()); EduSubject firstSubject = eduSubjectService.getOne(firstQueryWrapper); // 1.2 不存在,新加 if(firstSubject == null ) { firstSubject = new EduSubject(); // id 随机生成uuid firstSubject.setTitle(studentVo.getFirstSubject()); firstSubject.setParentId("0"); firstSubject.setSort(0); // 创建时间、修改时间 -- MyBatisPlus数据填充 eduSubjectService.save(firstSubject); } // 2 二级科目 // 2.1 查询二级科目 QueryWrapper secondQueryWrapper = new QueryWrapper(); secondQueryWrapper.eq("parent_id", firstSubject.getId()); secondQueryWrapper.eq("title",studentVo.getSecondSubject()); EduSubject secondSubject = eduSubjectService.getOne(secondQueryWrapper); // 2.2 不存在,添加 if(secondSubject == null) { secondSubject = new EduSubject(); // id 随机生成uuid // 1)二级科目的名称 secondSubject.setTitle(studentVo.getSecondSubject()); // 2) 二级科目所属一级科目的id secondSubject.setParentId(firstSubject.getId()); secondSubject.setSort(0); // 创建时间、修改时间 -- MyBatisPlus数据填充 eduSubjectService.save(secondSubject); } } @Override public void doAfterAllAnalysed(AnalysisContext context) { } }