Java處理表格的實用工具庫
前言
處理 Excel 表格是開發(fā)中經(jīng)常遇到的需求,比如表格合并、篩選表格中的某些行列、修改單元格數(shù)據(jù)等。
今天給大家分享一個 Java 處理表格的工具庫,不需要任何專業(yè)知識,拿來就能用,快速又輕松~
可能有同學(xué)說了,用 Python 處理表格不是更方便么?為毛用 Java ???
當然是因為企業(yè)中大部分后臺開發(fā)用的都是 Java!如果你要搞一個允許用戶自主上傳 Excel 進行處理的服務(wù),那顯然直接用 Java 來實現(xiàn)最方便~
Easy Excel
要介紹的庫是阿里的 Easy Excel,簡單、省內(nèi)存的讀寫 Excel 的開源項目。
文檔地址:www.yuque.com/easyexcel/d…
直接打開官方文檔,就能看到項目的使用說明了:
首先在項目中引入 Easy Excel(版本號以文檔中的最新版本號為主):
<dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>3.0.5</version> </dependency>
然后進入文檔的 快速開始 部分,就可以看到讀取和寫入表格數(shù)據(jù)的方法了。
下面讓我們以一個實際需求為例,試著使用一下這個庫。
需求
假設(shè)我們有這樣一個 Excel 表格:
如果想要調(diào)換 姓名列 和 年齡列 的順序,應(yīng)該怎么做呢?
讀取表格
首先要讀取原始表格中的數(shù)據(jù)。
Easy Excel 提供了兩種讀取表格的方式:創(chuàng)建對象的讀 和 不創(chuàng)建對象的讀 。
創(chuàng)建對象的讀
如果你已知整個表格的表頭信息,比如列名(比如 “姓名”)和列的數(shù)據(jù)類型(比如字符串),那么可以創(chuàng)建一個對應(yīng)的類,用來在 Java 中表示表格的元信息。
比如為上述表格創(chuàng)建 YupiData 類,代碼如下:
@Data public class YupiData { // 姓名 private String name; // 年齡 private Integer age; // 出生日期 private Date bornDate; }
默認會根據(jù)屬性的順序來關(guān)聯(lián)表格列的順序,比如 name 對應(yīng)姓名(第 0 列)、age 對應(yīng)年齡(第 1 列)。
當然,你也可以使用注解的方式來指定每個屬性對應(yīng)的表格列,支持指定下標和列名,代碼如下:
@Data public class YupiData { // 強制讀取下標為 2 的列(第三列) @ExcelProperty(index = 2) // 指定接受日期的格式 @DateTimeFormat("yyyy/MM/dd") private Date bornDate; // 用名字去匹配,不能和其他列重復(fù) @ExcelProperty("年齡") private Integer age; @ExcelProperty("姓名") private String name; }
定義好了表格數(shù)據(jù)類,就可以開始讀取了,該庫非常貼心,提供了 同步 和 異步 兩種讀取方式。
同步是指一次性讀取表格中的所有行,以列表的方式完整返回,再整體去處理。由于這種方式會將數(shù)據(jù)完整加載到內(nèi)存中,因此只 適用于表格行數(shù)比較少 的情況。代碼如下:
/** * 同步讀取 */ public void synchronousRead() { String fileName = "魚皮的表格.xlsx"; // 讀取到的數(shù)據(jù) List<YupiData> list = EasyExcel.read(fileName) .head(YupiData.class) .sheet() .doReadSync(); }
異步方式需要定義一個 監(jiān)聽器 ,每讀取一行,就要立即去處理該行數(shù)據(jù)。這樣就不需要將所有數(shù)據(jù)都加載到內(nèi)存中,算一行讀一行,理論上算完了也可以丟棄。代碼如下:
/** * 定義監(jiān)聽器 */ public class YupiDataListener implements ReadListener<YupiData> { /** * 每讀一行數(shù)據(jù),都會調(diào)用一次 * * @param data 一行數(shù)據(jù) * @param context 上下文 */ @Override public void invoke(YupiData data, AnalysisContext context) { // 輸出姓名 System.out.println(data.getName()); } } /** * 開始讀取 */ void assynchronousRead() { String fileName = "魚皮的表格.xlsx"; EasyExcel.read(fileName, YupiData.class, new YupiDataListener()) .sheet() .doRead(); }
不創(chuàng)建對象的讀
如果事先不清楚表格會有哪些列、類型如何(比如讓用戶自主上傳表格),那么可以使用 不創(chuàng)建對象讀 的方式,直接用 Map<Integer, String> 泛型類來接收:
List<Map<Integer, String>> list = EasyExcel .read(fileName) .sheet() .doReadSync(); // Map 的 key 為列下標,value 為單元格的值 for (Map<Integer, String> data : list) { ... }
當然,這種讀取方式也同時支持同步和異步,可以根據(jù)需求選擇方式,靈活的一批!
寫入表格
學(xué)會讀取后,寫入表格就更簡單了,依然是先定義一個類,用來表示要寫入表格的元信息(列名、列數(shù)據(jù)類型等)。
比如要完成表格列順序調(diào)換的需求,定義表格數(shù)據(jù)類的時候,把 age 和 name 屬性的順序換一下就好了:
@Data public class YupiWriteData { // 年齡 ↑ private Integer age; // 姓名 ↓ private String name; // 出生日期 private Date bornDate; }
然后執(zhí)行 Easy Excel 的 write 方法,就完事了,代碼如下:
void doWrite() { // 已讀取和處理后的數(shù)據(jù)列表 List<YupiWriteData> dataList = xxx; String fileName = "result.xlsx"; EasyExcel.write(fileName, YupiWriteData.class) .sheet("工作表1") .doWrite(dataList); }
搞定,是不是賊簡單!
除了這個庫外,Java 處理 Excel 的庫還有很多,比如 Apache POI、Hutool 等,大家可以去試試。但我個人感覺還是 Easy Excel 更對我的胃口。
EasyExcel特點
Java領(lǐng)域解析、生成Excel比較有名的框架有Apache poi、jxl等。但他們都存在一個嚴重的問題就是非常的耗內(nèi)存。如果你的系統(tǒng)并發(fā)量不大的話可能還行,但是一旦并發(fā)上來后一定會OOM或者JVM頻繁的full gc。
EasyExcel是阿里巴巴開源的一個excel處理框架,以使用簡單、節(jié)省內(nèi)存著稱。EasyExcel能大大減少占用內(nèi)存的主要原因是在解析Excel時沒有將文件數(shù)據(jù)一次性全部加載到內(nèi)存中,而是從磁盤上一行行讀取數(shù)據(jù),逐個解析。
EasyExcel采用一行一行的解析模式,并將一行的解析結(jié)果以觀察者的模式通知處理(AnalysisEventListener)。
總結(jié)
到此這篇關(guān)于Java處理表格實用工具庫的文章就介紹到這了,更多相關(guān)Java處理表格工具庫內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Springcloud微服務(wù)架構(gòu)基礎(chǔ)知識解析
這篇文章主要介紹了Springcloud微服務(wù)架構(gòu)基礎(chǔ)知識解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-04-04Java基本數(shù)據(jù)類型與對應(yīng)的包裝類(動力節(jié)點java學(xué)院整理)
Java是面向?qū)ο蟮木幊陶Z言,包裝類的出現(xiàn)更好的體現(xiàn)這一思想,Java語言提供了八種基本類型。六種數(shù)字類型(四個整數(shù)型,兩個浮點型),一種字符類型,還有一種布爾型。 下面通過本文給大家詳細介紹,感興趣的朋友一起學(xué)習(xí)吧2017-04-04JAVA StringBuffer類與StringTokenizer類代碼解析
這篇文章主要介紹了JAVA StringBuffer類與StringTokenizer類代碼解析,具有一定借鑒價值,需要的朋友可以參考下2018-01-01java實現(xiàn)的日期時間轉(zhuǎn)換工具類完整示例
這篇文章主要介紹了java實現(xiàn)的日期時間轉(zhuǎn)換工具類,結(jié)合完整實例形式分析了java針對日期時間常見的轉(zhuǎn)換、計算、格式化等相關(guān)操作與封裝技巧,需要的朋友可以參考下2019-10-10