easyExcel读取excel文件

简介

Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。
easyexcel重写了poi对07版Excel的解析,一个3M的excel用POI sax解析依然需要100M左右内存,改用easyexcel可以降低到几M,并且再大的excel也不会出现内存溢出;03版依赖POI的sax模式,在上层做了模型转换的封装,让使用者更加简单方便。

本文只介绍最简单的读取,写入和其他复杂操作可参考官方文档;
官方文档地址:**https://easyexcel.opensource.alibaba.com/docs/current/quickstart/read

读取功能实现

依赖(pom)

<properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <java.version>1.8</java.version>
    </properties>

    <parent>
        <artifactId>spring-boot-starter-parent</artifactId>
        <groupId>org.springframework.boot</groupId>
        <version>2.2.6.RELEASE</version>
    </parent>

    <dependencies>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
        </dependency>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>3.1.2</version>
        </dependency>

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-boot-starter</artifactId>
            <version>3.0.0</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>2.3.3</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

    </dependencies>

引入swagger依赖用作测试。

添加启动类和配置文件

@SpringBootApplication
@EnableOpenApi
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class,args);
    }
}
server:
  port: 8081
spring:
  application:
    name: netty-test-01
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai&characterEncoding=utf-8
    username: root
    password: root

读取监听器

package com.test.netty;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.util.ListUtils;
import com.test.netty.pojo.DataDto;
import com.test.netty.service.DataService;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
@Slf4j
public class ExcelListener extends AnalysisEventListener<DataDto> {

    private DataService dataService;

    private static final int BATCH_COUNT = 5;

    private List<DataDto> dataDtos = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

    public ExcelListener() {
        this.dataDtos = new ArrayList<>();
    }

    public ExcelListener(DataService dataService) {
        this.dataService = dataService;
    }

    @Override
    public void invoke(DataDto dto, AnalysisContext analysisContext) {
        log.info("read data:{},invoke size:{}",dto.toString(),dataDtos.size());
        dataDtos.add(dto);
        if (dataDtos.size() >= BATCH_COUNT){
            saveData();
            log.info("客户端用户id:{},用户名:{},用户真实姓名:{},手机号:{}",dto.getClientId(),dto.getUsername(),dto.getRealName(),dto.getPhone());
            dataDtos = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        int size = dataDtos.size();
        saveData();
        log.info("full size:{}",size);
    }

    private void saveData(){
        dataService.insertBatch(dataDtos);
        log.info("{}条数据,开始存储数据库",dataDtos.size());
    }
}

补充一下实体类

@Data
public class DataDto {
    private int clientId;

    private String username;

    private String realName;

    private String phone;
}

建表sql:

CREATE TABLE `data_dto`(
`id` int(10) not null auto_increment comment 'id',
`client_id` VARCHAR(50) DEFAULT null COMMENT '客户端用户id',
`username` VARCHAR(20) DEFAULT null COMMENT '用户名',
`real_name` VARCHAR(50) DEFAULT null COMMENT '用户名',
`phone` VARCHAR(50) DEFAULT null COMMENT '手机号',
PRIMARY KEY (`id`)
)

写接口测试一下

package com.test.netty.controller;


import com.alibaba.excel.EasyExcel;
import com.test.netty.ExcelListener;
import com.test.netty.pojo.DataDto;
import com.test.netty.service.DataService;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;

@RestController
@RequestMapping("excel")
@Api(tags = "excel操作")
public class ExcelController {

    @Autowired
    private DataService dataService;

    @PostMapping("upload")
    public void upload(@RequestPart("file") MultipartFile file)throws IOException {
        EasyExcel.read(file.getInputStream(), DataDto.class,new ExcelListener(dataService)).autoCloseStream(true).sheet().doRead();
    }


}

package com.test.netty.service;

import com.baomidou.mybatisplus.service.IService;
import com.test.netty.pojo.DataDto;

public interface DataService extends IService<DataDto> {
}

package com.test.netty.service.impl;

import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.test.netty.mapper.DataMapper;
import com.test.netty.pojo.DataDto;
import com.test.netty.service.DataService;
import org.springframework.stereotype.Service;

@Service
public class DataServiceImpl extends ServiceImpl<DataMapper, DataDto> implements DataService {
}

这里直接使用了mybatisPlus的通用方法,不用mybatisPlus的可以写一个批量插入方法

验证

启动项目后,浏览器打开,输入ocalhost:8081/swagger-ui/,进入swagger测试页面
easyExcel读取excel文件_第1张图片
选择文件后执行,成功后查看数据库数据都有。

你可能感兴趣的:(excel,java)