通过Easy Excel导入数据

news2024/11/28 2:55:55

目录

  • 🍑一、背景
  • 🍑二、开发验证
    • 🍊2.1、引入easyexcel依赖
    • 🍊2.2、创建表及基础代码
    • 🍊2.3、处理类及接口
      • 🍓2.3.1、EasyExcel监听处理器
      • 🍓2.3.2、Controller接口
      • 🍓2.3.3、service调用监听器
    • 🍊2.4、启动项目,通过swagger接口测试
      • 🍓2.4.1、上传excel
      • 🍓2.4.2、excel详情
      • 🍓2.4.3、查看数据库验证
  • 🍑三、其它

🔼上一集:小钊记

🍑一、背景


大概2023年7月6号,整了一个180天倒计时(距离2024元旦),设定了一些计划,通过腾讯在线文档记录每天完成情况。突然想起来,今年五一的时候,搭建了一个系统,就是上面的小钊记,想着要不把180天倒计时计划表导入数据库,之前也做过解析excel,是通过poi,springboot 解析Excel(栏位与实体类一一对应),这次改用Easy Excel试一下,听名字就感觉比较简单。
在这里插入图片描述

🍑二、开发验证


🍊2.1、引入easyexcel依赖


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

🍊2.2、创建表及基础代码


  • 日常记录表
    DROP TABLE IF EXISTS `t_rxz_daily_record`;
    create table t_rxz_daily_record
    (
        id                     int not null auto_increment comment '主键',
        record_date            Date not null comment '记录日期',
        wake_up_time           time not null comment '起床时间',
        lunch_break_duration   varchar(50) not null comment '午休时长',
        hunger_before_bedtime  varchar(50) not null comment '睡前饿意',
        motion                 varchar(50) not null comment '运动',
        learning               varchar(50) not null comment '学习',
        sleep_time             varchar(50) not null comment '睡觉时间',
        explosive_red_rate     varchar(50) not null comment '爆红率',
        net_weight             FLOAT not null comment '净重',
        update_time            datetime default CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP comment '更新时间',
        primary key (id)
    );
    
  • 基础代码
    • entity

      package com.renxiaozhao.bean.entity;
      
      import java.io.Serializable;
      import java.sql.Time;
      import java.util.Date;
      
      import com.baomidou.mybatisplus.annotation.TableName;
      
      import io.swagger.annotations.ApiModelProperty;
      import lombok.Data;
      
       /**
       * 日常记录表实体.
       * @author : 韧小钊
       * @date : 2023-8-10
       */
      @Data
      @TableName("t_rxz_daily_record")
      public class DailyRecordEntity implements Serializable {
          private static final long serialVersionUID = 5252694875850308782L;
          
          /** 主键 */
          @ApiModelProperty(name = "主键",notes = "")
          private Integer id ;
          /** 记录日期 */
          @ApiModelProperty(name = "记录日期",notes = "")
          private Date recordDate ;
          /** 起床时间 */
          @ApiModelProperty(name = "起床时间",notes = "")
          private Time wakeUpTime ;
          /** 午休时长 */
          @ApiModelProperty(name = "午休时长",notes = "")
          private String lunchBreakDuration ;
          /** 睡前饿意 */
          @ApiModelProperty(name = "睡前饿意",notes = "")
          private String hungerBeforeBedtime ;
          /** 运动 */
          @ApiModelProperty(name = "运动",notes = "")
          private String motion ;
          /** 学习 */
          @ApiModelProperty(name = "学习",notes = "")
          private String learning ;
          /** 睡觉时间 */
          @ApiModelProperty(name = "睡觉时间",notes = "")
          private String sleepTime ;
          /** 爆红率 */
          @ApiModelProperty(name = "爆红率",notes = "")
          private String explosiveRedRate ;
          /** 净重 */
          @ApiModelProperty(name = "净重",notes = "")
          private Float netWeight ;
          /** 更新时间 */
          @ApiModelProperty(name = "更新时间",notes = "")
          private Date updateTime ;
          
      }
      
    • mapper

      package com.renxiaozhao.dao.mapper;
      
      import com.baomidou.mybatisplus.core.mapper.BaseMapper;
      import com.renxiaozhao.bean.entity.DailyRecordEntity;
      
      
      public interface DailyRecordMapper extends BaseMapper<DailyRecordEntity>{}
      
      
      
    • service接口及实现类

      package com.renxiaozhao.service.impl;
      
      import org.springframework.stereotype.Service;
      
      import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
      import com.renxiaozhao.bean.entity.DailyRecordEntity;
      import com.renxiaozhao.dao.mapper.DailyRecordMapper;
      import com.renxiaozhao.service.inf.DailyRecordService;
      
      @Service
      public class DailyRecordServiceImpl extends ServiceImpl<DailyRecordMapper, DailyRecordEntity>  implements DailyRecordService {}
      
      
      
      package com.renxiaozhao.service.inf;
      
      import com.baomidou.mybatisplus.extension.service.IService;
      import com.renxiaozhao.bean.entity.DailyRecordEntity;
      
      public interface DailyRecordService  extends IService<DailyRecordEntity>   {
          
      }
      
      
      

🍊2.3、处理类及接口


🍓2.3.1、EasyExcel监听处理器


  • 读取监听器(ReadListener): 在读取 Excel 文件之前,可以使用 BeforeReadListener 接口来处理读取开始前的事件。在每次读取一行数据时,可以使用 ReadListener 接口的 onRead 方法来处理读取到的数据。在读取完成后,可以使用 AfterReadListener 接口来处理读取结束后的事件。
  • 写入监听器(WriteListener): 在写入 Excel 文件之前,可以使用 BeforeWriteListener 接口来处理写入开始前的事件。在每次写入一行数据时,可以使用 WriteListener 接口的 onWrite 方法来处理要写入的数据。在写入完成后,可以使用 AfterWriteListener 接口来处理写入结束后的事件。
    分析监听器(AnalysisEventListener):
  • AnalysisEventListener: 是一种用于读取大量数据时的监听器接口。您可以实现 AnalysisEventListener 接口,并在 onRead 方法中处理读取到的每一行数据。EasyExcel 会将读取的数据分批处理,以减少内存消耗。

目前只用到了读取监听器,代码如下:

package com.renxiaozhao.service.impl;

import java.sql.Time;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.renxiaozhao.bean.entity.DailyRecordEntity;
import com.renxiaozhao.service.util.DateUtils;

import lombok.extern.slf4j.Slf4j;

/**
 * 初始化表格数据.
 */
@Slf4j
public class ExcelListener implements ReadListener<LinkedHashMap<Integer, String>> {

    List<DailyRecordEntity> dailyRecords = new ArrayList<>();

    @Override
    public void invoke(LinkedHashMap<Integer, String> rowData, AnalysisContext context) {
        DailyRecordEntity record = new DailyRecordEntity();
        try {
            // 记录日期
            record.setRecordDate(DateUtils.parseDate(rowData.get(0)));
            // 起床时间
            record.setWakeUpTime(Time.valueOf(rowData.get(1) + ":00"));
            // 午休时长
            record.setLunchBreakDuration(rowData.get(2));
            // 睡前饿意
            record.setHungerBeforeBedtime(rowData.get(3));
            // 运动
            record.setMotion(rowData.get(4));
            // 学习
            record.setLearning(rowData.get(5));
            // 睡觉时间
            record.setSleepTime(rowData.get(6));
            // 爆红率
            record.setExplosiveRedRate(rowData.get(7));
            // 净重
            record.setNetWeight(Float.parseFloat(rowData.get(8)));
        } catch (ParseException e) {
            log.error(rowData + "参数转化格式失败:",e);
        }
        dailyRecords.add(record);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {

    }

    public List<DailyRecordEntity> getDailyRecords() {
        return dailyRecords;
    }
    
}

🍓2.3.2、Controller接口


@PostMapping("/exportRecord")
    @ApiOperation(value = "导入每日记录信息", notes = "导入每日记录信息")
    public Result<String> exportRecord(@RequestParam("file") MultipartFile file) {
        try {
            sportRecordService.exportRecord(file);
            return Result.success();
        } catch (Exception e) {
            log.error("导入记录数据异常", e);
            return Result.error("导入记录数据异常" + e.getMessage());
        }
    }

在这里插入图片描述

🍓2.3.3、service调用监听器


支持多个sheet,每遍历完一个记得清空数据,图中listener.getDailyRecords().clear() 是在清空 listener 对象中的 dailyRecords 数据,以便在处理下一个 sheet 时,相关数据不会重叠或占用过多的内存。
在这里插入图片描述

@Override
    public void exportRecord(MultipartFile file) {
        String message = "共导入%s个月记录,成功%s,失败%s";
        StringBuilder failMessages = new StringBuilder();
        InputStream inputStream = null;
        ExcelReader excelReader = null;
        try {
            inputStream = file.getInputStream();
            ExcelListener listener = new ExcelListener();
            excelReader = EasyExcel.read(inputStream).registerReadListener(listener).build();
            //获取sheet页
            List<ReadSheet> readSheets = excelReader.excelExecutor().sheetList();
            int success = 0;
            int fail = 0;
            for (ReadSheet readSheet : readSheets) {
                String sheetName = readSheet.getSheetName();
                //读取excel数据
                excelReader.read(readSheet);
                List<DailyRecordEntity> records = listener.getDailyRecords();
                try {
                    if (records != null && records.size() > 0) {
                        //保存表信息
                        boolean flag = dailyRecordService.saveBatch(records);
                        if (flag) {
                            success++;
                        }
                    }
                } catch (Exception e) {
                    log.error("插入数据错误", e);
                    failMessages.append("sheet ").append(sheetName).append(":").append(e.getMessage()).append(";");
                    fail++;
                } finally {
                    listener.getDailyRecords().clear();
                }
            }
            message = String.format(message, success + fail, success, fail);
            if (!StringUtils.isEmpty(failMessages.toString())) {
                log.error(failMessages.toString());
            }
        } catch (Exception e) {
            log.error("读取文件失败", e);
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    log.error("读取文件失败", e);
                }
            }
            if (excelReader != null) {
                excelReader.finish();
            }
        }
    }

🍊2.4、启动项目,通过swagger接口测试


🍓2.4.1、上传excel


在这里插入图片描述

🍓2.4.2、excel详情


导出腾讯在线文档,按照月份划分sheet,详情如下:

  • 7月
    在这里插入图片描述- 8月
    在这里插入图片描述

🍓2.4.3、查看数据库验证


成功登记了7、8月份的数据
在这里插入图片描述

🍑三、其它


确实简单好用!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/858373.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue3使用wangEditor

那么这一节我们在编辑公司信息的弹窗中使用富文本插件wangEditor官网 Vue3使用wangEditor 安装wangEditor在弹窗中引入wangEditor结构api接口部分editor组件script部分怎么去修改富文本的编辑器&#xff1f; 案例内效果&#xff1a; 安装wangEditor npm install wangeditor/…

bash: make: command not found

make之后报错信息如下&#xff1a;cd 对应的文件路径后 make 发现报错&#xff1a;bash: make: command not found 这个原因可能是没有安装make工具,也可能是安装了make之后,没有将make的文件路径添加到系统环境变量中 有没有安装make,可以使用Search Everything搜索是否有make…

24聊城大学823软件工程考研

1.软件发展有几个阶段&#xff1f;各有何特征&#xff1f; ①程序设计阶段 硬件特征&#xff1a;价格贵、存储容量小、运行可靠性差。 软件特征&#xff1a;只有程序、程序设计概念&#xff0c;不重视程序设计方法。 ②程序系统阶段。 硬件特征&#xff1a;速度、容量及工作可…

JS逆向系列之猿人学爬虫第11题 - app抓取 - so文件协议破解

题目地址 http://match.yuanrenxue.com/match/11这是个app题目,先下载下来安装到测试手机上 安装完成后的app界面长这样 打开之后是这样的: 要求已经简单明了了。 二话不说先反编译app 不出意外的是没出意外,源代码里面没啥混淆,所有东西都展示的明明白白的。 "…

Java转换流

文章目录 转换流的理解**InputStreamReader****OutputStreamWriter**练习 引入情况1&#xff1a; 使用FileReader 读取项目中的文本文件。由于IDEA设置中针对项目设置了UTF-8编码&#xff0c;当读取Windows系统中创建的文本文件时&#xff0c;如果Windows系统默认的是GBK编码&a…

每天一个知识点——Normalization

这里结合大模型的学习&#xff0c;主要分析Layer Norm、RMS Norm和Deep Norm的异同&#xff0c;与此同时&#xff0c;究竟是在之前执行Normalization&#xff08;Pre-Norm&#xff09;还是之后执行&#xff08;Post-Norm&#xff09;&#xff0c;也是一个比较喜欢拿来讨论的知识…

LoRaWAN网关与网络服务器(NS)的通信CUPS 协议介绍

LoRa Basics™ Station 定期查询 CUPS 服务器以获取更新。该协议是 HTTP/REST,使用Credentials中描述的客户端/服务器身份验证方法。对于每个查询,工作站都会提供有关其当前状态的信息,并接收包含其 LNS 和 CUPS 凭证更新的二进制 blob,以及具有任意更新的通用数据段。 通…

AIRIOT搭建低成本、更聪明的智能环卫系统,让管理更加高效智能

环卫工程作为城市基础设施保障&#xff0c;是城市建设管理中不可或缺的重要组成部分。随着城市进程的加快及技术的进步&#xff0c;环卫工程管理也在逐渐向精细化、智能化、绿色化等趋势发展。 智能环卫依托物联网、AI、大数据等技术&#xff0c;对环卫管理所涉及到的人、车、物…

ACM算法竞赛中在编辑器中使用输入输出样例-CPH

通用方法 我们可以在编辑器中创建三个文件&#xff0c;一个是main.cpp,一个是test.in,一个是test.out分别用来写代码&#xff0c;输入输入数据&#xff0c;显示输出数据 这种方法的好处是不需要插件&#xff0c;在任何编辑器中都可以实现&#xff0c;例如Devc,sublime,vscode…

【Unity细节】Unity打包后UI面板消失是怎么回事

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 秩沅 原创 收录于专栏&#xff1a;unity细节和bug ⭐关于物体的动画碰到其他碰撞器后停止播放的问题⭐ 文章目录 ⭐关于物体的动画碰…

Camunda 7.x 系列【3】Camunda 简介

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Spring Boot 版本 2.7.9 本系列Camunda 版本 7.19.0 源码地址&#xff1a;https://gitee.com/pearl-organization/camunda-study-demo 文章目录 1. 概述2. 核心组件2.1 流程引擎2.2 模型2.3 Web…

无涯教程-Perl - grep函数

描述 此函数从LIST中提取EXPR为TRUE的所有元素。 语法 以下是此函数的简单语法- grep EXPR, LIST返回值 此函数返回在标量context中表达式返回true的次数以及在列表context中与表达式匹配的元素列表。 例 以下是显示其基本用法的示例代码- #!/usr/bin/perllist (1,&qu…

webpack 热更新的实现原理

webpack 的热更新⼜称热替换&#xff08;Hot Module Replacement&#xff09;&#xff0c;缩写为HMR。这个机制可以做到不⽤刷新浏览器⽽将新变更的模块替换掉旧的模块。 原理&#xff1a; ⾸先要知道 server 端和 client 端都做了处理⼯作&#xff1a; 在 webpack 的 watch…

在Cesium中给管道添加水流效果

添加效果前后对比: 关键代码: /*** 水流粒子,目前支持向上或者向下的效果* @param {Number} x* @param {Number} y* @param {Number} z* @param {Number} options* @example* options = {* color: Cesium.Color.AZURE,* emissionRate: 5, //影响水流速度* direc…

Python编程——谈谈函数的定义、调用与传入参数

作者&#xff1a;Insist-- 个人主页&#xff1a;insist--个人主页 本文专栏&#xff1a;Python专栏 专栏介绍&#xff1a;本专栏为免费专栏&#xff0c;并且会持续更新python基础知识&#xff0c;欢迎各位订阅关注。 目录 一、理解函数 二、函数的定义 1、语法 2、定义一个…

接口测试过程中常见的接口安全性问题,通用测试点整理归纳

我们日常的接口测试工作主要是验证接口的功能性&#xff08;入参、出参、边界值等&#xff09;&#xff0c;在接口测试过程中遇到的一些接口安全性的问题&#xff0c;整理成了通用的测试点&#xff0c;不一定适用于全部的产品&#xff0c;仅做参考。 一、登录接口校验 验证登…

手写SpringCloud系列-负载均衡算法实现

手写SpringCLoud项目地址&#xff0c;求个star github:https://github.com/huangjianguo2000/spring-cloud-lightweight gitee:https://gitee.com/huangjianguo2000/spring-cloud-lightweigh 一&#xff1a;什么是负载均衡 最开始的系统访问量很少&#xff0c;就一个单机就足…

研究生阶段如何进入一个领域——兼李芒老师教育技术导论解读

文章 https://devpress.csdn.net/hpc/64c8bb57bfca273ff3549881.html

svg的图片怎么通过修改源码修改其颜色

这里有一张svg的图片&#xff0c;如下&#xff1a; 原svg的代码(在IDE中打开)如下&#xff1a; svg代码如下&#xff1a; <?xml version"1.0" standalone"no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN""http://www.w…

最好用的六款虚拟机软件

下面&#xff0c;我将介绍目前市面上适合个人用户使用的六款最佳虚拟化软件&#xff0c;让你可以更好的选择。 01 — VMware Workstation Vmware作为全球最知名的虚拟化企业&#xff0c;至今已有超过20年的发展历史。在针对个人用户的产品上&#xff0c;Vmware提供了适用于A…