操作MS Execl電子表格的常用JAR包

點(diǎn)擊上方「藍(lán)字」關(guān)注我們

在做報(bào)表開發(fā)時(shí),免不了要導(dǎo)出數(shù)據(jù)。除了簡(jiǎn)單的循環(huán)列表數(shù)據(jù)導(dǎo)出外,還有基于模板的數(shù)據(jù)導(dǎo)出。比如生成運(yùn)營(yíng)周報(bào)或者月報(bào)之類的,甚是符合使用模板導(dǎo)出方式。今天總結(jié)一些常用的Execl導(dǎo)出JAR包。
0x01:jxl
支持Excel 95-2000的所有版本;生成Excel 2000標(biāo)準(zhǔn)格式;支持字體、數(shù)字、日期操作;能夠修飾單元格屬性;支持圖像和圖表。
jxl是純Java的,不依賴Windows系統(tǒng),即使運(yùn)行在Linux下,它同樣能夠正確的處理Excel文件。另外需要說明的是,jxl對(duì)圖形和圖表的支持很有限,而且僅僅識(shí)別PNG格式。
官網(wǎng)
http://jexcelapi.sourceforge.net/
倉(cāng)庫(kù)地址
https://mvnrepository.com/artifact/net.sourceforge.jexcelapi/jxl
備注,jxl已經(jīng)有點(diǎn)過期了。已經(jīng)很久沒有更新了,可以說已經(jīng)沒有維護(hù)了。
0x02:Apache POI
Apache POI是Apache軟件基金會(huì)的開放源碼函式庫(kù),POI提供API給Java程序?qū)icrosoft Office格式檔案讀和寫的功能。最主要功能如下:
HSSF - 提供讀寫Microsoft Excel格式檔案的功能
XSSF - 提供讀寫Microsoft Excel OOXML格式檔案的功能
HWPF - 提供讀寫Microsoft Word格式檔案的功能
HSLF - 提供讀寫Microsoft PowerPoint格式檔案的功能
HDGF - 提供讀寫Microsoft Visio格式檔案的功能
Apache POI功能非常強(qiáng)大,可以解決幾乎所有日常開發(fā)中遇到需要使用Execl的問題。但是在解決一些問題是需要開發(fā)人員編寫大量的代碼。
官網(wǎng):
https://poi.apache.org/

0x03:easypoi
easypoi的功能如同名字easy,主打的功能就是容易,讓一個(gè)沒接觸過poi的開發(fā)人員,就可以方便的寫出Excel導(dǎo)出、Excel模板導(dǎo)出、Excel導(dǎo)、,Word模板導(dǎo)出等功能。通過簡(jiǎn)單的注解和模板語言(熟悉的表達(dá)式語法),完成以前復(fù)雜的寫法。
API文檔:
http://doc.wupaas.com/docs/easypoi/easypoi-1c0u4mo8p4ro8
倉(cāng)庫(kù):
https://gitee.com/lemur/easypoi
https://gitee.com/lemur/easypoi-test
備注,easypoi對(duì)Apache POI進(jìn)行了二次封裝,屏蔽了Apache POI那些復(fù)制的API。
0x04:easyexcel
Java解析、生成Excel比較有名的框架有Apache POI、jxl。但都存在一個(gè)嚴(yán)重的問題就是非常耗內(nèi)存,POI有一套SAX模式的API可以一定程度的解決一些內(nèi)存溢出的問題,但POI還是有一些缺陷,比如07版Excel解壓縮以及解壓后存儲(chǔ)都是在內(nèi)存中完成的,內(nèi)存消耗依然很大。easyexcel重寫了poi對(duì)07版Excel的解析,能夠原本一個(gè)3M的excel用POI sax依然需要100M左右內(nèi)存降低到幾M,并且再大的excel不會(huì)出現(xiàn)內(nèi)存溢出,03版依賴POI的sax模式。在上層做了模型轉(zhuǎn)換的封裝,讓開發(fā)人員更加簡(jiǎn)單方便。阿里巴巴出品必屬精品。
API文檔
https://www.yuque.com/easyexcel/doc/easyexcel
官網(wǎng):
https://github.com/alibaba/easyexcel
下面是我在使用easyexcel時(shí)遇到的一個(gè)問題,應(yīng)該說使用不當(dāng)導(dǎo)致的問題。今天給大家講一下免得,大家在使用中因?yàn)槭褂貌划?dāng)導(dǎo)致這個(gè)問題。先在github下載easyexcel,如果下載慢的話可以使用國(guó)內(nèi)鏡像:
https://gitee.com/mirrors/easyexcel
下載完后導(dǎo)入到開發(fā)工具eclipse或者idea,可以看到如下目錄很多Execl模板

就看如下這個(gè)特別復(fù)雜的模板,不過演示的這個(gè)問題跟模板的復(fù)雜程度無關(guān)。

找到操作該模板的代碼所在

把相關(guān)代碼拷貝出來,新建一個(gè)TestTemplate.java類
import?java.io.File;
import?java.util.ArrayList;
import?java.util.HashMap;
import?java.util.List;
import?java.util.Map;
import?com.alibaba.easyexcel.test.demo.fill.FillData;
import?com.alibaba.easyexcel.test.util.TestFileUtil;
import?com.alibaba.excel.EasyExcel;
import?com.alibaba.excel.ExcelWriter;
import?com.alibaba.excel.enums.WriteDirectionEnum;
import?com.alibaba.excel.write.metadata.WriteSheet;
import?com.alibaba.excel.write.metadata.fill.FillConfig;
import?com.alibaba.excel.write.metadata.fill.FillWrapper;
public?class?TestTemplate?{
????public?static?void?main(String[]?args)?{
????????//?模板注意?用{}?來表示你要用的變量?如果本來就有"{","}"?特殊字符?用"\{","\}"代替
????????//?{}?代表普通變量?{.}?代表是list的變量?{前綴.}?前綴可以區(qū)分不同的list
????????String?templateFileName?=
????????????TestFileUtil.getPath()?+?"demo"?+?File.separator?+?"fill"?+?File.separator?+?"composite.xlsx";
????????//保存的目錄
????????String?fileName?=?"d:/"?+?System.currentTimeMillis()?+?".xlsx";
????????ExcelWriter?excelWriter?=?EasyExcel.write(fileName).withTemplate(templateFileName).build();
????????WriteSheet?writeSheet?=?EasyExcel.writerSheet().build();
????????FillConfig?fillConfig?=?FillConfig.builder().direction(WriteDirectionEnum.HORIZONTAL).build();
????????//?如果有多個(gè)list?模板上必須有{前綴.}?這里的前綴就是?data1,然后多個(gè)list必須用?FillWrapper包裹
????????excelWriter.fill(new?FillWrapper("data1",?data()),?fillConfig,?writeSheet);
????????excelWriter.fill(new?FillWrapper("data1",?data()),?fillConfig,?writeSheet);
????????excelWriter.fill(new?FillWrapper("data2",?data()),?writeSheet);
????????excelWriter.fill(new?FillWrapper("data2",?data()),?writeSheet);
????????excelWriter.fill(new?FillWrapper("data3",?data()),?writeSheet);
????????excelWriter.fill(new?FillWrapper("data3",?data()),?writeSheet);
????????Map<String,?Object>?map?=?new?HashMap<String,?Object>();
????????map.put("date",?"2019年10月9日13:28:28");
????????excelWriter.fill(map,?writeSheet);
????????//?別忘記關(guān)閉流
????????excelWriter.finish();
????}
????private?static?List?data()?{
????????List?list?=?new?ArrayList();
????????for?(int?i?=?0;?i?10;?i++)?{
????????????FillData?fillData?=?new?FillData();
????????????list.add(fillData);
????????????fillData.setName("張三");
????????????fillData.setNumber(5.2);
????????}
????????return?list;
????}
}
直接運(yùn)行在d:/產(chǎn)生相關(guān)根據(jù)模板生成的文件。現(xiàn)在來改一下模板文件,把Sheet的名字由sheet1改成月報(bào),并對(duì)代碼做如下修改

WriteSheet?writeSheet?=?EasyExcel.writerSheet().build();?
改成
WriteSheet?writeSheet?=?EasyExcel.writerSheet("sheet1").build();
出現(xiàn)以下異常
2020-11-29?19:49:17.120?DEBUG?[main]?com.alibaba.excel.context.WriteContextImpl:199?-?Can?not?find?sheet:null?,now?create?it
2020-11-29?19:49:17.198?DEBUG?[main]?com.alibaba.excel.context.WriteContextImpl:381?-?Finished?write.
Exception?in?thread?"main"?java.lang.NullPointerException
????at?com.alibaba.excel.write.executor.ExcelWriteFillExecutor.doFill(ExcelWriteFillExecutor.java:191)
????at?com.alibaba.excel.write.executor.ExcelWriteFillExecutor.fill(ExcelWriteFillExecutor.java:118)
????at?com.alibaba.excel.write.ExcelBuilderImpl.fill(ExcelBuilderImpl.java:78)
????at?com.alibaba.excel.ExcelWriter.fill(ExcelWriter.java:185)
????at?TestTemplate.main(TestTemplate.java:29)
所以在使用模板時(shí)注意一下他們之間的關(guān)系。

掃碼二維碼
獲取更多精彩
Java樂園

