Easy-Excel
它是什麼?
easy-excel 是基於 Apache POI 框架的一款擴展封裝庫,讓我們在開發中更快速的完成導入導出的需求。 儘管很多人會提出 poi 能幹這事兒爲什麼還要封裝一層呢?
easy-excel 很大程度上簡化了代碼、讓使用者更輕鬆的 讀、寫 Excel 文檔,也不用去關心格式兼容等問題,很多時候我們在代碼中會寫很多的 for 循環,各種 getXXXIndex 來獲取行或列讓代碼變的更臃腫。多個項目之間打一槍換一個地方,代碼 Copy 來 Copy 去十分凌亂, 如果你也在開發中遇到類似的問題,那麼 easy-excel 是你值得一試的工具。
特性
支持:
- 基於 Java 8 開發
- 簡潔的 API 操作
- 註解驅動
- 可配置列順序
- 自定義導入/導出轉換器
- 導出支持自定義樣式處理器
- 導入/導出 錯誤信息校驗
- 模板導出
- 支持 Excel 2003、2007格式
- 多 sheet 導入/導出
快速開始
引入依賴
- Apache Maven
<dependency>
<groupId>io.github.itguang</groupId>
<artifactId>easy-excel</artifactId>
<version>1.0.2-RELEASE</version>
</dependency>
- Gradle Groovy DSL
compile group: 'io.github.itguang', name: 'easy-excel', version: '1.0.2-RELEASE'
導出
下面是我們的 Java 模型類,用於存儲 Excel 的行數據。
第一步: 爲我們的 pojo 添加 @ExcelColumn
註解,後面會給出各個參數的意思。
@Data
@AllArgsConstructor
public class Product {
@ExcelColumn(columnName = "id", index = 10)
private Integer id;
@ExcelColumn(columnName = "價格", index = 20, centToYuan = true, suffix = " 元", columnNameCellStyleHandler =
YellowBgCellStyleHandler.class)
private Long price;
@ExcelColumn(columnName = "創建日期", index = 60, columnNameCellStyleHandler = GreyBgCellStyleHandler.class)
private OffsetDateTime created;
@ExcelColumn(columnName = "名稱", index = 40)
private String name;
@ExcelColumn(columnName = "是否是新品", index = 41, trueToStr = "新品", falseToStr = "非新品")
private Boolean isNew;
@ExcelColumn(columnName = "訂單狀態", index = 50, enumKey = "name", prefix = "狀態: ", cellStyleHandler =
RedFontCellStyleHandler.class)
private StateEnum stateEnum;
@ExcelColumn(columnName = "狀態變更日期", index = 55)
private LocalDateTime updateTime;
@ExcelColumn(columnName = "備註", index = 70)
private String other;
}
第二步: 調用 ExcelWriter
類進行導出操作, write() 方法 會返回一個 Workbook
對象
@Test
public void testExport() throws IOException {
Workbook workbook = ExcelWriter.create(ExcelType.XLS)
.sheetName("商品數據")
.sheetHeader("--2月份商品數據--")
.write(products, Product.class);
File file = new File(productFile);
OutputStream outputStream = new FileOutputStream(file);
workbook.write(outputStream);
outputStream.close();
}
導出表格:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-yX6GH0eK-1587636665081)(https://s2.ax1x.com/2020/02/28/3DWpTO.png)]
導入
假設我們現在有這樣一張 excel 表格:
第一步: 給需要接收excel數據的 pojo 實體類添加註解: @ExcelColumn
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Employee {
@ExcelColumn(index = 10, columnName = "ID")
private Integer id;
@ExcelColumn(index = 20, columnName = "名稱")
private String name;
@ExcelColumn(index = 30, columnName = "工資", yuanToCent = true, suffix = " 元")
private Long salary;
@ExcelColumn(index = 40, columnName = "性別",enumKey = "name")
private Gender gender;
@ExcelColumn(index = 50, columnName = "生日")
private OffsetDateTime birthday;
}
需要注意的是,導入操作,接受的實體類必須有無參構造器,否則不能出入成功
第二步: 調用 ExcelReader
類的方法
@Test
public void test_import_xlsx() throws FileNotFoundException {
InputStream fileInputStream = new FileInputStream(employeeFile_Xlsx);
List<Employee> employees = ExcelReader
.read(fileInputStream, ExcelType.XLSX)
.columnNameRowNum(1)
.toPojo(Employee.class);
Assert.assertNotNull(employees);
}
@ExcelColumn 註解參數
@ExcelColumn
註解提供了常用的 轉換操作,包括列名定義,列排序,Boolean值轉換,前綴後綴,日期格式化,分轉元,元轉分 等等.
對於更加複雜的轉換,提供了轉換器接口:
- IWriteConverter: 導出轉換器
- IReadConverter: 導入轉換器
對於需要自定義樣式的需求,分別提供了 對於 columnName
和 rowData
的樣式處理器:
- ICellStyleHandler: 樣式處理器
參數 | 解釋 |
---|---|
columnName | xcel 每一列的名稱 |
index | 排序(僅對導出有效),支持不連續的整數 |
datePattern | 日期格式,默認: yyyy/MM/dd,只支持 OffsetDateTime和 LocalDateTime |
required | 是否必須 |
enumKey | 枚舉導入使用的key,序列化枚舉使用 |
trueToStr | true 轉換字符串(僅對導出有效) |
strToTrue | 字符串轉 true(僅對導入有效) |
falseToStr | false 轉換(僅對導出有效) |
strToFalse | 字符串 轉 false(僅對導入有效) |
prefix | 前綴 |
suffix | 後綴 |
centToYuan | 是否啓用 分轉元(僅對導出有效) ,支持 Integer 和 Long 類型 |
yuanToCent | 是否啓用 元轉分(僅對導入有效),支持 Integer 和 Long 類型 |
writeConverter | 導出轉換器 |
readConverter | 導入轉換器 |
cellStyleHandler | rowData 樣式處理器 |
columnNameCellStyleHandler | columnName 樣式處理器 |
API
查看 wiki
測試
本項目採用 github action CI 自動構建,每當 master 分支有變動時就會觸發構建,運行所有單元測試。
目前的 jacoco 測試報告:
導入導出的核心代碼基本覆蓋到