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 复制 全屏
posted @ 2022-12-01 15:02  hanease  阅读(200)  评论(0编辑  收藏  举报