天天看點

一行代碼完成 JAVA 的 EXCEL 讀寫——EasyExcel 的方法封裝EasyExcel一. 依賴二. 需要的類三. 讀取 Excel四. 導出 Excel

前段時間在 github 上發現了阿裡的 EasyExcel 項目,覺得挺不錯的,就寫了一個簡單的方法封裝,做到隻用一個函數就完成 Excel 的導入或者導。剛好前段時間更新修複了一些 BUG,就把我的這個封裝分享出來,請多多指教

附上源碼:

https://github.com/HowieYuan/easyexcel-method-encapsulation

EasyExcel

EasyExcel 的 github 位址:

https://github.com/alibaba/easyexcel

EasyExcel 的官方介紹:

可以看到 EasyExcel 最大的特點就是使用記憶體少,當然現在它的功能還比較簡單,能夠面對的複雜場景比較少,不過基本的讀寫完全可以滿足。

一. 依賴

首先是添加該項目的依賴,目前的版本是 1.0.2

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

二. 需要的類

1. ExcelUtil

工具類,可以直接調用該工具類的方法完成 Excel 的讀或者寫

2. ExcelListener

監聽類,可以根據需要與自己的情況,自定義處理擷取到的資料,我這裡隻是簡單地把資料添加到一個 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;
    }
}           

3. ExcelWriterFactroy

用于導出多個 sheet 的 Excel,通過多次調用 write 方法寫入多個 sheet

4. ExcelException

捕獲相關 Exception

三. 讀取 Excel

讀取 Excel 時隻需要調用

ExcelUtil.readExcel()

方法

@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 方法

四. 導出 Excel

1. 導出的 Excel 隻擁有一個 sheet

隻需要調用

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;
}           

2. 導出的 Excel 擁有多個 sheet

調用

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 名以及對應的映射類