前段時間在 github 上發現了阿里的 EasyExcel 項目,以爲挺不錯的,就寫了一個簡單的方法封裝,作到只用一個函數就完成 Excel 的導入或者導。恰好前段時間更新修復了一些 BUG,就把個人這個封裝分享出來,請多多指教git
附上源碼:github.com/HowieYuan/e…github
EasyExcel 的 github 地址: github.com/alibaba/eas… EasyExcel 的官方介紹:bash
能夠看到 EasyExcel 最大的特色就是使用內存少,固然如今它的功能還比較簡單,可以面對的複雜場景比較少,不過基本的讀寫徹底能夠知足。app
首先是添加該項目的依賴,目前的版本是 1.1.2-beta4ide
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>1.1.2-beta4</version>
</dependency>
複製代碼
工具類,能夠直接調用該工具類的方法完成 Excel 的讀或者寫函數
監聽類,能夠根據須要與本身的狀況,自定義處理獲取到的數據,我這裏只是簡單地把數據添加到一個 List 裏面。工具
public class ExcelListener extends AnalysisEventListener {
//自定義用於暫時存儲data。
//能夠經過實例獲取該值
private List<Object> datas = new ArrayList<>();
/**
* 經過 AnalysisContext 對象還能夠獲取當前 sheet,當前行等數據
*/
@Override
public void invoke(Object object, AnalysisContext context) {
//數據存儲到list,供批量處理,或後續本身業務邏輯處理。
datas.add(object);
//根據本身業務作處理
doSomething(object);
}
private void doSomething(Object object) {
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
/*
datas.clear();
解析結束銷燬不用的資源
*/
}
public List<Object> getDatas() {
return datas;
}
public void setDatas(List<Object> datas) {
this.datas = datas;
}
}
複製代碼
用於導出多個 sheet 的 Excel,經過屢次調用 write 方法寫入多個 sheetui
捕獲相關 Exceptionthis
讀取 Excel 時只須要調用 ExcelUtil.readExcel()
方法spa
@RequestMapping(value = "readExcel", method = RequestMethod.POST)
public Object readExcel(MultipartFile excel) {
return ExcelUtil.readExcel(excel, new ImportInfo());
}
複製代碼
其中 excel 是 MultipartFile 類型的文件對象,而 new ImportInfo() 是該 Excel 所映射的實體對象,須要繼承 BaseRowModel 類,如:
public class ImportInfo extends BaseRowModel {
@ExcelProperty(index = 0)
private String name;
@ExcelProperty(index = 1)
private String age;
@ExcelProperty(index = 2)
private String email;
/*
做爲 excel 的模型映射,須要 setter 方法
*/
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
複製代碼
做爲映射實體類,經過 @ExcelProperty 註解與 index 變量能夠標註成員變量所映射的列,同時不可缺乏 setter 方法
只須要調用 ExcelUtil.writeExcelWithSheets()
方法:
@RequestMapping(value = "writeExcel", method = RequestMethod.GET)
public void writeExcel(HttpServletResponse response) throws IOException {
List<ExportInfo> list = getList();
String fileName = "一個 Excel 文件";
String sheetName = "第一個 sheet";
ExcelUtil.writeExcel(response, list, fileName, sheetName, new ExportInfo());
}
複製代碼
fileName,sheetName 分別是導出文件的文件名和 sheet 名,new ExportInfo() 爲導出數據的映射實體對象,list 爲導出數據。
對於映射實體類,能夠根據須要經過 @ExcelProperty 註解自定義表頭,固然一樣須要繼承 BaseRowModel 類,如:
public class ExportInfo extends BaseRowModel {
@ExcelProperty(value = "姓名" ,index = 0)
private String name;
@ExcelProperty(value = "年齡",index = 1)
private String age;
@ExcelProperty(value = "郵箱",index = 2)
private String email;
@ExcelProperty(value = "地址",index = 3)
private String address;
}
複製代碼
value 爲列名,index 爲列的序號
若是須要複雜一點,能夠實現以下圖的效果:
對應的實體類寫法以下:
public class MultiLineHeadExcelModel extends BaseRowModel {
@ExcelProperty(value = {"表頭1","表頭1","表頭31"},index = 0)
private String p1;
@ExcelProperty(value = {"表頭1","表頭1","表頭32"},index = 1)
private String p2;
@ExcelProperty(value = {"表頭3","表頭3","表頭3"},index = 2)
private int p3;
@ExcelProperty(value = {"表頭4","表頭4","表頭4"},index = 3)
private long p4;
@ExcelProperty(value = {"表頭5","表頭51","表頭52"},index = 4)
private String p5;
@ExcelProperty(value = {"表頭6","表頭61","表頭611"},index = 5)
private String p6;
@ExcelProperty(value = {"表頭6","表頭61","表頭612"},index = 6)
private String p7;
@ExcelProperty(value = {"表頭6","表頭62","表頭621"},index = 7)
private String p8;
@ExcelProperty(value = {"表頭6","表頭62","表頭622"},index = 8)
private String p9;
}
複製代碼
調用 ExcelUtil.writeExcelWithSheets()
處理第一個 sheet,以後調用 write()
方法依次處理以後的 sheet,最後使用 finish()
方法結束
public void writeExcelWithSheets(HttpServletResponse response) throws IOException {
List<ExportInfo> list = getList();
String fileName = "一個 Excel 文件";
String sheetName1 = "第一個 sheet";
String sheetName2 = "第二個 sheet";
String sheetName3 = "第三個 sheet";
ExcelUtil.writeExcelWithSheets(response, list, fileName, sheetName1, new ExportInfo())
.write(list, sheetName2, new ExportInfo())
.write(list, sheetName3, new ExportInfo())
.finish();
}
複製代碼
write 方法的參數爲當前 sheet 的 list 數據,當前 sheet 名以及對應的映射類