使用easyExcel导入excel简易demo

github地址

https://github.com/alibaba/easyexcel

我用的springboot 照例先上依赖

<!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>easyexcel</artifactId>
	<version>2.1.6</version>
</dependency>

需要的实体类和Listener

使用easyExcel导入excel简易demo_第1张图片

实体类,这里的@Data我用了idea Lombok的插件声明的get和set方法

package com.fchan.layui.entity;

import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import java.io.Serializable;

@Data
public class EasyExcelTest implements Serializable {
    private static final long serialVersionUID = 8362987561243233425L;

    //@ExcelProperty(value ="类型",index = 0)     //文档中建议只用 index 或者只用 value 不要混用
    @ExcelProperty(index = 0)
    private String type;//开支类型 信用卡等

    @ExcelProperty(index =1)
    private String sum;

    @ExcelProperty(index =2)
    private String name;//开支来源  如:**银行信用卡

    @ExcelProperty(index =3)
    private String date;

    @ExcelProperty(index =4)
    private Integer status;

    @ExcelProperty(index =5)
    private String descr;

}

对读取的excel中单元格格式为时间的内容进行格式化

要注意的一点就是实体类中接收的属性的类型只能为String才能格式化
使用easyExcel导入excel简易demo_第2张图片

使用easyExcel导入excel简易demo_第3张图片

Listener读取监听类

package com.fchan.layui.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fchan.layui.entity.EasyExcelTest;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Slf4j
public class EasyExcelListener extends AnalysisEventListener<EasyExcelTest> {

    static final ObjectMapper JSON = new ObjectMapper();

    /**
     * 每隔5条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收
     */
    private static final int BATCH_COUNT = 5;

    //Collections.synchronizedList给List的add方法加 synchronized 锁
    List<EasyExcelTest> list = Collections.synchronizedList(new ArrayList<EasyExcelTest>());
/*

     * 假设这个是一个DAO,当然有业务逻辑这个也可以是一个service。当然如果不用存储这个对象没用。

    private DemoDAO demoDAO;
    public DemoDataListener() {
        // 这里是demo,所以随便new一个。实际使用如果到了spring,请使用下面的有参构造函数
        demoDAO = new DemoDAO();
    }

     * 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来
     *
     * @param demoDAO
     *
    public DemoDataListener(DemoDAO demoDAO) {
        this.demoDAO = demoDAO;
    }
*/

    /**
     * 加上存储数据库
     */
    private void saveData() {
        //demoDAO.save(list);
        log.info("存储数据库成功!");
    }


    /**
     * 解析每一条数据的时候都会进这个方法
     * @param data
     * @param context
     */
    @Override
    public void invoke(EasyExcelTest data, AnalysisContext context) {
        try {
            log.info("解析到一条数据:{}",JSON.writeValueAsString(data));
            if(list.size() >= BATCH_COUNT){
                //存储数据库
                saveData();

                //然后准备攒下一波数据
                list.clear();
            }
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }

    /**
     * 解析完成的时候也要保存一遍数据库
     * @param context
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        if(list.size() > 0){
            //存数据库
            saveData();
        }
    }
}

读取demo

@PostMapping("testEasyExcel")
    @ResponseBody
    String testEasyExcel(@RequestParam("excel")MultipartFile excel) throws IOException {
        //这个EasyExcelListener里已经写入了监听保存的操作,所以外面不需要自己再处理了
        // 这里默认读取第一个sheet
        EasyExcel.read(excel.getInputStream(), EasyExcelTest.class, new EasyExcelListener()).sheet().doRead();
        return "success";
    }

excel具有多行头解析demo

/**
     * 多行头
     *
     * 

1. 创建excel对应的实体对象 参照{@link DemoData} *

2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoDataListener} *

3. 设置headRowNumber参数,然后读。 这里要注意headRowNumber如果不指定, 会根据你传入的class的{@link ExcelProperty#value()}里面的表头的数量来决定行数, * 如果不传入class则默认为1.当然你指定了headRowNumber不管是否传入class都是以你传入的为准。 */ @Test public void complexHeaderRead() { String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx"; // 这里 需要指定读用哪个class去读,然后读取第一个sheet EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).sheet() // 这里可以设置1,因为头就是一行。如果多行头,可以设置其他值。不传入也可以,因为默认会根据DemoData 来解析,他没有指定头,也就是默认1行 .headRowNumber(1).doRead(); }

也可以获取读到的excel中的内容

不过这样会把数据加载到内存中

/**
     * 同步的返回,不推荐使用,如果数据量大会把数据放到内存里面
     */
    @Test
    public void synchronousRead() {
        String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";
        // 这里 需要指定读用哪个class去读,然后读取第一个sheet 同步读取会自动finish
        List<DemoData> list = EasyExcel.read(fileName).head(DemoData.class).sheet().doReadSync();
        for (DemoData data : list) {
            LOGGER.info("读取到数据:{}", JSON.toJSONString(data));
        }
        // 这里 也可以不指定class,返回一个list,然后读取第一个sheet 同步读取会自动finish
        List<Map<Integer, String>> listMap = EasyExcel.read(fileName).sheet().doReadSync();
        for (Map<Integer, String> data : listMap) {
            // 返回每条数据的键值对 表示所在的列 和所在列的值
            LOGGER.info("读取到数据:{}", JSON.toJSONString(data));
        }
    }

具体还是要看github上的官方文档
https://github.com/alibaba/easyexcel

你可能感兴趣的:(JAVA)