Java 處理表格,真的很爽!


一個簡單又快速的表格處理庫

大家好,我是魚皮。

處理 Excel 表格是開發中經常遇到的需求,比如表格合並、篩選表格中的某些行列、修改單元格數據等。

今天給大家分享一個 Java 處理表格的工具庫,不需要任何專業知識,拿來就能用,快速又輕松~

可能有同學說了,用 Python 處理表格不是更方便么?為毛用 Java 啊?

當然是因為企業中大部分后台開發用的都是 Java!如果你要搞一個允許用戶自主上傳 Excel 進行處理的服務,那顯然直接用 Java 來實現最方便~

Easy Excel

要介紹的庫是阿里的 Easy Excel,簡單、省內存的讀寫 Excel 的開源項目。

文檔地址:https://www.yuque.com/easyexcel/doc/easyexcel

直接打開官方文檔,就能看到項目的使用說明了:

官方文檔

首先在項目中引入 Easy Excel(版本號以文檔中的最新版本號為主):

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.0.5</version>
</dependency>

然后進入文檔的 快速開始 部分,就可以看到讀取和寫入表格數據的方法了。

下面讓我們以一個實際需求為例,試着使用一下這個庫。

需求

假設我們有這樣一個 Excel 表格:

如果想要調換 姓名列年齡列 的順序,應該怎么做呢?

讀取表格

首先要讀取原始表格中的數據。

Easy Excel 提供了兩種讀取表格的方式:創建對象的讀不創建對象的讀

創建對象的讀

如果你已知整個表格的表頭信息,比如列名(比如 “姓名”)和列的數據類型(比如字符串),那么可以創建一個對應的類,用來在 Java 中表示表格的元信息。

比如為上述表格創建 YupiData 類,代碼如下:

@Data
public class YupiData {
  // 姓名
  private String name;
  // 年齡
  private Integer age;
  // 出生日期
  private Date bornDate;
}

默認會根據屬性的順序來關聯表格列的順序,比如 name 對應姓名(第 0 列)、age 對應年齡(第 1 列)。

當然,你也可以使用注解的方式來指定每個屬性對應的表格列,支持指定下標和列名,代碼如下:

@Data
public class YupiData {
  // 強制讀取下標為 2 的列(第三列)
  @ExcelProperty(index = 2)
  // 指定接受日期的格式
  @DateTimeFormat("yyyy/MM/dd")
  private Date bornDate;
    
  // 用名字去匹配,不能和其他列重復
  @ExcelProperty("年齡")
  private Integer age;
    
  @ExcelProperty("姓名")
  private String name;
}

定義好了表格數據類,就可以開始讀取了,該庫非常貼心,提供了 同步異步 兩種讀取方式。

同步是指一次性讀取表格中的所有行,以列表的方式完整返回,再整體去處理。由於這種方式會將數據完整加載到內存中,因此只 適用於表格行數比較少 的情況。代碼如下:

/**
 * 同步讀取
 */
public void synchronousRead() {
  String fileName = "魚皮的表格.xlsx";
  // 讀取到的數據
  List<YupiData> list = EasyExcel.read(fileName)
  	.head(YupiData.class)
    .sheet()
    .doReadSync();
}

異步方式需要定義一個 監聽器 ,每讀取一行,就要立即去處理該行數據。這樣就不需要將所有數據都加載到內存中,算一行讀一行,理論上算完了也可以丟棄。代碼如下:

/**
 * 定義監聽器
 */ 
public class YupiDataListener 
    implements ReadListener<YupiData> {
  /**
   * 每讀一行數據,都會調用一次
   *
   * @param data 一行數據
   * @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();
}

不創建對象的讀

如果事先不清楚表格會有哪些列、類型如何(比如讓用戶自主上傳表格),那么可以使用 不創建對象讀 的方式,直接用 Map<Integer, String> 泛型類來接收:

List<Map<Integer, String>> list = EasyExcel
    .read(fileName)
    .sheet()
    .doReadSync();
// Map 的 key 為列下標,value 為單元格的值
for (Map<Integer, String> data : list) {
	... 
}

當然,這種讀取方式也同時支持同步和異步,可以根據需求選擇方式,靈活的一批!

寫入表格

學會讀取后,寫入表格就更簡單了,依然是先定義一個類,用來表示要寫入表格的元信息(列名、列數據類型等)。

比如要完成表格列順序調換的需求,定義表格數據類的時候,把 age 和 name 屬性的順序換一下就好了:

@Data
public class YupiWriteData {
  // 年齡 ↑
  private Integer age;
  // 姓名 ↓
  private String name;
  // 出生日期
  private Date bornDate;
}

然后執行 Easy Excel 的 write 方法,就完事了,代碼如下:

void doWrite() {
  // 已讀取和處理后的數據列表
  List<YupiWriteData> dataList = xxx;
  String fileName = "result.xlsx";
  EasyExcel.write(fileName, YupiWriteData.class)
      .sheet("工作表1")
      .doWrite(dataList);
}

搞定,是不是賊簡單!

除了這個庫外,Java 處理 Excel 的庫還有很多,比如 Apache POI、Hutool 等,大家可以去試試。但我個人感覺還是 Easy Excel 更對我的胃口。


好了,是不是很簡單了,有興趣的話自己寫個表格處理程序吧~

學到的話,幫魚皮點個 唄,感謝!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM