入门alibaba的EasyExcel

一、关于EasyExcel

1、什么是EasyExcel,有什么作用?

EasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目。在尽可能节约内存的情况下支持读写百M的Excel。

2、为什么选择EasyExcel,而不是Apache poi或者jxl?

Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。easyexcel重写了poi对07版Excel的解析,能够原本一个3M的excel用POI sax依然需要100M左右内存降低到几M,并且再大的excel不会出现内存溢出,03版依赖POI的sax模式。在上层做了模型转换的封装,让使用者更加简单方便。

3、怎样使用?

以下章节能让你快速使用EasyExcel对excel文件进行读写操作。

二、入门EasyExcel

1、新建一个maven项目、导入easyexcel的jar包。

maven项目的jar包可以在https://mvnrepository.com/里面搜索,能快速的搜索到想要的jar包,以及版本。

我这里选择的是当前最新的2.1.4版本。

2、新建一个实体类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package com.hgl.entity;

import java.util.Date;

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.DateTimeFormat;
import com.alibaba.excel.annotation.format.NumberFormat;
import com.alibaba.excel.annotation.write.style.ColumnWidth;

// 表示列宽
@ColumnWidth(20)
public class UserEntity {

// index--表示属性在第几列,value--表示标题
@ExcelProperty(value = "姓名", index = 0)
private String name;

// @DateTimeFormat--对日期格式的转换
@DateTimeFormat("yyyy-MM-dd")
@ExcelProperty(value = "生日", index = 1)
private Date birthday;

@ExcelProperty(value = "电话", index = 2)
private String telphone;

// @NumberFormat--对数字格式的转换
@NumberFormat("#.##")
@ExcelProperty(value = "工资", index = 3)
private double salary;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Date getBirthday() {
return birthday;
}

public void setBirthday(Date birthday) {
this.birthday = birthday;
}

public String getTelphone() {
return telphone;
}

public void setTelphone(String telphone) {
this.telphone = telphone;
}

public double getSalary() {
return salary;
}

public void setSalary(double salary) {
this.salary = salary;
}

}

3、提供一个供外部调用写入Excel的接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package com.hgl.controller;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletResponse;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.excel.EasyExcel;
import com.google.common.collect.Lists;
import com.hgl.entity.UserEntity;

@RestController
@RequestMapping("/excel")
public class ExcelWriteController{


/**
* 测试写入Excel文件
*
* @param response
* @throws IOException
*/
@GetMapping("/download")
public void doDownLoad(HttpServletResponse response) throws IOException {
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
String fileName = URLEncoder.encode("第一个文件", "UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
EasyExcel.write(response.getOutputStream(), UserEntity.class).sheet("模板").doWrite(getData());
}

/**
* 构造假数据,实际上应该从数据库查出来
*
* @return List<UserEntity>
*/
private List<UserEntity> getData(){
List<UserEntity> users = Lists.newArrayList();
for (int i = 1; i <= 9; i++) {
UserEntity user = new UserEntity();
user.setBirthday(new Date());
user.setName("user_" + i);
user.setSalary(1.285 * i);
user.setTelphone("1888888888" + i);
users.add(user);
}
return users;
}
}

下载结果:

4、提供一个供外部调用读取Excel的接口

首先需要写一个监听器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package com.hgl.listener;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.hgl.entity.UserEntity;

/**
* 1、注意监听器不能由spring容器管理,每次调用时都需要手动new
* 2、监听器内部需要使用ioc中的bean时,可以通过构造方法传入
*
* @author guilin
*
*/
public class UserListener extends AnalysisEventListener<UserEntity>{

private List<UserEntity> data = Lists.newArrayList();

private static final Logger LOGGER = LoggerFactory.getLogger(UserListener.class);

/**
* 解析每条数据时都会调用
*/
@Override
public void invoke(UserEntity user, AnalysisContext context) {
data.add(user);
}

/**
* 所有数据解析完之后调用
*/
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
// 可以在此处执行业务操作
// 本例就打印到控制台即可,表示读取完成
LOGGER.info(JSON.toJSONString(data));
}

}

读取方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.hgl.controller;

import java.io.IOException;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.excel.EasyExcel;
import com.hgl.entity.UserEntity;
import com.hgl.listener.UserListener;

@RestController
@RequestMapping("/excel")
public class ExcelReadController {

/**
* 测试读取Excel文件
*
* @param file
* @return String
*/
@PostMapping("/read")
public String doDownLoad(MultipartFile file) throws IOException {
EasyExcel.read(file.getInputStream(), UserEntity.class, new UserListener()).sheet().doRead();
return "success";
}
}

使用postman测试读数据:

成功读到数据:

三、收尾

这篇文章提供了最简单的使用EasyExcel进行读写操作的例子,更多使用方法请参考官方文档或开源社区。

附上官方文档地址:https://alibaba-easyexcel.github.io/

GitHub开源地址:https://github.com/alibaba/easyexcel

查看评论