easyExcel 使用指南详解
來源:easyExcel 使用指南詳解 - 知乎
easyExcel簡介
Java領域解析、生成Excel比較有名的框架有Apache poi、jxl等。但他們都存在一個嚴重的問題就是非常的耗內存。如果你的系統并發量不大的話可能還行,但是一旦并發上來后一定會OOM或者JVM頻繁的full gc。
easyExcel是阿里巴巴開源的一個excel處理框架,以使用簡單、節省內存著稱。
64M內存1分鐘內讀取75M(46W行25列)的Excel(當然還有急速模式能更快,但是內存占用會在100M多一點)
easyExcel能大大減少占用內存的主要原因是在解析Excel時沒有將文件數據一次性全部加載到內存中,而是從磁盤上一行行讀取數據,逐個解析。
下圖是easyExcel和POI在解析Excel時的對比圖。?
easyExcel采用一行一行的解析模式,并將一行的解析結果以觀察者的模式通知處理(AnalysisEventListener)。
上面簡要介紹了easyExcel的特點和原理,關于easyExcel的其他問題可以先參考下這個文章。下面就通過代碼來介紹下怎么使用easyExcel。
快速使用指南
文件上傳讀取Excel
下面通過一個讀取用戶信息的列子來展示下怎么使用easyExcel。
step1:創建用戶信息類
@Data public class UserInfo extends BaseRowModel {@ExcelProperty(index = 0)private String name;@ExcelProperty(index = 1)private int age;@ExcelProperty(index = 2)private String address;}step2:創建AnalysisEventListener子類
/*** 每解析一行會回調invoke()方法。* 整個excel解析結束會執行doAfterAllAnalysed()方法*///有個很重要的點 不能被spring管理,要每次讀取excel都要new。 //這邊就會有一個問題:如果UserInfoDataListener中需要用到Spring中的主鍵怎么辦? public class UserInfoDataListener extends AnalysisEventListener<UserInfo> {Logger logger = LoggerFactory.getLogger(UserInfoDataListener.class);//每次讀取100條數據就進行保存操作private static final int BATCH_COUNT = 100;//由于每次讀都是新new UserInfoDataListener的,所以這個list不會存在線程安全問題List<UserInfo> list = new ArrayList<>();//這個組件是Spring中的組件,這邊推薦兩種方法注入這個組件//第一種就是提供一個UserInfoDataListener的構造方法,這個方法提供一個參數是UserInfoDataListener類型//另外一種方法就是將 UserInfoDataListener 這個類定義成 UserService 實現類的內部類(推薦這種方式)//private UserService userService;@Overridepublic void invoke(UserInfo data, AnalysisContext analysisContext) {logger.info("解析到一條數據:{}", JSON.toJSONString(data));list.add(data);if (list.size() >= BATCH_COUNT) {saveData();// 存儲完成清理 listlist.clear();}}@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {// 這里也要保存數據,確保最后遺留的數據也存儲到數據庫saveData();logger.info("所有數據解析完成!");}private void saveData() {logger.info("{}條數據,開始存儲數據庫!", list.size());//保存數據//userService.save(list);logger.info("存儲數據庫成功!");}}step3: 讀取excel
public class EasyExcelDemo {public static void main(String[] args) throws Exception {InputStream fis = new FileInputStream("D:\\UserInfo.xlsx");AnalysisEventListener listener = new UserInfoDataListener();ExcelReader excelReader = EasyExcel.read(fis, UserInfo.class, listener).build();ReadSheet readSheet = EasyExcel.readSheet(0).build();ReadSheet readSheet2 = EasyExcel.readSheet(1).build();excelReader.read(readSheet);// 這里千萬別忘記關閉,讀的時候會創建臨時文件,到時磁盤會崩的excelReader.finish();}}只需要上面3步就能進行Excel的讀取了。
文件下載Excel
public class ExcelUtil {public static OutputStream getOutputStream(String fileName, HttpServletResponse response)throws Exception{try{fileName = URLEncoder.encode(fileName,"utf-8");response.setContentType("application/vnd.ms-excel");response.setCharacterEncoding("utf-8");//此處指定了文件類型為xls,如果是xlsx的,請自行替換修改response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".xls");response.setHeader("Pragma", "public");response.setHeader("Cache-Control", "no-store");response.addHeader("Cache-Control", "max-age=0");return response.getOutputStream();} catch (IOException e){throw new Exception("導出文件失敗!");}}public static void writeExcel(HttpServletResponse response, List<? extends BaseRowModel> list, String fileName,String sheetName, Class clazz) throws Exception {ExcelWriter writer = new ExcelWriter(getOutputStream(fileName, response), ExcelTypeEnum.XLS);Sheet sheet = new Sheet(1, 0, clazz);sheet.setSheetName(sheetName);writer.write(list, sheet);writer.finish();}}在Controller中我們只要像下面這種方式調用就行了。
@RequestMapping(value = "/file/testExcelDownload")public void testExcelDownload(HttpServletRequest request,HttpServletResponse response){//以下信息從數據庫中查出List<ExcelInfo> excelInfos = new ArrayList<>();ExcelInfo info1 = new ExcelInfo();ExcelInfo info2 = new ExcelInfo();excelInfos.add(info1);excelInfos.add(info2);info1.setIssuerName("name1");info1.setRiskLevel("level1");info2.setIssuerName("name1");info2.setRiskLevel("level1");try {String fileName = "excelInfo";String sheetName = "sheet1";ExcelUtil.writeExcel(response, excelInfos, fileName, sheetName, ExcelInfo.class);} catch(Exception e){log.error("模板下載失敗",e);}}在導出Excel的部分,easyExcel還提供了自定義樣式,插入表格,插入圖片等其他功能,還有一個比較有意思的功能就是Excel模板填充的功能。詳細的功能信息參考官方文檔。
總結
以上是生活随笔為你收集整理的easyExcel 使用指南详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 利用 Celery 构建 Web 服务的
- 下一篇: Python操作MSSQL