最近这不又接到一个需求,上游用户想要下载上报给咱们的列表数据,用来进行一些简略的线下剖析。
用户的需求有必要满足啊!所以我就吭哧吭哧的找到俺的chrome大哥,立即所搜”springboot下载json数据“的模板代码,试图经过CV大法快速实现用户需求。
后来转念一想,用户想要的仅是列表数据,假如下载一个json数据还要让用户进行预处理才能进行剖析,体验也太不友好了,所以决定直接下载一个Excel文件。
Excel文件下载没搞过啊,chrome大哥又得靠你了。
最先找到是apache-poi,这个就有点吊了,经过该lib,咱们能够运用Java读写Microsoft Office文档,这不便是用Java写Word、PPT啥的么。了解该lib的基础功用后,我去找了下”经过apache poi读写excel“的模板代码。好家伙!!!暂且不说性能怎么样,这一个一个单元格的操作办法就能够累死人,虽然说操作的细致程度十分高。但是对我来说仅是想要一个api能够将List数据转化成Excel就行了,越简略越好。
造轮子的事情作业之外能够做,作业内仍是要功率第一。
后边就碰到了EasyExcel,发现用起来真的十分便利。所以便想写一篇小文章记载下整个集成过程,也便利后续查阅。
1、搭建springboot web工程
这个相信各位老司机都驾轻就熟了,这儿也不过多叙说了,实在不可IDEA的Spring Initializr也是十分好用的工具。
2、引进EasyExcel的依赖包
这儿我运用的是3.1.3的版别,读者能够运用最新的版别哈。
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.1.3</version>
</dependency>
3、下载Excel
首先咱们预备一个十分简略的bean,作为列表的元数据。
该bean有三个字段,自然而然,终究生成的Excel也将有三列,分别对应这三个字段。
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
private int age;
private String name;
private String address;
}
接下来写下载接口,顶层的RequestMapping
这儿仅写一次,咱们知道后边的接口途径都有/easyexcel
前缀就行了。
核心是download接口,该接口逻辑首要分三步:
- 预备数据。这儿只需预备一个List格局的数据就行,元数据就用咱们上面的bean即可。读者能够依据自己的业务需要进行调整。
- 设置呼应。这儿咱们要将呼应数据设置为excel格局。
- 写入数据。这个便是Easyexcle十分棒的地方,它供给了十分简洁的API供用户运用,只需要一行代码就能够将List列表转化为Excel文件。write办法指定输出流和写入数据的class目标;sheet办法指定excel的sheet名称;doWrite则指定写入的列表数据。
@RestController
@RequestMapping("/easyexcel")
public class EasyexcelController {
@GetMapping("/download")
public void download(HttpServletResponse response) {
try {
// 预备数据
List<Student> studentList = new ArrayList<>(10);
for (int i = 0; i < 10; i++) {
Student s = new Student();
s.setAge(i * 10 + 1);
s.setName("name" + i);
s.setAddress("address" + i);
studentList.add(s);
}
// 设置呼应
response.setContentType("application/vnd.excel");
response.setCharacterEncoding("utf-8");
String fileName = URLEncoder.encode("file", "UTF-8").replaceAll("\+", "%20");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
// 写入数据
EasyExcel.write(response.getOutputStream(), Student.class).sheet("sheet1").doWrite(studentList);
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行使用,在浏览器网址栏输入http://localhost:8080/easyexcel/download,即可看到文件已经被下载下来啦。
打开文件看下,内容便是上面生成的列表数据。
4、读取Excel
咱们先来写一个最简略的读接口。
依旧在上面的EasyexcelController
,咱们添加如下读接口:
@GetMapping("/read")
public void readExcel() {
// 这儿换成你们的excel文件途径
File file = new File("FilePath");
EasyExcel.read(file, Student.class, new ReadListener<Student>() {
@Override
public void invoke(Student s, AnalysisContext analysisContext) {
System.out.println(s);
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
System.out.println("read finished");
}
}).sheet("sheet1").doRead();
}
履行结果如下所示:
最最最简略的读接口能够看到代码量十分的少,首要便是下面几步:
- 构造文件目标File。EasyExcel供给的API十分丰富,咱们能够构造一个File目标,也能够经过文件途径直接读取;
- 调用
EasyExcel.read()
函数读取文件。这儿咱们需要指定文件file,指定反序列化的类目标以及一个监听器。上面咱们直接运用匿名内部类的方式创建了ReadListener
监听器。该监听器的invoke
办法会在读取完Excel的每一行记载时调用一次,doAfterAllAnalysed
办法会在读取完悉数数据后调用一次。EasyExcel这么规划的目的是:一些Excel的内容十分多,几千上万行。假如把数据悉数读取到内存中,机器必定吃不消。因此规划了invoke
办法,每次读取完一行记载回调一次,咱们能够在这儿进行一些定制化操作,比方每读取100行就将数据耐久化到数据库中,然后清空内存再读取下100条数据。doAfterAllAnalysed
办法则能够终究兜底,处理最后未耐久化的数据。
耐久化的代码如下所示:
@GetMapping("/read")
public void readExcel() {
// 这儿换成你们的excel文件途径
File file = new File("FilePath");
EasyExcel.read(file, Student.class, new ReadListener<Student>() {
public static final int CACHE_SIZE = 100;
private List<Student> cached = new ArrayList<>(CACHE_SIZE);
@Override
public void invoke(Student s, AnalysisContext analysisContext) {
cached.add(s);
if (cached.size() >= CACHE_SIZE) {
saveData();
cached = new ArrayList<>(CACHE_SIZE);
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
saveData();
}
}).sheet("sheet1").doRead();
}
5、上传Excel
最简略的上传接口如下所示:
@GetMapping("/upload")
public void upload(MultipartFile file) {
try {
EasyExcel.read(file.getInputStream(), Student.class, new ReadListener<Student>() {
@Override
public void invoke(Student s, AnalysisContext analysisContext) {
System.out.println(s);
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
System.out.println("read finished");
}
}).sheet("sheet1").doRead();
} catch (Exception e) {
e.printStackTrace();
}
}
能够看出写法上和读取Excel接口十分类似,只不过咱们经过web的方式接收了Excel文件而已。
该接口的请求结果如下所示:
6、写入Excel
写Excel和下载Excel也十分类似,只不过一个是写入文件傍边,一个是写入到网络流傍边。
咱们就用上面的Excel为例,向其中写入一个Student(age=101, name=name10, address=address10)
。
写入的代码如下:
@PostMapping("/write")
public void write(@RequestBody Student student) {
// 你的文件途径
File file = new File("FilePath");
EasyExcel.write(file, Student.class).sheet("sheet1").doWrite(Collections.singleton(student));
// 写入成功后,咱们尝试读取下文件
EasyExcel.read(file, Student.class, new ReadListener<Student>() {
@Override
public void invoke(Student s, AnalysisContext analysisContext) {
System.out.println(s);
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
System.out.println("read finished");
}
}).sheet("sheet1").doRead();
}
接口运行结果如下所示,能够看到咱们成功写入了数据。
7、总结
从上面的4个接口来看,EasyExcel确实为咱们供给了十分简略的API来操作Excel文件,咱们仅需少数代码便能够实现强壮的功用。
当然,EasyExcel的功用远不止这些,还包括“多sheet读取”、“读表头”、“数据转换”等功用,本篇文章仅是介绍了最常用的功用,咱们假如有特别需求的话,能够参考EasyExcel的官方文档 easyexcel.opensource.alibaba.com/docs/curren… ,去探索更多或许哈。