前言
小编最近使用springboot集成使用EasyExcel时发现了一个坑
EasyExcel
EasyExcel是由阿里巴巴开发团队提供的一套操作excel的工具, 与常用的POI区别就在于如下
-
POI对大数据处理起来会引起OOM内存溢出, EasyExcel对此进行了优化, 对内存的占用极大的优化,同时允许分批处理数据
-
POI对于读写EXCEL操作复杂, 而EasyExcel只需几行代码即可完成
注意点
EasyExcel 版本更新快,不同版本 API 均有不同,有些已经废弃,所以,大家查看文档时,务必找到对应版本的!
SpringBoot集成EasyExcel
SpringBoot可以很方便的集成EasyExcel
添加依赖到pom.xml
<!-- EasyExcel依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.0-beta2</version>
</dependency>
使用上也是很简单,咸鱼君就举个简单的例子, 将excel转换为java 实体类来读取
先定义一个User的实体
package com.mrcoder.frameservice.model.po;
import javax.persistence.Table;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
//import lombok.Getter;
//import lombok.Setter;
/**
* @Description: User实体类
* @author: mrcoder
*/
//@Getter
//@Setter
@Data
@Table(name = "frame_user")
public class User extends BaseEntity {
private static final long serialVersionUID = -6525290662533134200L;
@ExcelProperty(index = 1)
private String name;
@ExcelProperty(index = 2)
private String nickName;
@ExcelProperty(index = 3)
private Integer age;
@ExcelProperty(index = 4)
private String email;
@ExcelProperty(index = 5)
private String phone;
private Integer status;
}
而后定义一个监听器
package com.mrcoder.frameservice.excel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import com.mrcoder.frameservice.model.po.User;
import java.util.ArrayList;
import java.util.List;
@Slf4j
public class UserModelListener extends AnalysisEventListener<User> {
//自定义用于暂时存储data
private List<User> dataList = new ArrayList<User>();
@Override
public void invoke(User user, AnalysisContext context) {
log.info("解析到一条数据:{}", JSON.toJSONString(user));
log.info("age:{}", user.getAge());
//根据自己业务做处理
doSomething(user);
dataList.add(user);
}
private void doSomething(User user) {
log.info("处理数据!");
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
log.info("所有数据解析完成!");
//datas.clear();
}
public List<User> getDataList() {
return dataList;
}
public void setDataList(List<User> dataList) {
this.dataList = dataList;
}
}
然后,我们定义一个Controller来调用读取上传的Excel
package com.mrcoder.frameservice.controller;
import com.alibaba.excel.EasyExcel;
import com.mrcoder.frameservice.excel.UserModelListener;
import com.mrcoder.frameservice.model.po.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
@RestController
@RequestMapping("excel")
public class ExcelController {
private static final Logger logger = LoggerFactory.getLogger(ExcelController.class);
@PostMapping("/importUsers")
public void importUsers(HttpServletRequest request) throws IOException {
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
MultipartFile skuExcel = multipartRequest.getFile("filename");
InputStream inputStream = skuExcel.getInputStream();
EasyExcel.read(inputStream, User.class, new UserModelListener()).sheet().doRead();
}
最后我们postman提交excel文件即可
excel文件
image.png
控制台打印结果
image.png
EasyExcel使用问题总结
@ExcelProperty注解是什么
这个注解就是Excel文件列对应实体的依据
@ExcelProperty(index = 1)
private String name;
如上代码, 意思就是 User的name值对应Excel内容的第2列值!
注意, index从0开始, 代表Excel文件的第一列!
读取excel文件反射成实体后全为NULL
这个问题,咸鱼君也碰过到, 查阅资料得知,lombok这个依赖和EasyExcel还是有点冲突的, 解决的方法就是
将实体类上的这两个注解干掉即可, 没碰到此问题的可能是后续版本解决了该bug!
@Getter
@Setter
最后, 对EasyExcel使用上还有疑问的可以去官方文档上看~
https://alibaba-easyexcel.github.io/index.html
最后,关于EasyExcel反射实体后,进行数据处理的多种方式,可以在我的git项目上找到使用案例, 项目介绍可以看这里.
网友评论