@excel注解_惊了!如何通过阿里 EasyExcel 7 行代码, 优雅地实现 Excel 文件导出功能?...
目錄
一、前言
二、Apache poi、jxl 的缺陷
三、阿里出品的 EasyExcel,安利一波
四、EasyExcel 解決了什么
五、快速上手
六、特殊場(chǎng)景支持
七、Web 下載示例代碼
八、需要注意的點(diǎn)
九、總結(jié)
一、前言
關(guān)于導(dǎo)出 Excel 文件,可以說(shuō)是大多數(shù)服務(wù)中都需要集成的功能。那么,要如何優(yōu)雅快速地(偷懶地)去實(shí)現(xiàn)這個(gè)功能呢?
你可能第一想法是:這還不簡(jiǎn)單?用 Apache 開(kāi)源框架 poi, 或者 jxl 都可以實(shí)現(xiàn)啊。面向百度編程,把代碼模板 copy 下來(lái),根據(jù)自己的業(yè)務(wù)再改改,能有多難?
嗯.. 的確不難,但是你的代碼可能是下面這個(gè)熊樣子的:
上面這段代碼看上去是不是又臭又長(zhǎng)呢?今天,小哈將教您如何使用 7 行代碼搞定 Excel 文件生成功能!
二、Apache poi、jxl 的缺陷
在說(shuō)如何實(shí)現(xiàn)之前,我們先來(lái)討論一下傳統(tǒng) Excel 框架的不足!除了上面說(shuō)的,Apache poi、jxl 都存在生成 excel 文件不夠簡(jiǎn)單優(yōu)雅快速外,它們都還存在一個(gè)嚴(yán)重的問(wèn)題,那就是非常耗內(nèi)存,嚴(yán)重時(shí)會(huì)導(dǎo)致內(nèi)存溢出。
POI 雖然目前來(lái)說(shuō),是 excel 解析框架中被使用最廣泛的,但這個(gè)框架并不完美。
為什么這么說(shuō)呢?
開(kāi)發(fā)者們大部分使用 POI,都是使用其 userModel 模式。而 userModel 的好處是上手容易使用簡(jiǎn)單,隨便拷貝個(gè)代碼跑一下,剩下就是寫(xiě)業(yè)務(wù)轉(zhuǎn)換了,雖然轉(zhuǎn)換也要寫(xiě)上百行代碼,但是還是可控的。
然而 userModel 模式最大的問(wèn)題是在于,對(duì)內(nèi)存消耗非常大,一個(gè)幾兆的文件解析甚至要用掉上百兆的內(nèi)存。現(xiàn)實(shí)情況是,很多應(yīng)用現(xiàn)在都在采用這種模式,之所以還正常在跑是因?yàn)椴l(fā)不大,并發(fā)上來(lái)后,一定會(huì)OOM或者頻繁的 full gc。
三、阿里出品的 EasyExcel,安利一波
什么是 EasyExcel? 見(jiàn)名知意,就是讓你操作 Excel 異常的酸爽。先來(lái)看下 EasyExcel GitHub 官方截圖:
截止目前為止已有 5519 Star, 官方對(duì)其的簡(jiǎn)介是:
快速、簡(jiǎn)單避免OOM的java處理Excel工具!
以下是官方介紹:
四、EasyExcel 解決了什么
主要來(lái)說(shuō),有以下幾點(diǎn):
傳統(tǒng) Excel 框架,如 Apache poi、jxl 都存在內(nèi)存溢出的問(wèn)題;
傳統(tǒng) excel 開(kāi)源框架使用復(fù)雜、繁瑣;
EasyExcel 底層還是使用了 poi, 但是做了很多優(yōu)化,如修復(fù)了并發(fā)情況下的一些 bug, 具體修復(fù)細(xì)節(jié),可閱讀官方文檔https://github.com/alibaba/easyexcel;
五、快速上手
5.1 添加依賴
com.alibaba
easyexcel
1.1.2-beta5
5.2 七行代碼搞定 Excel 生成
上面這段示例代碼中,有兩個(gè)點(diǎn)很重要,小哈已經(jīng)重點(diǎn)標(biāo)注標(biāo):
①:WriteModel 這個(gè)對(duì)象就是要寫(xiě)入 Excel 的數(shù)據(jù)模型對(duì)象,等等,你這好像不行吧?表頭 head,以及每個(gè)單元格內(nèi)的數(shù)據(jù)順序都沒(méi)指定,能達(dá)到想要的效果么?別急,后面會(huì)討論這塊!
②:創(chuàng)建需要寫(xiě)入的數(shù)據(jù)集,當(dāng)然了,正常業(yè)務(wù)中,這塊都是從數(shù)據(jù)庫(kù)中查詢出來(lái)的。
PS: 如果說(shuō)寫(xiě)入的數(shù)據(jù)量很大,需要做分片查詢?cè)賹?xiě)入的處理,否則可能會(huì) OOM(Out of Memory).
回過(guò)頭來(lái),我們來(lái)看看 WriteModel 這個(gè)對(duì)象內(nèi)部到底有什么幺蛾子!
ExayExcel 提供注解的方式, 來(lái)方便的定義 Excel 需要的數(shù)據(jù)模型:
①:首先,定義的寫(xiě)入模型必須要繼承自?BaseRowModel.java;
②:通過(guò)?@ExcelProperty?注解來(lái)指定每個(gè)字段的列名稱,以及下標(biāo)位置;
同時(shí),上面定義的 createModelList() 方法也很簡(jiǎn)單,通過(guò)循環(huán),創(chuàng)建一個(gè)寫(xiě)入模型的 List 集合:
廢話不多說(shuō),這個(gè)快速接入的案例也介紹的差不多了,跑一跑單元測(cè)試看下實(shí)際效果:
怎么樣,效果還是挺棒棒的!
六、特殊場(chǎng)景支持
在實(shí)際的業(yè)務(wù)中,我們還會(huì)有一些特需的需求,比如說(shuō)下面這些。
6.1 動(dòng)態(tài)生成 Excel 內(nèi)容
上面的例子是基于注解的,也就是說(shuō)表頭 head, 以及內(nèi)容都是寫(xiě)死的,換句話說(shuō),我定義好了一個(gè)數(shù)據(jù)模型,那么,生成的 Excel 文件也就是只能遵循這種模型來(lái)了,但是,實(shí)際業(yè)務(wù)中可能會(huì)存在動(dòng)態(tài)變化的需求,要怎么做呢?
①:無(wú)注解模式,動(dòng)態(tài)添加表頭,也可自由組合復(fù)雜表頭,代碼如下:
②:創(chuàng)建動(dòng)態(tài)數(shù)據(jù),注意這里的數(shù)據(jù)類型是?Object:
跑一下單元測(cè)試,看下效果:
6.2 自定義表頭以及內(nèi)容樣式
我想自定義表頭,內(nèi)容樣式,咋辦?
我們復(fù)用了上面的示例代碼,并額外添加了設(shè)置自定義表格樣式的代碼, createTableStytle()具體內(nèi)容如下:
我們可以通過(guò) TableStyle 這個(gè)類來(lái)設(shè)置表頭、表格主題的樣式。
6.3 合并單元格
我們可以通過(guò) merge() 方法來(lái)合并單元格:
注意下標(biāo)是從 0 開(kāi)始的,也就是說(shuō)合并了第六行到第七行,其中的第一列到第五列,跑下代碼,看下效果:
6.4 自定義處理
對(duì)于更復(fù)雜的處理,EasyExcel 預(yù)留了 WriterHandler 接口來(lái),允許你自定義處理代碼:
接口中定義了三個(gè)方法:
sheet(): 在創(chuàng)建每個(gè) sheet 后自定義業(yè)務(wù)邏輯處理;
row(): 在創(chuàng)建每個(gè) row 后自定義業(yè)務(wù)邏輯處理;
cell(): 在創(chuàng)建每個(gè) cell 后自定義業(yè)務(wù)邏輯處理;
我們實(shí)現(xiàn)了該接口后,編寫(xiě)自定義邏輯處理代碼,然后調(diào)用 getWriterWithTempAndHandler()靜態(tài)方法獲取 ExcelWriter 對(duì)象時(shí),傳入 WriterHandler 的實(shí)現(xiàn)類即可。
比如下面的示例代碼:
ExcelWriter writer = EasyExcelFactory.getWriterWithTempAndHandler(null, out, ExcelTypeEnum.XLSX, true, new MyWriterHandler());
七、Web 下載示例代碼
public class Down {
@GetMapping("/a.htm")
public void cooperation(HttpServletRequest request, HttpServletResponse response) {
ServletOutputStream out = response.getOutputStream();
ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX, true);
String fileName = new String(("UserInfo " + new SimpleDateFormat("yyyy-MM-dd").format(new Date()))
.getBytes(), "UTF-8");
Sheet sheet1 = new Sheet(1, 0);
sheet1.setSheetName("第一個(gè)sheet");
writer.write0(getListString(), sheet1);
writer.finish();
response.setContentType("multipart/form-data");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-disposition", "attachment;filename="+fileName+".xlsx");
out.flush();
}
}
八、需要注意的點(diǎn)
8.1 寫(xiě)入大數(shù)據(jù)時(shí),需分片
比如說(shuō),我們需要從數(shù)據(jù)庫(kù)中查詢出數(shù)據(jù)量較大時(shí),我們需要在業(yè)務(wù)層做分片處理,也就是,我們需要分多次查詢,再寫(xiě)入,防止內(nèi)存溢出 OOM.
8.2 Excel 最大行數(shù)問(wèn)題
Excel 03, 07 版本均有行數(shù)、列數(shù)的限制:
| Excel 2003 | 65536 | 256 |
| Excel 2007 | 1048576 | 16384 |
csv 由于是文本文件,實(shí)際上沒(méi)有最大行數(shù)的限制,但是用 Excel 客戶端打開(kāi)還是多了不顯示。
也就是說(shuō),如果你想寫(xiě)入更多的行數(shù)是不行的,強(qiáng)行這么做,程序會(huì)報(bào)類似如下異常
Invalid row number (1048576) outside allowable range (0..1048575)
如何解決呢?
分多個(gè) Excel 文件寫(xiě)入;
同一個(gè) Excel 文件,分多個(gè) Sheet 寫(xiě)入;
九、總結(jié)
小哈今天主要給小伙伴介紹了 EasyExcel, 為什么要使用它,以及演示了相關(guān)示例代碼。當(dāng)然了,EasyExcel 除了寫(xiě) Excel 文件外,它還有快速讀取 Excel 的功能,由于本文主要介紹的是:如何優(yōu)雅地實(shí)現(xiàn) Excel 文件生成,所以就沒(méi)有介紹了,有興趣的小伙伴們,也可以去 GitHub 官網(wǎng)去去查看相關(guān)文檔。
最后,祝您看完本文后有所收獲,下期見(jiàn)!
十、GitHub 源碼地址
https://github.com/weiwosuoai/spring-boot-tutorial/tree/master/spring-boot-excel
十一、Ref
https://github.com/alibaba/easyexcel
推薦閱讀
???求求你們了,別再寫(xiě)滿屏的 try catch 了!!???前、后端分離權(quán)限控制設(shè)計(jì)和實(shí)現(xiàn)思路???自從用完Gradle后,有點(diǎn)嫌棄Maven了!速度賊快!???淺析 VO、DTO、DO、PO 的概念、區(qū)別和用處!
最近面試BATJ,整理一份面試資料《Java面試BAT通關(guān)手冊(cè)》,覆蓋了Java核心技術(shù)、JVM、Java并發(fā)、SSM、微服務(wù)、數(shù)據(jù)庫(kù)、數(shù)據(jù)結(jié)構(gòu)等等。
獲取方式:點(diǎn)“在看”,關(guān)注公眾號(hào)并回復(fù)?Java?領(lǐng)取,更多內(nèi)容陸續(xù)奉上。
文章有幫助的話,在看,轉(zhuǎn)發(fā)吧。
謝謝支持喲 (*^__^*)
總結(jié)
以上是生活随笔為你收集整理的@excel注解_惊了!如何通过阿里 EasyExcel 7 行代码, 优雅地实现 Excel 文件导出功能?...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 鄞州银行属于什么银行
- 下一篇: 民众国际期货开户流程