1. 項目介紹
1.1 簡介
Chimm.Excel 是什么?
該程序是一個用 Java 寫的 Excel 生成工具,基於模板操作,簡單,快捷,易上手。
1.2 特性
-
數據組裝方式大有不同
和網上部分開源軟件的區別是,這個程序是基於 excel 模板驅動的,需要在模版里填寫變量名稱,而並非在程序中添加注解。
-
為什么不采用基於注解的方式?
網上一些基於注解的 excel 導出,基本上只能導出簡單的表格樣式。該程序使用的是 excel 模板,所以可以導出一些比較復雜的表格樣式。
-
Antlr4
Antlr (ANother Tool for Language Recognition) 是一個強大的跨語言語法解析器,可以用來讀取、處理、執行或翻譯結構化文本或二進制文件。它被廣泛用來構建語言,工具和框架。Antlr可以從語法上來生成一個可以構建和遍歷解析樹的解析器。由於該程序是基於
Antlr4進行開發的,所以在變量定義上面,非常的靈活,我們可以定義集合變量,甚至我們還可以在公式中定義變量。一個表格對應一個數據對象,開發人員只需查詢數據、組裝數據即可。 -
excel 模板如何生成?
模板生成非常的簡單,我們定義變量的時候,只需要使用$+大小括號包圍的形式即可,如:${school.name}。 -
Chimm.Excel功能簡介- [x] 導出excel二進制文件
- [x] 根據模板中的變量,將值寫入
- [x] 支持公式
- [x] 支持帶變量的公式,如:
SUM(A1,A2,${demo.value})
- [x] 支持帶變量的公式,如:
- [x] 操作表格添加/減少行
- [x] ⭐️添加行會自動更新公式
- [x] 合並單元格(支持批量合並)
- [x] 更改單元格邊框樣式(加粗、虛線等)
- [x] 支持設置超鏈接(v1.2.0)## 2. 功能展示
我提供了一個 demo 測試類。
模板具體位置: src/test/resources/demo.xlsx
測試類的具體位置:src/test/java/../demo/Demo.java
模板文件:

處理后的文件:

3. 項目結構
.com.github.chimmhuang
└── excel
├── ExcelHelper.java 整個程序的主入口
├── exception 自定義異常
├── parser Antlr4解析文件
└── tablemodel 表格相關的類
3.1 ExcelHelper - 表格處理對象
該對象是 Chimm.Excel 整個程序的主入口,提供了 創建 excel 工作簿、獲取 sheet 頁表格、填充模板數據、導出二進制等功能,下面我將詳細的介紹主要的方法。
-
createWorkbook(byte[] bytes)
創建 excel 工作簿:該方法是將二進制模板文件,封裝為ExcelWorkbook對象,並返回。 -
getSheetTable(byte[] bytes, int sheetIndex) -
getSheetTable(byte[] bytes, String sheetName)
獲取對應 sheet 頁的表格對象:該方法獲取傳入的二進制模板文件中指定sheet頁的表格對象。 -
fillInData(SheetTable table, Object data)
將變量填充入表格:該方法是將已經封裝好了的表格數據對象 填充到 模板表格 里。 -
convert2Byte(SheetTable table)
該方法會將指定的表格對象轉換為 excel 二進制文件
3.2 ExcelWorkbook - excel對象
該對象對應的是整個 excel 文件,包含了所有 sheet 頁的表格對象,目前階段該對象的實際使用場景並不太多,所以提供的方法較少
-
getSheet(int index) -
getSheet(String sheetName)
獲取指定的 sheet 頁對象,並返回。 -
getXssfWorkbook()
該方法會返回 Apache poi 原生的xssfWorkbook對象,提供給開發者進行 poi 的一些原生操作。
3.3 SheetTable - 表格對象
該對象對應的是 sheet 頁的表格。提供了一些操作表格樣式的方法
-
getRow(int rowNum)
獲取指定行號的行對象。 -
removeRowGE(int rowNum)
刪除行號大於等於指定 rowNum 的行對象 -
appendRow(Row srcRow)
在表格最后添加一行 -
mergeCell(int firstRowNum, int lastRowNum, String firstColName, String lastColName)
合並單元格 -
-setBorderStyle(int firstRowNum, int lastRowNum, String firstColName, String lastColName, BorderStyle borderStyle, BorderPositionEnum borderPositionEnum)``
設置指定范圍的邊框的樣式,你可以更改邊框的樣式,如粗線、虛線等
3.4 Row - 行對象
該對象對應的是 excel 的行,提供了一些對行進行操作的方法
-
getCell(String cellName)
獲取該行指定列的單元格對象 -
copy()
復制一個該對象(深克隆該對象)。 -
setBorderStyle(BorderPositionEnum positionEnum, BorderStyle borderStyle)
設置該行邊框的樣式,你可以更改邊框的樣式,如粗線、虛線等
3.5 Cell - 單元格對象
該對象對應的是 excel 的單元格。提供了一些對單元格操作的方法
-
getValue() -
setValue(Object value)
獲取/設置 該單元格的值 -
setFormula(String formula)
設置該單元格的公式 -
setBorderStyle(BorderPositionEnum positionEnum, BorderStyle borderStyle)
設置該單元格的邊框的樣式,你可以更改邊框的樣式,如粗線、虛線等
4. 使用說明
4.1 配置模板
模板配置,使用 美元符號加上大括號來定義變量即可,如: ${demo.value}。
我在該項目中提功能 demo 使用的模板,基本滿足絕大部分場景:src/test/resources/demo.xlsx
4.2 導入坐標
<dependency>
<groupId>com.github.chimmhuang</groupId>
<artifactId>chimm.excel</artifactId>
<version>1.2.0</version>
</dependency>
4.3 功能介紹
4.3.1 導入模板,導出結果表格
- 此處展示了模板的導入
- 省略了表格數據的填充,表格數據填充需要讓我們定義的表格變量類與模板上的變量名稱一一對應即可,此處省略。
- 展示了填充完數據后,最終生成的字節對象,即是我們期望的結果表格,開發者可以操作該對象進行文件的導出或上傳。
public void testFillInTable() throws Exception {
// 獲取文件的二進制
File file = new File("src/test/resources/demo.xlsx");
byte[] bytes = FileUtils.readFileToByteArray(file);
// 通過 ExcelHelper 獲取 excel 表格對象
ExcelWorkbook excelWorkbook = ExcelHelper.createWorkbook(bytes);
// 獲取指定的 sheet 頁(該對象即是我們設置好的表格模板)
SheetTable table = excelWorkbook.getSheet(0);
// 封裝表格數據對象
SchoolReportData tableData = new SchoolReportData();
// ... 填充數據 ...
tableData.setTitle("xx中學成績單");
// ... 省略了添加數據的代碼 ...
// ... 省略了動態設置表格樣式的代碼 ...
// 將封裝好的表格對象,填充到 excel 表格中
ExcelHelper.fillInData(table, tableData);
// 將表格對象轉換為二進制,resultBytes 即是最終想要的結果
byte[] resultBytes = ExcelHelper.convert2Byte(table);
}
4.3.2 設置公式
public void testFillInTable() throws Exception {
/*
獲取文件的二進制
通過 ExcelHelper 獲取 excel 表格對象
...
*/
// 獲取指定的 sheet 頁(該對象即是我們設置好的表格模板)
SheetTable table = excelWorkbook.getSheet(0);
// 給表格的 第13行 第A列 設置公式
Row row13 = table.getRow(13).getCell("A").setFormula("SUM(A1,A2,${demo.value})");
}
4.3.3 添加行/減少行
public void testFillInTable() throws Exception {
/*
獲取文件的二進制
通過 ExcelHelper 獲取 excel 表格對象
...
*/
// 獲取指定的 sheet 頁(該對象即是我們設置好的表格模板)
SheetTable table = excelWorkbook.getSheet(0);
// 獲取第13行
Row row13 = table.getRow(13);
// 將 rowNum 大於 13 的都刪除,進行動態表格添加
table.removeRowGE(13);
// 復制行
Row copy1 = row13.copy();
Row copy2 = row13.copy();
// 設置新的值
copy1.getCell("A").setValue("copy1");
copy2.getCell("A").setValue("copy2");
// 設置完畢后,添加進表格
table.appendRow(copy1);
table.appendRow(copy2);
}
4.3.4 合並單元格
public void testFillInTable() throws Exception {
/*
獲取文件的二進制
通過 ExcelHelper 獲取 excel 表格對象
...
*/
// 獲取指定的 sheet 頁(該對象即是我們設置好的表格模板)
SheetTable table = excelWorkbook.getSheet(0);
// 合並單元格,【此處僅展示功能,需要合並的 rowNum 建議動態計算】
table.mergeCell(13, 15, "A", "A");
table.mergeCell(16, 19, "A", "A");
}
4.3.5 單元格邊框加粗
public void testFillInTable() throws Exception {
/*
獲取文件的二進制
通過 ExcelHelper 獲取 excel 表格對象
...
*/
// 獲取指定的 sheet 頁(該對象即是我們設置好的表格模板)
SheetTable table = excelWorkbook.getSheet(0);
// 設置指定行的單元格樣式,【此處僅展示功能:加粗,rowNum 建議動態計算】
table.getRow(19).setBorderStyle(BorderPositionEnum.BOTTOM, BorderStyle.MEDIUM);
}
4.3.6 設置超鏈接
public void testFillInTable() throws Exception {
/*
獲取文件的二進制
通過 ExcelHelper 獲取 excel 表格對象
...
*/
// 獲取指定的 sheet 頁(該對象即是我們設置好的表格模板)
SheetTable table = excelWorkbook.getSheet(0);
// 設置超鏈接
table.getRow(2).getCell("A").setHyperlinkURL("https://www.baidu.com");
}
5. 參與貢獻
非常歡迎你的加入!提一個 Issue 或者提交一個 Pull Request。
6. 聯系作者
QQ & 微信:905369866
email:chimmhuang@163.com
7. 開源協議
Apache 2.0 © Chimm Huang
