SpringBoot集成EasyExcel实现Excel下载
一、背景
为什么会用Easyexcel来做Excel下载
项目中的Excel导入功能刚做好,领导又来了:这次要导出功能。我导入才刚整明白呢,你又来了。但是没有办法,领导才是衣食父母嘛,只有干了。
阿里巴巴语雀团队对EasyExcel是这样介绍的
- 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模式。在上层做了模型转换的封装,让使用者更加简单方便。
- 当然还有急速模式能更快,但是内存占用会在100M多一点
- 这篇文章很多地方都与上传的文章相同,只是controller有所变动,因为是同一个框架嘛。
二、集成EasyExcel
1、 在pom.xml中添加EasyExcel依赖
<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.1.3</version></dependency>
2、创建EasyExcel映射实体类
import com.alibaba.excel.annotation.ExcelProperty;public class ExcelEntity {// ExcelProperty中的参数要对应Excel中的标题@ExcelProperty("ID")private int ID;@ExcelProperty("NAME")private String name;@ExcelProperty("AGE")private int age;public ExcelEntity() {}public ExcelEntity(int ID, String name, int age) {this.ID = ID;this.name = name;this.age = age;}public int getID() {return ID;}public void setID(int ID) {this.ID = ID;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}
3、创建controller
- 这里必须设置setContentType以及setHeader两个东西,否则下载出来的文件会有问题。
import com.alibaba.excel.EasyExcel;import com.alibaba.excel.ExcelReader;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.web.bind.annotation.*;import org.springframework.web.multipart.MultipartFile;import java.io.IOException;import java.io.InputStream;import java.util.List;@RestController@CrossOrigin@RequestMapping("/loggerItem")public class LoggerItemController {@GetMapping("/download")public void downLoad(HttpServletResponse response){// 设置响应类型为excelresponse.setContentType("application/vnd.ms-excel");/** 设置响应头以及文件名称* Content-disposition 是 MIME 协议的扩展,MIME 协议指示 MIME 用户代理如何显示附加的文件。* 浏览器接收到头时,它会激活文件下载对话框* attachment 附件* filename 附件名*/response.setHeader("Content-Disposition", "attachment;filename=aaa.xlsx");try {// 从HttpServletResponse中获取OutputStream输出流ServletOutputStream outputStream = response.getOutputStream();/** EasyExcel 有多个不同的read方法,适用于多种需求* 这里调用EasyExcel中通过OutputStream流方式输出Excel的write方法* 它会返回一个ExcelWriterBuilder类型的返回值* ExcelWriterBuilde中有一个doWrite方法,会输出数据到设置的Sheet中*/EasyExcel.write(outputStream,ExcelEntity.class).sheet("测试数据").doWrite(UploadExcelListener.list);} catch (IOException e) {e.printStackTrace();}}}
5、application.yml配置
这里的文件上传大小,如果单做导出的话可以不用配,由于我这里需要上传数据进行测试,所以进行了配置
server:# 指定端口号port: 8080spring:servlet:multipart:# 配置单个上传文件大小file-size-threshold: 100Mb# 配置总上传大小max-request-size: 300M
6、测试
我们先搞一个简单的Excel,上传上去用来测试

然后通过Postman模拟发送上传请求,上传测试文件
- 选择Post请求并输入请求地址
- 在下面选择Body
- Key的框中输入controller中的请求的方法中的参数,后面的下拉框中选择File
- VALUE框中有一个Select File ,点击后选择自己刚才创建的测试的Excel
- 最后点击Send发送请求

然后在浏览器中发送下载请求


成功下载。
三、EasyExcel中的write方法汇总
/*** Build excel the write** @return*/public static ExcelWriterBuilder write() {return new ExcelWriterBuilder();}/*** Build excel the write** @param file* File to write* @return Excel writer builder*/public static ExcelWriterBuilder write(File file) {return write(file, null);}/*** Build excel the write** @param file* File to write* @param head* Annotate the class for configuration information* @return Excel writer builder*/public static ExcelWriterBuilder write(File file, Class head) {ExcelWriterBuilder excelWriterBuilder = new ExcelWriterBuilder();excelWriterBuilder.file(file);if (head != null) {excelWriterBuilder.head(head);}return excelWriterBuilder;}/*** Build excel the write** @param pathName* File path to write* @return Excel writer builder*/public static ExcelWriterBuilder write(String pathName) {return write(pathName, null);}/*** Build excel the write** @param pathName* File path to write* @param head* Annotate the class for configuration information* @return Excel writer builder*/public static ExcelWriterBuilder write(String pathName, Class head) {ExcelWriterBuilder excelWriterBuilder = new ExcelWriterBuilder();excelWriterBuilder.file(pathName);if (head != null) {excelWriterBuilder.head(head);}return excelWriterBuilder;}/*** Build excel the write** @param outputStream* Output stream to write* @return Excel writer builder*/public static ExcelWriterBuilder write(OutputStream outputStream) {return write(outputStream, null);}/*** Build excel the write** @param outputStream* Output stream to write* @param head* Annotate the class for configuration information.* @return Excel writer builder*/public static ExcelWriterBuilder write(OutputStream outputStream, Class head) {ExcelWriterBuilder excelWriterBuilder = new ExcelWriterBuilder();excelWriterBuilder.file(outputStream);if (head != null) {excelWriterBuilder.head(head);}return excelWriterBuilder;}
所有的方法都在这儿了,其实如果看不懂到底应该调用哪一个write方法的话,可以以根据自己所能得到的参数来判断。
四、扩展
- 导出到本地Excel
public static void main(String[] args) {EasyExcel.write("C:/Users/Lonely Programmer/Desktop/输出文件名.xlsx",ExcelEntity.class).sheet("测试数据").doWrite(UploadExcelListener.list);}
输出本地的Excel和通过OutputStream流输出的方式是一样的,只是参数变了,原本传的是OutputStream流,现在传的是文件的绝对路径。
平时上班比较忙,操作过程中如果遇到什么问题,可以评论提问,我看到了的话,有时间基本上都会回复的(前提是我会,哈哈哈)。
