一、前言
用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 implements Serializable { private static final long serialVersionUID = 1L; /** * id */ @ExcelProperty(value = "ID",index = 0) private Integer id; /** * 英文 */ @ExcelProperty(value = "英文",index = 1) private String english; /** * 漢語 */ @ExcelProperty(value = "漢語",index = 2) private String chinese; /** * 作者(登錄人) */ @ExcelProperty(value = "作者",index = 3) private String author; /** * 發布時間 */ @ExcelProperty(value = "發布時間",index = 4) private Date commitTime; /** * 點贊數量 */ @ExcelProperty(value = "點贊數量",index = 5) private Integer 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 = new FileOutputStream(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表格的數據 * * @param word List<Word> * @return List<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); } return wList; }
4、效果
5、在瀏覽器中彈出下載文件
彈出文件不用用Ajax的方式發送請求,需要用XMLHttpRequest的方式
前端發送請求示例:
let url = config.base_server + 'api-paper/question/exportQuestion?access_token=' + config.getToken().access_token; let xhr = new XMLHttpRequest(); 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();