1. 程式人生 > 其它 >SpringBoot(六) - 阿里巴巴的EasyExcel

SpringBoot(六) - 阿里巴巴的EasyExcel

1、依賴

<!-- 阿里EasyExcel start -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>2.1.7</version>
</dependency>

2、寫入Excel

2.1 實體

@Data
public class Student {

    //學號
    @ExcelProperty("學號")
    private Integer id;

    // 姓名
    @ExcelProperty("姓名")
    private String name;

    // 年齡
    @ExcelProperty("年齡")
    private Integer age;

    // 班級
    @ExcelProperty("班級")
    private String classRoom;

    // 性別
    @ExcelProperty("性別")
    private String sex;

    // 院校
    @ExcelProperty("院校")
    private String graduate;

    // 畢業時間
    @DateTimeFormat("yyyy年MM月dd日HH時mm分ss秒")
    @ExcelProperty("畢業時間")
    private Date graduateTime;

    // 手機號
    @ExcelProperty("手機號")
    private String phone;
    
    //@NumberFormat("#.#") //保留1位小數
    //@ExcelProperty(value = "薪資", index = 3) //設定表圖和指定的列, 將工資放在 第四列
    //@ExcelIgnore  忽略欄位,比如密碼
    
}

2.2 實體的資料監聽器

@Slf4j
public class StudentDataListener extends AnalysisEventListener<Student> {

    /**
     * 每隔5條儲存資料庫,實際使用中可以3000條,然後清理list ,方便記憶體回收
     */
    private static final int BATCH_COUNT = 5; //實際操作的時候看情況修改
    List<Student> list = new ArrayList<>();

    /**
     * 這個每一條資料解析都會來呼叫
     *
     * @param data
     *            one row value. Is is same as {@link AnalysisContext#readRowHolder()}
     * @param context
     */
    @Override
    public void invoke(Student data, AnalysisContext context) {
        log.info("解析到一條資料:{}", data);
        list.add(data);
        // 達到BATCH_COUNT了,需要去儲存一次資料庫,防止資料幾萬條資料在記憶體,容易OOM
        if (list.size() >= BATCH_COUNT) {
            log.info("存資料庫");

            // 批量插入
            // 儲存完成清理 list
            list.clear();
        }
    }

    /**
     * 所有資料解析完成了 都會來呼叫
     *
     * @param context
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        log.info("所有資料解析完成!");
    }

    //為了方便獲取讀取的資料
    public List<Student> getList() {
        return list;
    }
}

2.3 03版本的Excel寫入

@Test
public void testExcel03(){

    //要寫入的檔案的路徑
    String fileName = "D:\\KEGONGCHANG\\DaiMa\\IDEA\\KH96\\SpringBoot\\SpringBoot\\springboot-03-asyztimer\\excel\\excel03_student.xls";

    // 如果這裡想使用03 則 傳入excelType引數即可
    //獲取學生資訊,實際應用中從資料庫中查詢出來即可,list集合

    Student student =   Student.builder().id(19).name("huayu").age(19)
        .classRoom("KH96").sex("男").graduate("金科")
        .graduateTime(new Date()).phone("13501020304").build();
    List<Student> studentList = new ArrayList<>();
    studentList.add(student);

    //將資料寫入檔案
    EasyExcel.write(fileName, Student.class)
        	 .excelType(ExcelTypeEnum.XLS)
        	 .sheet("學生資訊")
        	 .doWrite(studentList);

    log.info("學生資訊寫入完成!!!{}",student);

}

測試結果:

2.4 07版本的Excel 寫入

@Test
public void testExcel07(){

   //要寫入的檔案的路徑
   String fileName = "D:\\KEGONGCHANG\\DaiMa\\IDEA\\KH96\\SpringBoot\\SpringBoot\\springboot-03-asyztimer\\excel\\excel07_student.xls";


   //獲取學生資訊
    studentList.add(student);

     //07版寫入檔案
    EasyExcel.write(fileName, Student.class)
        	 .sheet("學生資訊")
        	 .doWrite(studentList);

    log.info("學生資訊寫入完成!!!{}",student);

}

測試結果:

2.5 寫入多個sheet

@Test
public void testWriteSheets(){

    String fileName = "D:\\KEGONGCHANG\\DaiMa\\IDEA\\KH96\\SpringBoot\\SpringBoot\\springboot-03-asyztimer\\excel\\excel07_student_sheets.xlsx";

    //獲取學生資訊
    studentList.add(student);

    // 這裡 需要指定寫用哪個class去寫,然後寫到第一個sheet,名字為模板 然後檔案流會自動關閉
    ExcelWriter excelWriter = EasyExcel.write(fileName, Student.class).build();

    WriteSheet sheet;

    for (int i = 0; i < 2; i++) {
        sheet = EasyExcel.writerSheet(i, "學生資訊"+(i+1)).build();
        excelWriter.write(studentList,sheet);
    }

    excelWriter.finish();

    log.info("學生資訊寫入完成!!!{}",student);

}

測試結果:

3、讀出Excel

3.1 doRead()

3.1.1 sheet1中的資料

sheet1:

3.1.2 doRead() 方法讀取

//讀取Excel中的學生資訊
@Test
public void testReadExcel(){

    String fileName = "D:\\KEGONGCHANG\\DaiMa\\IDEA\\KH96\\SpringBoot\\SpringBoot\\springboot-03-asyztimer\\excel\\excel07_student_sheets.xlsx";

    // 例項化一個數據監聽器
    StudentDataListener studentDataListener =  new StudentDataListener();

    //第一種
    //讀取後的資料放進list中,所以可以從list中獲取資料,(這裡的資料是我們處理過的,最多返回5條的資料,可以根據實際境況修改)
    EasyExcel.read(fileName, Student.class,studentDataListener)
        	 .sheet()  //預設讀取第一個sheet
        	 .doRead();
    List<Student> list = studentDataListener.getList();
    log.info("------ 讀取後的資料放進list中,所以可以從list中獲取資料,最多返回5條的資料 ------");
    list.forEach(ersonData->{
        log.info(ersonData.toString());
    });

}

3.1.3 測試結果:

3.1.4 分析 doRead() 方法

//沒有任何資料返回
public void doRead() {
    if (this.excelReader == null) {
        throw new ExcelGenerateException("Must use 'EasyExcelFactory.read().sheet()' to call this method");
    } else {
        this.excelReader.read(new ReadSheet[]{this.build()});
        this.excelReader.finish();
    }
}

3.2 doReadSync()

3.2.1 sheet2中的資料

sheet2:

3.2.2 doReadSync() 方法讀取

//讀取Excel中的學生資訊
@Test
public void testReadExcel(){

    String fileName = "D:\\KEGONGCHANG\\DaiMa\\IDEA\\KH96\\SpringBoot\\SpringBoot\\springboot-03-asyztimer\\excel\\excel07_student_sheets.xlsx";

    // 例項化一個數據監聽器
    StudentDataListener studentDataListener =  new StudentDataListener();

    //第二種
    log.info("------ 同步獲取資料,讀取到的所有資料 ------");
    //同步獲取資料,讀取到的所有資料
    List<Student> list2 =  EasyExcel.read(fileName, Student.class,studentDataListener)
        							.sheet(1) //讀取第二個sheet
        							.doReadSync();
    list2.forEach(ersonData->{
        log.info(ersonData.toString());
    });
}

3.2.3 測試結果:

3.2.4 分析 doReadSync() 方法

//會將讀取到的資料返回
public <T> List<T> doReadSync() {
    if (this.excelReader == null) {
        throw new ExcelAnalysisException("Must use 'EasyExcelFactory.read().sheet()' to call this method");
    } else {
        SyncReadListener syncReadListener = new SyncReadListener();
        this.registerReadListener(syncReadListener);
        this.excelReader.read(new ReadSheet[]{this.build()});
        this.excelReader.finish();
        return syncReadListener.getList();
    }
}
JAVA 複製 全屏