easyexcel读取excel将数据存到mysql【一个简单的例子】

2023-11-18

读取excel

1 xml里面增加maven

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

2 读取excel用到的实体

自行更改字段

package com.hahaha.dto;

import com.alibaba.excel.annotation.ExcelProperty;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@EqualsAndHashCode
public class ReadExcelDto {

    /**
     * 账期
     * 用名字去匹配,这里需要注意,如果名字重复,会导致只有一个字段读取到数据
     */
    @ExcelProperty("账期")
    private String month;

	/**
     * 强制读取第三列 这里不建议 index 和 name 同时用,要么一个对象只用index,要么一个对象只用name去匹配
     */
    @ExcelProperty(index = 2)
    private Double doubleData;
   
    /**
     * 姓名
     */
    @ExcelProperty(value = "姓名")
    private String name;
}

3 读取excel用到的监听器

package com.hahaha.util.easyexcel;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
import com.hahaha.service.CommonExcelReadService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

/**
 * 公共的excel读取监听器
 * @param <T> 实体范型
 */
public class CommonReadListener<T> extends AnalysisEventListener<T> {
    private static final Logger LOGGER = LoggerFactory.getLogger(CommonReadListener.class);
    /**
     * 每隔1000条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收
     */
    private static final int BATCH_COUNT = 1000;
    List<T> list = new ArrayList<>();
    /**
     * 假设这个是一个DAO,当然有业务逻辑这个也可以是一个service。当然如果不用存储这个对象没用。
     */
    private CommonExcelReadService service;

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

    /**
     * 这个每一条数据解析都会来调用
     *
     * @param data
     *            one row value. Is is same as {@link AnalysisContext#readRowHolder()}
     * @param context context
     */
    @Override
    public void invoke(T data, AnalysisContext context) {
        LOGGER.info("解析到一条数据:{}", JSON.toJSONString(data));
        list.add(data);
        // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
        if (list.size() >= BATCH_COUNT) {
            saveData();
            // 存储完成清理 list
            list.clear();
        }
    }

    /**
     * 所有数据解析完成了 都会来调用
     *
     * @param context context
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 这里也要保存数据,确保最后遗留的数据也存储到数据库
        saveData();
        LOGGER.info("所有数据解析完成!");
    }

    /**
     * 加上存储数据库
     */
    private void saveData() {
        LOGGER.info("{}条数据,开始存储数据库!", list.size());
        Integer num = service.saveBatchData(list);
        LOGGER.info("存储数据库成功数量为:{}", num);
    }
}

将数据都读取到内存中的监听器

package com.hahaha.util.easyexcel;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

/**
 * 公共的excel读取监听器
 * @param <T> 实体范型
 */
public class CommonReadListener2<T> extends AnalysisEventListener<T> {
    private static final Logger LOGGER = LoggerFactory.getLogger(CommonReadListener2.class);

    List<T> list = new ArrayList<>();

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

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        LOGGER.info("所有数据解析完成!");
    }

    /**
     * 获取excel的所有数据,数据量太大会出现内存溢出
     * @return list
     */
    public List<T> getList() {
        return list;
    }

}

4 读取excel用到的公共service

package com.hahaha.service;

import java.util.List;

/**
 *
 * 公共的excel读取接口
 * 实现接口并重写saveBatchData方法即可保存自定义的业务数据
 */
public interface CommonExcelReadService {

    /**
     * 批量保存数据
     * @param list 要保存的数据
     * @param <T> 数据类型实体,可以根据具体的业务实体转换
     * @return Integer 保存成功的条数
     */
    public <T> Integer saveBatchData(List<T> list);
}

5 读取excel用到的公共方法

package com.hahaha.util.easyexcel;

import com.alibaba.excel.EasyExcel;
import com.hahaha.service.CommonExcelReadService;

import java.io.InputStream;

/**
 * excel工具类
 */
public class EasyExcelUtil {

    /**
     * 这种是 内存溢出出现的情况非常低,但是事务不好控制(主要是出错全部回滚)
     * @param inputStream 文件流
     * @param clazz 读取excel的实体class
     * @param commonService 将数据存储到某张表的service【需要在业务service上实现这个接口,并重写saveBatchData方法】
     * @param <T> 泛型类型
     */
    public static <T> void readExcel(InputStream inputStream, Class<?> clazz, CommonExcelReadService commonService) {
        CommonReadListener readExcelDataListener = new CommonReadListener(commonService);

        EasyExcel.read(inputStream, clazz, readExcelDataListener)
                .sheet()
                .doRead();
    }
    
    /**
     * 这种是 将数据都读取到内存中
     * 事务好控制,但是数据量太大绝对会出现内存溢出
     * @param inputStream 文件流
     * @param clazz 读取excel的实体class
     * @param <T> 泛型类型
     */
    public static <T> List<T> readExcel(InputStream inputStream, Class<?> clazz) {
        CommonReadListener2 readExcelDataListener = new CommonReadListener2();

        EasyExcel.read(inputStream, clazz, readExcelDataListener)
                .sheet()
                .doRead();

        return readExcelDataListener.getList();
    }
}

6

controller接口

package com.hahaha.controller;

import javax.annotation.Resource;
import com.hahaha.util.easyexcel.EasyExcelUtil;
import org.springframework.web.multipart.MultipartFile;

@RestController
public class MyController {

	@Resource
    private MyService myService;

	@PostMapping("upload")
    public 你的返回结构 upload(MultipartFile file) {
    	// 校验文件格式和大小的
        CommonMethod.uploadVerify(file);
        try {
        // todo ReadExcelDto是读取excel的dto,改成自己的;myService改成自己的
            EasyExcelUtil.readExcel(file.getInputStream(), ReadExcelDto.class, myService);
        } catch (IOException o){
            log.error(o.getMessage());
            返回错误信息
        }
        return 返回正确信息
    }
}

校验文件格式和大小看这个
https://blog.csdn.net/lh155136/article/details/126585728

7 业务service和serviceIml

我这个是有mybatisplus的,如果不需要可以去掉

package com.hahaha.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.hahaha.entity.MyEntity;
import com.hahaha.service.CommonExcelReadService;

// todo 这里非常重要,一定要实现CommonExcelReadService 
public interface MyService extends IService<MyEntity>, CommonExcelReadService {

}
package com.hahaha.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hahaha.dto.ReadExcelMIITDto;
import com.hahaha.entity.MyEntity;
import com.hahaha.mapper.MyMapper;
import com.hahaha.service.MyService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Service
public class MyServiceImpl extends ServiceImpl<MyMapper, MyEntity> implements MyService {

    @Resource
    private MyMapper myMapper;

    @Override
    public <T> Integer saveBatchData(List<T> list) {
        List<ReadExcelDto> entityList = JSONObject.parseArray(JSONObject.toJSONString(list),
                ReadExcelDto.class);

        return myMapper.saveBatchList(entityList);
    }
}

7 mapper和mapper.xml

我是手写了一个insertbatch方法,也可以用mybaits-plus的savebatch

package com.hahaha.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.hahaha.dto.ReadExcelMIITDto;
import com.hahaha.entity.MyEntity;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface MyMapper extends BaseMapper<MyEntity> {

    int saveBatchList(List<ReadExcelDto> list);
}
	<insert id="saveBatchList">
        INSERT INTO 你的表名字 (
            month,
            name
        )
        VALUES
        <foreach collection="list" item="obj" separator=",">
            (
                #{obj.month},
                #{obj.name}
            )
        </foreach>
	</insert>

测试

在这里插入图片描述

在这里插入图片描述
其他难度的后面再更新,有疑问的欢迎评论

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

easyexcel读取excel将数据存到mysql【一个简单的例子】 的相关文章

  • MySQL 左连接 WHERE table2.field = "X"

    我有以下表格 pages Field Type Null Key Default Extra page id int 11 NO PRI NULL auto increment type varchar 20 NO NULL
  • 获取mysql中逗号分隔行中不同值的计数

    一个表 Jobs 有 2 列 JobId 城市 当我们保存工作时 工作位置可能是多个城市 如下所示 JobId City 1 New York 2 New York Ohio Virginia 3 New York Virginia 我如何
  • MySQL 和 PHP 参数 1 作为资源

    好吧 当我运行下面提到的代码时 PHP 向我抛出此错误 在日志中 Error mysql num rows 期望参数 1 为资源 第 10 行 place 中给出的字符串 9 11号线 queryFP SELECT FROM db coun
  • NHibernate - 无法执行查询 - 输入字符串的格式不正确

    我已经为此摸不着头脑有一段时间了 我不知道出了什么问题 概述 我的 MySQL 数据库中有两个表 两者都正确映射到数据库 我可以加载数据 并且我能够查询一个表 但不能查询另一个表 我研究过的解决方案 表和 C 代码之间的类型转换问题 映射问
  • MVCC 如何与 MySql 中的 Lock 配合使用?

    我知道Mysql中使用锁或者MVCC可以实现并发控制 比如可重复读 但我不知道MVCC如何避免幻读 在其他地方了解到一般是通过MVCC和Gap Lock来实现的 但是目前我理解的是MVCC不需要锁 即更新和删除都是使用undo log来实现
  • MySQL正则表达式:如何将字符串中的数字与\d匹配?

    我有一个专栏release date它以字符串格式存储日期 不是 DATETIME 格式 因为它们有时可以是任何其他字符串文字 我想根据给定的月份和年份查找任意日期的所有记录 尝试遵循但对我不起作用 gt Post find all con
  • numpy NPV 和 Excel NPV 有区别吗?

    我的 Excel 中有一行包含 11 个值 TotalSavings 0 8000 8000 8000 8000 8000 8000 8000 8000 8000 8000 贴现率为 0 08 我在 Excel 中使用 计算 NPVNPV
  • Mysql带限制的删除语句

    我试图从表中删除行 但出现错误 DELETE FROM chat messages ORDER BY timestamp DESC LIMIT 20 50 我在 50 时收到此错误 您的 SQL 语法有错误 检查与您的 MySQL 服务器版
  • 支持 >65k 行的 Excel VBA SQL 驱动程序

    在 Excel 2010 中通过 VBA 查询 Excel 数据时 我遇到一个有趣的问题 我正在使用这些驱动程序连接到 xls 或 xls x m 文件 Sub OpenCon ByRef theConn As Connection ByV
  • 启动时的 Excel 加载项

    我正在使用 Visual C 创建 Microsoft Excel 的加载项 当我第一次创建解决方案时 它包含一个名为 ThisAddIn Startup 的函数 我在这个函数中添加了以下代码 private void ThisAddIn
  • MySQL 概念:会话与连接

    我对 MySQL 的概念有点困惑 会话与连接 当谈论连接到 MySQL 时 我们使用连接术语 连接池等 然而在 MySQL 在线文档中 http dev mysql com doc refman 4 1 en server system v
  • 休眠以持久保存日期

    有没有办法告诉 Hibernate java util Date 应该持久保存 我需要这个来解决 MySQL 中缺少的毫秒分辨率问题 您能想到这种方法有什么缺点吗 您可以自己创建字段long 或者使用自定义的UserType 实施后User
  • 使用什么框架来引导我的第一个生产 scala 项目?

    我正在第一次涉足 scala 的生产应用程序 该应用程序当前打包为 war 文件 我的计划是创建 scala 编译工件的 jar 文件 并将其添加到 war 文件的 lib 文件夹中 我的增强功能是通过 Jersey 公开的 mysql 支
  • VBA 架构技巧 - 宏封装

    我拼凑了 Excel 的概念证明 以从数据库获取数据 并需要将其打包 以便可以将其分发给我们的客户 我的第一次尝试只是将所有代码放入代码模块中 但随后在 Excel 中我可以看到宏列表中的所有模块 而我实际上只想要列表中的主要模块 我猜想我
  • MySQL InnoDB 约束不起作用

    我偶然发现 innoDB 约束的奇怪行为 但找不到原因 我有包含数据的表格 下面列出了它们的结构 CREATE TABLE contents id int 10 unsigned NOT NULL AUTO INCREMENT title
  • CakePHP 查找 - 按字符串到整数排序?

    我想使用 CakePHP 从数据库中提取照片数组 按照片标题排序 0 1 2 3 我的查询当前看起来像 ss photos this gt Asset gt find all array conditions gt array kind g
  • 来自数据库的 jfreechart 散点图

    如何使用java中的jfreechart绘制mysql数据库表中数据的散点图 我使用过 Swing 库 任何链接都会有帮助 我搜索了谷歌但找不到理解的解决方案 如果您有代码 请提供给我 实际上我确实做了条形图并使用 jfreechart 绘
  • 选择获取与 MySQL Group 中 max 对应的整行

    当我使用Max使用后查找特定 MySQL 组中字段的最大值GROUP BY 是否可以获取包含最大值的整行 我在处理一些论坛代码时偶然发现了这个线程 我想获取每个线程的最新帖子并将其显示在特定板的线程列表中 Quassnoi上面的回答对我非常
  • 如何修复日期过滤器 VBA,因为它没有拾取我范围内的所有日期

    我正在尝试创建一个过滤器来过滤掉我选择的日期内的所有日期 我选择的日期将始终反映整个月 例如 如果我需要 2019 年 5 月的数据 我将输入开始日期为 01 05 2019 结束日期为 31 05 2019 我的数据过滤器将需要选取经过我
  • 使用 PHP 将 latin1_swedish_ci 转换为 utf8

    我有一个数据库 里面充满了类似的值 Dhaka 应该是 Dhaka 因为我在创建数据库时没有指定排序规则 现在我想修复它 我无法从最初获取数据的地方再次获取数据 所以我在想是否可以在 php 脚本中获取数据并将其转换为正确的字符 我已将数据

随机推荐

  • 【OpenGL进阶】04.支持多贴图的Shader

    这篇文章来实现一下多贴图的效果 在这篇文章中 再次对代码进行了封装 是代码看起来更加清晰明了 shader h中添加了SetTexture接口 pragma once include ggl h struct UniformTexture
  • [canvas] 坐标旋转

    坐标旋转 做圆周运动 vr 0 1 angle 0 radius 100 centerX 0 centerY 0 object x centerX Math sin angle radius object y centerY Math co
  • git报错:warning: unable to access

    git操作的时候出现该错误 warning unable to access Users a10 12 config git ignore Permission denied warning unable to access Users a
  • 一个女孩的就业之路(同济大学BBS上两年不沉的帖子)

    文章很长 有机会见到这篇文章的童鞋 希望能耐心看完 其他不多说 我是2005年毕业的 偶尔来这里看看 不常灌水 今天来随意写下一些 如果对各位有任何的帮助 是我衷心所愿 1 考研与就业 2004年的暑假 我和大多数人一样 艰难的抉择 究竟是
  • NacosValue 注解

    NacosValue 定义在 nacos api 工程中 com alibaba nacos api config annotation NacosValue 注解解析在 nacos spring project 工程中 com aliba
  • 阻塞队列java实现

    阻塞队列 目前队列存在的问题 1 很多场景要求分离生产者和消费者两个角色 它们得由不同的线程来担当 而之前的实现根本没有考虑线程安全问题 2 队列为空 那么在之前的实现里会返回null 如果硬拿到一个元素 只能不断循环尝试 3 队列为满 那
  • PHP魔术方(2)

    PHP魔术方 2 文章目录 PHP魔术方 2 1 toString 和 invoke tostring 和 invoke 两者的触发形式接近 2 call 用来检测所调用的成员方法是否存在 3 callStatic 4 get 5 set
  • 在Linux系统上用C++将主机名称转换为IPv4、IPv6地址

    在Linux系统上用C 将主机名称转换为IPv4 IPv6地址 功能 指定一个std string类型的主机名称 函数解析主机名称为IP地址 含IPv4和IPv6 解析结果以std vector
  • vue div高度自适应

    1 在 js文件中编写自定义指令 export default install Vue 在组件标签上绑定 v resizable 指令 并使用对象的形式通过绑定值传递宽度和高度以及最大 最小高度的值 在 bind 函数中 获取传递的值 并根
  • 走进区块链企业 I 用实践赋能实体产业,坚持提供价值服务的旺链科技

    作为华东师范大学MBA高材生 他在高科技制造 金融行业有着超过16年的业务咨询管理和技术架构经验 他是中国云体系产业创新联盟理事会常务理事 边缘计算产业联盟专家委员 也是原 Accenture资深总监 集成技术专家 而在如今话题正盛的 区块
  • linux创建,恢复和删除screen

    学习记录 侵删 目录 1 创建 2 恢复 3 删除 使用服务器训练模型时 如果服务器断开 之前的训练结果显示的终端就不好找到了 貌似可以通过线程去恢复 没试过 可以使用screen 训练前先打开一个screen 如果服务器断开 重连后可以恢
  • 最新免费版 Office 全家桶Copilot,Gamma+MindShow 两大ChatGPT AI创意工具GPT-4神器助力高效智能制作 PPT,一键生成,与AI智能对话修改PPT(免安装)

    目录 前言 ChatGPT MindShow 1 使用ChatGPT工具生成PPT内容 2 使用MindShow工具一键智能制作PPT MindShow简介 使用网页版制作 pdf转ppt GAMMA AI神器 GAMMA app介绍 注册
  • MySQL基础篇:sql_mode配置

    文章目录 零 简介 一 sql mode常用来解决的几类问题 二 sql mode包含的模式 三 sql mode各个选项作用示例 3 1 sql mode为空 对于不符合定义的值 会截断到符合定义类型 3 2 sql mode为ANSI
  • 编程语言用 Java 开发一个打飞机小游戏(附完整源码)

    编程语言用 Java 开发一个打飞机小游戏 附完整源码 上图 写在前面 技术源于分享 所以今天抽空把自己之前用java做过的小游戏整理贴出来给大家参考学习 java确实不适合写桌面应用 这里只是通过这个游戏让大家理解oop面向对象编程的过程
  • 【React】路由(详解)

    目录 单页应用程序 SPA 路由 前端路由 后端路由 路由的基本使用 使用步骤 常用组件说明 BrowserRouter和HashRouter的区别 路由的执行过程 默认路由 精确匹配 Switch的使用 重定向路由 嵌套路由 向路由组件传
  • 计算机网络体系结构 - 运输层

    一 运输层协议概述 运输层为应用进程之间提供端到端的逻辑通信 二 运输层的端口 端口 port 也称为协议端口号 protocol port number 对上层的应用进程进行标识 端口用一个16位端口号进行标志 端口号只具有本地意义 端口
  • 剑指offer-输出字符串所有种类的排列组合

    常规题 先校验长度 不符合则直接输出 符合则判断是否为最后一个字符 是则直接new对象输出 不是则交换begin和i位置的数字 再用递归输出 public class Test28 先校验 public static void permut
  • 笔试

    文章目录 前言 40 复位电路设计 1 recovery time和removal time 2 同步复位和异步复位 3 异步复位同步释放 本文参考 往期精彩 前言 嗨 今天来学习复位电路设计相关问题 微信关注 FPGA学习者 获取更多精彩
  • cec2017(python):红狐优化算法(Red fox optimization,RFO)求解cec2017

    一 红狐优化算法 红狐优化算法 Red fox optimization RFO 由Dawid Po ap和 Marcin Wo niak于2021年提出 该算法模拟了红狐的狩猎行为 具有收敛速度快 寻优精度高等优势 参考文献 Poap D
  • easyexcel读取excel将数据存到mysql【一个简单的例子】

    读取excel 1 xml里面增加maven