easyExcel读取excel文件

2023-09-18 10:48:07

简介

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测试页面
在这里插入图片描述
选择文件后执行,成功后查看数据库数据都有。

更多推荐

Spark的基础

实训笔记--Spark的基础Spark的基础一、Spark的诞生背景二、Spark概念2.1SparkCore2.2.SparkSQL2.3SparkStreaming2.4SparkMLlib2.5SparkGraphX2.6SparkR三、Spark的特点3.1计算快速3.2易用性3.3兼容性3.4通用性四、Spa

Java IO 之 BIO、NIO 和 AIO

一、IOIO是Input和Output二词的缩写,意为输入和输出,直接来说,实现一般的I/O是没有什么难度的,但涉及到多线程时,要解决I/O的问题就不是一个简单的事情了,会涉及到同步和异步的问题,阻塞和非阻塞的问题。1.1同步和异步同步可以借用多线程来方便理解,多条线程,从字面意思上来看,当他们在同一直线上时,就是同步

mysql---视图详解

提示:视图最大的优点用来协助用户提高查询效力以及保护数据安全文章目录视图视图的作用:创建视图单表创建视图多表创建视图查看视图更新视图数据修改视图删除视图视图视图(View)是一个虚拟表,其内容由select查询定义。同真实的表一样,是一个select查询的结果集,所有数据来源于基表视图其实就是一个select返回的结果

写一篇nginx配置指南

nginx.conf配置找到Nginx的安装目录下的nginx.conf文件,该文件负责Nginx的基础功能配置。配置文件概述Nginx的主配置文件(conf/nginx.conf)按以下结构组织:配置块功能描述全局块与Nginx运行相关的全局设置events块与网络连接有关的设置http块代理、缓存、日志、虚拟主机等

分布式电源接入对配电网影响分析(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。⛳️座右铭:行百里者,半于九十。📋📋📋本文目录如下:🎁🎁🎁目录💥1概述📚2运行结果🎉3参考文献🌈4Matlab代码、数据、文章💥1概述分布式电源的接入将配电系统从传统的无源放射

极简解析!IP计费的s5爬虫IP

大家好!今天我将为大家分享关于s5爬虫IP服务的知识。对于经常做爬虫的小伙伴来说,需要大量的爬虫IP支持爬虫业务,那么对于选择什么样的爬虫IP,我想我有很多发言权。下面我们一起了解下IP计费的s5爬虫IP的知识,废话不多说,让我们开始吧!第一部分:了解s5爬虫和IP计费首先,让我们简单了解一下s5爬虫和IP计费是什么。

最新AI系统ChatGPT源码+支持OpenAI全模型+国内AI模型+AI绘画

一、SparkAI智能创作系统SparkAi创作系统是基于国外很火的ChatGPT进行开发的Ai智能问答系统。本期针对源码系统整体测试下来非常完美,可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作ChatGPT?小编这里写一个详细图文教程吧!SparkAi程序使用Ne

【AI语言大模型】星火使用介绍

一、前言现在AI语言大模型是百花齐放,挺好!有竞争,有发展,才能推出更好的产品。现在,科大讯飞就推出了大语言模型——星火!能够学习和理解人类的语言,进行多轮对话,回答问题,高效便捷地帮助人们获取信息、知识和灵感。星火在对话栏设置了三个插件:文档回答、PPT生成、简历生成,下面详细介绍三个插件的用法。二、插件介绍如下图所

9 种方法使用 Amazon CodeWhisperer 快速构建应用

AmazonCodeWhisperer是一款很赞的生成式人工智能编程工具。自从在工作中使用了CodeWhisperer,我发现不仅代码编译的效率有所提高,应用开发的工作也变得快乐起来。然而,任何生成式AI工具的有效学习都需要初学者要有接受新工作方式的心态和意愿。AmazonCodeWhispererAICodeGene

一篇关于vue的入门的详细介绍

目录一.介绍二.库和框架的区别三.什么是MVVM模式四.实例4.1.Vue开发示例4.2.双向数据绑定4.3.生命周期好啦,今天的分享就到这了,希望能够帮到你呢!😊😊一.介绍Vue.js是一种流行的JavaScript框架,用于构建用户界面。它被设计为一个渐进式框架,可以逐步应用到现有项目中,也可以作为一个完整的单

【JVM】Java类的加载机制!

一、类的生命周期类加载过程包含:加载、验证、准备、解析和初始化,一共包括5个阶段。(1)加载:简单来说就是将java类的字节码文件加载到机器内存中。在加载类时,Java虚拟机必须完成以下3件事情:通过类的完全限定名称获取定义该类的二进制字节流。将该字节流表示的静态存储结构转换为Metaspace元空间区的运行时存储结构

热文推荐