java后端导入、导出excel,因此在此记录学习一下如何使用Springboot整合easyExcel。
JAVA解析Excel工具Easyexcel
解析、生成Excel比较有名的框架有apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,POI有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大.EASYEXCEL重写了POI对07版Excel的解析,能够原本一个3M的Excel用POI SAX依然需要100 m左右内存降低到几M,并且再大的EXCEL不会出现内存溢出,03版依赖POI的SAX模式。在上层做了模型转换的封装,让使用者更加简单方便
pom
在pom文件中添加依赖
<!-- easyexcel相关依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>1.1.1</version>
</dependency>
excel导出
(1)user实体类
//@Data是lombok的一个注解,加上它会自动生成getter、setter方法
@Data
public class User extends BaseRowModel {
@ExcelProperty(value = "ID", index = 0)
private String id;
@ExcelProperty(value = "姓名", index = 1)
private String name;
@ExcelProperty(value = "年龄", index = 2)
private Integer age;
}
(2)Usercontroller
@GetMapping("/user/excel")
public void excelExport(HttpServletResponse response) throws IOException {
userService.excelExport(response);
}
(3)Userservice
//导出excle
public void excelExport(HttpServletResponse response) throws IOException {
ExcelWriter writer = null;
// 文件输出位置
OutputStream out = null;
try {
List<User> userList = userMapper.getAllUser();
out = response.getOutputStream();
writer = new ExcelWriter(out, ExcelTypeEnum.XLSX);
String fileName = "用户信息表格";
// 写仅有一个 Sheet 的 Excel 文件, 此场景较为通用
Sheet sheet = new Sheet(1, 0, User.class);
// 第一个 sheet 名称
sheet.setSheetName("用户信息");
// 写数据到 Writer 上下文中
// 入参1: 数据库查询的数据list集合
// 入参2: 要写入的目标 sheet
writer.write(userList, sheet);
response.setCharacterEncoding("utf-8");
response.setContentType("application/vnd.ms-excel;charset=utf-8");
response.setHeader("Content-Disposition", "attachment;filename=" + new String((fileName + ".xlsx").getBytes(), "ISO8859-1"));
out.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (writer != null) {
// 将上下文中的最终 outputStream 写入到指定文件中
writer.finish();
}
if (out != null) {
try {
// 关闭流
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
excel导入
(1)Usercontroller
//导入excle
@PostMapping("/user/excelImport")
public String excelImport(@RequestParam("file") MultipartFile file) throws IOException {
userService.excelImport(file);
return "success";
}
(2)Userservice
//导入excle
public void excelImport(MultipartFile file) throws IOException {
if(!file.getOriginalFilename().equals("用户名单.xls") && !file.getOriginalFilename().equals("用户名单.xlsx") ){
return;
}
InputStream inputStream = new BufferedInputStream(file.getInputStream());
//实例化实现了AnalysisEventListener接口的类
ExcelListener excelListener = new ExcelListener(userMapper);
ExcelReader reader = new ExcelReader(inputStream,null,excelListener);
//读取信息
reader.read(new Sheet(1,1,User.class));
}
(3)ExcelListener
public class ExcelListener extends AnalysisEventListener<User> {
private List<User> datas = new ArrayList<>();
private static final int BATCH_COUNT = 3000;
private UserMapper userMapper;
public ExcelListener(UserMapper userMapper){
this.userMapper = userMapper;
}
@Override
public void invoke(User user, AnalysisContext analysisContext) {
//数据存储到datas,供批量处理,或后续自己业务逻辑处理。
datas.add(user);
//达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
if(datas.size() >= BATCH_COUNT){
saveData();
// 存储完成清理datas
datas.clear();
}
}
private void saveData() {
for(User user : datas){
userMapper.insert(user);
}
}
public List<User> getDatas() {
return datas;
}
public void setDatas(List<User> datas) {
this.datas = datas;
}
/**
* 所有数据解析完成了 都会来调用
*/
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
saveData();//确保所有数据都能入库
}
}
参考链接:https://blog.csdn.net/Felix_ar/article/details/103480950