一、前言
用java代码在后台实现导出excel表格可以说是很多服务器都需要集成的功能,实现的方法有Apache 开源框架 poi, 或者 jxl 都可以实现,但是Apache poi、jxl 都存在一个严重的问题,那就是非常耗内存,严重时会导致内存溢出。
所以这里可以用另一种方法,就是阿里出品的easyExcel,它主要解决了以下几点问题:
- 传统 Excel 框架,如 Apache poi、jxl 都存在内存溢出的问题;
- 传统 excel 开源框架使用复杂、繁琐;
EasyExcel 底层还是使用了 poi, 但是做了很多优化,如修复了并发情况下的一些 bug, 具体修复细节,可阅读官方文档https://github.com/alibaba/easyexcel
二、代码实现
1、向pom文件添加依赖
<!--导出Excel需要包--> <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>1.1.2-beta5</version> </dependency>
2、model
类继承baseRowModel
属性字段上添加@ExcelProperty
value --标题
index --索引
@Data @Builder @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode(callSuper = true) public class WordExcelVo extends BaseRowModel implementsSerializable { private static final long serialVersionUID = 1L; /*** id */@ExcelProperty(value = "ID",index = 0) privateInteger id; /*** 英文 */@ExcelProperty(value = "英文",index = 1) privateString english; /*** 汉语 */@ExcelProperty(value = "汉语",index = 2) privateString chinese; /*** 作者(登录人) */@ExcelProperty(value = "作者",index = 3) privateString author; /*** 发布时间 */@ExcelProperty(value = "发布时间",index = 4) privateDate commitTime; /*** 点赞数量 */@ExcelProperty(value = "点赞数量",index = 5) privateInteger number; }
3、导出主要代码
@Override public void exportExcel(List<Word>word, HttpServletResponse response) { try{ String path =CommonPath.WORD_EXCEL_PATH.getValue(); String fileName = System.currentTimeMillis() + ".xlsx"; //创建文件 File file = new File(path +fileName); OutputStream outputStream = newFileOutputStream(file); ExcelWriter writer =EasyExcelFactory.getWriter(outputStream); //只生成一个sheet Sheet sheet = new Sheet(1, 0, WordExcelVo.class); sheet.setSheetName("我的收藏"); //写数据 writer.write(writeWord(word), sheet); writer.finish(); outputStream.close(); } catch(IOException e) { e.printStackTrace(); } }
/*** 赋值excel表格的数据 * * @paramword List<Word> * @returnList<WordExcelVo> */ private List<WordExcelVo> writeWord(List<Word>word) { List<WordExcelVo> wList = new ArrayList<>(); for(Word aWord : word) { WordExcelVo wordExcelVo =WordExcelVo.builder() .id(aWord.getId()) .chinese(aWord.getChinese()) .english(aWord.getEnglish()) .author(aWord.getAuthor()) .commitTime(aWord.getCommitTime()) .number(aWord.getNumber()) .build(); wList.add(wordExcelVo); } returnwList; }
4、效果
5、在浏览器中弹出下载文件
弹出文件不用用Ajax的方式发送请求,需要用XMLHttpRequest的方式
前端发送请求示例:
let url = config.base_server + 'api-paper/question/exportQuestion?access_token=' +config.getToken().access_token; let xhr = newXMLHttpRequest(); xhr.open('POST', url, true); xhr.responseType = "blob"; xhr.setRequestHeader("client_type", "DESKTOP_WEB"); xhr.onload = function() { if (this.status === 200) { let blob = this.response; window.location.href =URL.createObjectURL(blob); } }; xhr.send();
后端代码也设置响应头等信息:
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-disposition", "attachment;filename=" + 文件名+ ".xls");
response.getOutputStream();