在第一天把需要导入的Excel文件的表以及需要的字段创建好了,也通过mybatis-plus的方法来完成了对这张表的分页查询、删除、新增和修改功能,接下来就是要实现把Excel文件中的数据给导入到数据库里面的操作了。经过询问开发组的大佬可以通过easyExcel来实现这一功能,然后我就去搜索加自己的尝试最后终于是成功的完成了这一功能,下面就分享一下我的操作过程!
1.导入依赖
<!-- 依赖版本控制 -->
<commons-io.version>2.11.0</commons-io.version>
<easyexcel.version>2.2.6</easyexcel.version>
<!--easyexcel依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>${easyexcel.version}</version>
</dependency>
<!-- 文件操作Io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
要使用easyExcel的话,首先得导入easyExcle依赖还有一个文件操作IO流得依赖,io流的依赖是为了能够方便拿到文件得后缀来简单得判断一下。
2.创建excel文件的模板
模板的创建需要根据具体excel文件里面的内容来设置表头。创建一个dto也就是自己使用的实体类,比如以下这样
里面需要写的内容直接上代码把:
/**
* 创建时间
*/
@ExcelProperty("开始时间(证书日期)")
private Date startTime;
/**
* 结束时间
*/
@ExcelProperty("结束时间")
private Date endTime;
/**
* 职称表姓名
*/
@ExcelProperty("姓名")
private String name;
/**
* 员工的编号
*/
@ExcelProperty("员工编号")
private Integer personNo;
这里面需要注意的是@ExcelProperty("") 是easyExcel的注解 里面的内容需要和表格的头一样 ,序号可以不用管
3.文件导入接口代码撰写
在把excel的模板实体类写好后,就可以开始从Controller层写代码了,话不多说直接上代码:
//职称信息导入
@ApiOperation("职称信息Excel导入")
@PostMapping("/upload")
public ResponseEntity<String> upload(@RequestPart("file") MultipartFile file)throws Exception{
if (file==null){
return ResponseEntity.ok("文件不能为空");
}
return rankService.uploadDataTable(file);
}
@ApiOperation("")注解也是在SWaggerUI上面标识当前接口是什么的作用,需要注意得是文件的导入需要是@PostMapping以及MultipartFile file复杂文件类型,当然我这里的判空有点小错误哈哈,不过没关系,需求功能能完成就好!接下来就是service的核心代码了,直接上图
3.1service层文件导入核心代码
/*
* 职称信息Excel表数据导入
* */
@Override
public ResponseEntity<String> uploadDataTable(MultipartFile file) throws IOException {
String originalFilename = file.getOriginalFilename();
if (!FilenameUtils.getExtension(originalFilename).equals("xlsx")
&& !FilenameUtils.getExtension(originalFilename).equals("xls")
&& !FilenameUtils.getExtension(originalFilename).equals("XLSX")) {
return ResponseEntity.ok("只能上传Excel文件");
}
List<ExcelYcPersonRank> excelYcPersonRanks = this.readExcel(file.getInputStream());
//用户id
List<YcPersonRank> ranks = excelYcPersonRanks.stream().skip(1).map(node -> {
YcPersonRank ycPersonRank = new YcPersonRank();
BeanUtils.copyProperties(node, ycPersonRank);
return ycPersonRank;
}).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(ranks)) {
this.update(Wrappers.lambdaUpdate(YcPersonRank.class)
.eq(YcPersonRank::getDataType, 1)
.set(YcPersonRank::getDelFlag, DeleteEnum.DELETE.getCode()));
this.saveBatch(ranks);
}
首先先拿到文件的名,拿到文件的后缀判断一下是不是excel文件格式的不是的话就返回信息
String originalFilename = file.getOriginalFilename();
if (!FilenameUtils.getExtension(originalFilename).equals("xlsx")
&& !FilenameUtils.getExtension(originalFilename).equals("xls")
&& !FilenameUtils.getExtension(originalFilename).equals("XLSX")) {
return ResponseEntity.ok("只能上传Excel文件");
}
然后就是easyexcel的读操作用法,.headRowNumber(2)是从表头开始,下一个是数据
//readexcel 读职称信息
private List<ExcelYcPersonRank> readExcel(InputStream inputStream) {
//表头在第二行
return EasyExcel.read(inputStream).head(ExcelYcPersonRank.class).headRowNumber(2).sheet().doReadSync();
}
需要注意的是,在我的文件导入模板中表头下面有一行数字,是需要跳过这行数据在进行导入的操作的,当时没发现在这里报错误卡了个把小时QAQ!用的是stream().skip(1)的方法
List<ExcelYcPersonRank> excelYcPersonRanks = this.readExcel(file.getInputStream());
//用户id
List<YcPersonRank> ranks = excelYcPersonRanks.stream().skip(1).map(node -> {
YcPersonRank ycPersonRank = new YcPersonRank();
BeanUtils.copyProperties(node, ycPersonRank);
return ycPersonRank;
}).collect(Collectors.toList());
因为我的excel模板和实体类的字段都是一样的所以我用了BeanUtils.copyProperties这个方法,复制一下实体类,后在转成需要进行操作实体类型的list,然后就可以进行对数据库的插入操作了,注意的是需要进行判空如果表里面没有东西的话也会插入,这里用了删除的枚举,也可以用死亡数据,固定的值,一般不能出现这种写死的数据不过我为了方便哈哈哈。
if (CollectionUtils.isNotEmpty(ranks)) {
this.update(Wrappers.lambdaUpdate(YcPersonRank.class)
.eq(YcPersonRank::getDataType, 1)
.set(YcPersonRank::getDelFlag, DeleteEnum.DELETE.getCode()));
this.saveBatch(ranks);
到这里整个文件导入通过easyExcel的方法就实现了,完成这个功能后其他也都是小case辣,当然还有一些小注意事项,FilenameUtils.getExtension()这个方法是需要导入这个包的。
<!-- 文件操作Io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
对于一些复杂的表头我的办法是用index下标,直接读当前列的数据,然后和数据库字段进行匹配,进行操作。
/**
* 人员编号
*/
@ExcelProperty(value = "人员编号",index = 1)
private String personNo;
/**
* 人员姓名
*/
@ExcelProperty(value = "人员姓名",index = 2)
private String name;
/**
* 是否考核 0否/1是
*/
@ExcelProperty(value = "是否考核",index = 3)
private String isExamine;
到这里就完成了文件导入的功能,Excel文件导入的功能不算太难,但是还是得通过自己的实际操作来进行撰写,才能发现一些小问题的存在。
4.总结:
在写完文件导入的功能后,对于代码的逻辑思路有了提高,也学到了个新的utils工具包的使用,还是需要继续多加努力学习,提高代码的思维和运用,今日的总结就到这里辣。