大型项目技术栈第六讲 EasyExcel的使用

EasyExcel的使用

一、EasyExcel

1.EasyExcel简介

  • easyExcel是阿里巴巴开源poi插件之一,当前最新版本2.1.3,poi版本3.17
  • 主要解决了poi框架使用复杂,sax解析模式不容易操作,数据量大起来容易OOM,解决了POI并发造成的报错

2.EasyExcel优势

  • 注解式自定义操作。
  • 输入输出简单,提供输入输出过程的接口
  • 支持一定程度的单元格合并等灵活化操作

3.EasyExcel开发示例

3.1 导入依赖包


     com.alibaba
     easyexcel
     2.1.3

3.2 创建实体类

实体类对需要导出或者导入的字段增加@ExcelProperty注解,index值为对应excel中的列,value为表头,format为日期格式化

public class PersonDto{
    /** id */
    @ExcelProperty(index = 0 , value = "id")
    private String id;
    /** 姓名 **/
    @ExcelProperty(index = 1 , value = "姓名")
    private String name;
    /** 生日 **/
    @ExcelProperty(index = 2 , value = "生日" , format = "yyyy-MM-dd")
    //新版本提供了一个@com.alibaba.excel.annotation.format.DateTimeFormatDateTimeFormat替代format属性
    private String birth;
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getBirth() {
        return birth;
    }

    public void setBirth(String birth) {
        this.birth = birth;
    }
}

3.3 写excel

测试类:

public class TestExcel {

    private List createModelList() {
        List PersonDtos = new ArrayList<>();

        for (int i = 0; i < 100; i++) {
            PersonDto personDto = new PersonDto();
            personDto.setName("学Java"+i);
            personDto.setId(""+i);
            personDto.setBirth(new Date().toString());
            PersonDtos.add(personDto);
        }

        return PersonDtos;
    }
    /**
 * 最简单的写
 * 

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

2. 直接写即可 */ @Test public void simpleWrite() { // 写法1 String fileName = "D:\\person.xlsx"; // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭 // 如果这里想使用03 则 传入excelType参数即可 EasyExcel.write(fileName, PersonDto.class).sheet("模板").doWrite(createModelList()); // 写法2 fileName = "D:\\person.xlsx"; // 这里 需要指定写用哪个class去写 ExcelWriter excelWriter = EasyExcel.write(fileName, PersonDto.class).build(); WriteSheet writeSheet = EasyExcel.writerSheet("模板").build(); excelWriter.write(createModelList(), writeSheet); /// 千万别忘记finish 会帮忙关闭流 excelWriter.finish(); } }

3.4读excel

AnalysisEventListener:
读取excel必须提供一个监听类继承该抽象类

public void invoke(PersonDto data, AnalysisContext context) 
在读取excel的每一行,都会去调用该监听器的invoke方法,自动传入解析好的java对象

public void doAfterAllAnalysed(AnalysisContext context)
在读取excel结束的时候,会调用该方法

3.4.1 PersonDtoListener



import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;

import java.util.ArrayList;
import java.util.List;

public class PersonDtoListener extends AnalysisEventListener {
    /**
     * 每隔5条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收
     */
    private static final int BATCH_COUNT = 5;
    List list = new ArrayList();
    /**
     * 假设这个是一个DAO,当然有业务逻辑这个也可以是一个service。当然如果不用存储这个对象没用。
     */
    private PersonDao personDao;

    public PersonDtoListener() {

    }

    /**
     * 官方问题提到不能用spring管理该监听器对象,所以不能直接用依赖注入注解注入
     * 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来
     *
     * @param personDAO
     */
    public PersonDtoListener(PersonDao personDAO) {
        this.personDao = personDAO;
    }

    /**
     * 这个每一条数据解析都会来调用
     *
     * @param data
     *            one row value. Is is same as {@link AnalysisContext#readRowHolder()}
     * @param context
     */

    public void invoke(PersonDto data, AnalysisContext context) {

        list.add(data);
        // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
        if (list.size() >= BATCH_COUNT) {
            saveData();
            // 存储完成清理 list
            list.clear();
        }
    }

    /**
     * 所有数据解析完成了 都会来调用
     *
     * @param context
     */

    public void doAfterAllAnalysed(AnalysisContext context) {
        // 这里也要保存数据,确保最后遗留的数据也存储到数据库
        saveData();

    }

    /**
     * 加上存储数据库
     */
    private void saveData() {
        System.out.println(list);
        personDao.save(list);

    }
}

3.4.2 测试类

    /**
     * 最简单的读
     * 

1. 创建excel对应的实体对象 参照{@link cn.nyse.entity.PersonDto} *

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

3. 直接读即可 */ @Test public void simpleRead() { // 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去 // 写法1: String fileName = "F:\\dfbz\\课件2.0\\guguanjia2.0\\some.xlsx"; // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭 EasyExcel.read(fileName, PersonDto.class, new PersonDtoListener()).sheet().doRead(); // 写法2: fileName = "F:\\dfbz\\课件2.0\\guguanjia2.0\\some.xlsx"; ExcelReader excelReader = EasyExcel.read(fileName, PersonDto.class, new PersonDtoListener()).build(); ReadSheet readSheet = EasyExcel.readSheet(0).build(); excelReader.read(readSheet); // 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的 excelReader.finish(); }

二、vue的文件上传

1.步骤

a.在input组件中添加点击事件@change=“upload”

b.在事件处理函数中传入事件对象,通过事件对象获取文件对象e.target.files[0]

c.创建表单对象let formData = new FormData();

d.放入文件对象 formData.append(“file”,e.target.files[0]);

d.通过axios设置请求头headers:{‘content-type’:‘multipart/form-data’}和提交方式post

e.后台通过上传对象MultipartFile file接受

页面:

后台

@RequestMapping("importExcel")
    public void importExcel(@RequestParam("file")MultipartFile file){
        System.out.println((file.getOriginalFilename()));
        。。。
    }

你可能感兴趣的:(大型项目技术栈汇总,java,excel)