通过Easy Excel导入数据

目录

  • 🍑一、背景
  • 🍑二、开发验证
    • 🍊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<>();@Overridepublic 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);}@Overridepublic 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 时,相关数据不会重叠或占用过多的内存。
在这里插入图片描述

@Overridepublic 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.mzph.cn/news/31718.shtml

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

相关文章

字节跳动推出公共DNS服务,将支持 DoH/DoT/DoQ 等协议

近日&#xff0c;字节跳动旗下的火山引擎正式上线 TrafficRoute 解析调度套件&#xff0c;其实质就是一套“公共 DNS”服务&#xff0c;目前仅支持免费版。该 DNS 后续将提供 DoH、DoT 和 DoQ 加密 DNS 查询协议。 火山引擎公共解析&#xff08;PublicDNS&#xff09;产品介绍&…

LeetCode算法递归类—验证二叉搜索树

目录 98. 验证二叉搜索树 题解&#xff1a; 代码&#xff1a; 运行结果&#xff1a;​编辑 给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下&#xff1a; 节点的左子树只包含 小于 当前节点的数。节点的右子树只包含…

Android Animation Made Easy

原文链接 Android Animation Made Easy 动画在任何一个GUI系统中都是一个非常重要的设计元素&#xff0c;它可以让交互变得优雅&#xff0c;让界面变得炫酷&#xff0c;让操作变得更加的舒畅&#xff0c;让状态过渡变得更加的顺滑&#xff0c;对视觉效果有极大的提升&#xff…

Android Retrofit 源码分析

一、retrofit 是什么&#xff1f; Retrofit 是一个 RESTful 的 HTTP 网络请求框架的封装。 网络请求的工作本质上是 OkHttp 完成&#xff0c;而 Retrofit 仅负责 网络请求接口的封装。 1&#xff09;App应用程序通过 Retrofit 请求网络&#xff0c;实际上是使用 Retrofit 接口…

小红书投放流程是什么,达人选择注意事项!

很多人会发现有些笔记的内容并不是很出彩&#xff0c;但是偏偏就火了&#xff0c;自己想去模仿就平平无奇&#xff0c;其中包含了很多因素&#xff0c;有运气、也有选题和博主发文思路在里面&#xff0c;今天&#xff0c;来和大家分享下小红书投放流程是什么&#xff0c;达人选…

K8s环境下监控告警平台搭建及配置

Promethues是可以单机搭建的&#xff0c;参考prometheus入门[1] 本文是就PromethuesGrafana在K8s环境下的搭建及配置 Prometheus度量指标监控平台简介 启动minikube minikube start 安装helm 使用Helm Chart 安装 Prometheus Operator: helm install prometheus-operator stabl…

flask-migrate使用

1.介绍 # 表,字段发生变化&#xff0c;都会有记录&#xff0c;自动同步到数据库中--》django支持这种操作 # 原生的sqlalchemy&#xff0c;不支持修改表的 # flask-migrate可以实现类似于django的 python manage.py makemigrations #记录 python manage.py migrate …

本地跑Mapreduce程序的相关配置

本地跑MapReduce程序需要配置的代码 为了在本地运行MapReduce程序&#xff0c;需要加如下的东西 在项目中创建一个如图所示的包&#xff1a;org.apache.hadoop.io.nativeio&#xff0c;并在该包下面创建一个名为&#xff1a;NativeIO的类&#xff08;注意&#xff1a;名字不能…

黑马程序员Vue全套视频

Vue 2 创建vue实例 示例: <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><script src"https://cdn.jsdelivr.net/npm/vue2.…

液体神经网络:LNN是个啥概念?

一、说明 在在人工智能领域&#xff0c;神经网络已被证明是解决复杂问题的非常强大的工具。多年来&#xff0c;研究人员不断寻求创新方法来提高其性能并扩展其能力。其中一种方法是液体神经网络&#xff08;LNN&#xff09;的概念&#xff0c;这是一个利用动态计算功能的迷人框…

Field Symbol与数据引用的几个应用

这俩货都是指针。在动态编程里用。 但是从好理解的角度来看&#xff0c;都给他们理解成数据对象。 都得指向其他的数据对象。不过field symbol指的是其他的数据对象内存地址的值。而数据引用只是指向内存地址。 1.Field symbol 当Field Symbol指向了其他的数据对象&#xf…

【实操干货】如何开始用Qt Widgets编程?(二)

Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写&#xff0c;所有平台无差别运行&#xff0c;更提供了几乎所有开发过程中需要用到的工具。如今&#xff0c;Qt已被运用于超过70个行业、数千家企业&#xff0c;支持数百万设备及应用。 在本文中&#xff0…

解决: git拉取报错 git 未能顺利结束 (退出码 1)

拉取代码失败信息 解决方法: 执行一下"git push -f origin master"命令即可 步骤: 1.项目文件夹右击选择"Git Bash Here",打开命令窗口 2. 输入"git push -f origin master"后,回画 执行结束 3.再拉取代码,成功

pytest结合 allure 打标记之的详细使用

前言 前面我们提到使用allure 可以生成漂亮的测试报告&#xff0c;下面就Allure 标记我们做详细介绍。 allure 标记 包含&#xff1a;epic&#xff0c;feature, story, title, testcase, issue, description, step, serverity, link, attachment 常用的标记 allure.feature…

20230807通过ffmpeg将DTS编码的AUDIO音频转换为AAC编码

20230807通过ffmpeg将DTS编码的AUDIO音频转换为AAC编码 2023/8/7 20:04 ffmpeg dts 转AAC 缘起&#xff1a;由于网上找的电影没有中文字幕&#xff0c;有内置的英文字幕&#xff0c;但是还是通过剪映/RP2023识别一份英文字幕备用&#xff01; I:\Downloads\2005[红眼航班]Red E…

数据结构 | 利用二叉堆实现优先级队列

目录 一、二叉堆的操作 二、二叉堆的实现 2.1 结构属性 2.2 堆的有序性 2.3 堆操作 队列有一个重要的变体&#xff0c;叫作优先级队列。和队列一样&#xff0c;优先级队列从头部移除元素&#xff0c;不过元素的逻辑顺序是由优先级决定的。优先级最高的元素在最前&#xff…

PHP最简单自定义自己的框架控制器自动加载运行(四)

1、实现效果调用控制中方法 2、创建控制器indexCrl.php <?php class indexCrl{public function index(){echo 当前index控制器index方法;} } 3、KJ.php字段加载控制器文件 public static function run(){//定义常量self::_set_const();//创建模块目录self::_mk_module();…

finfet grid

我正在「拾陆楼」和朋友们讨论有趣的话题&#xff0c;你⼀起来吧&#xff1f; 拾陆楼知识星球入口 90nm 及以下的工艺都要求储存器&#xff0c;IP&#xff0c;IO 的多晶硅方向必须和标准单元的多晶 硅方向保持一致&#xff0c;无法像过去工艺一样随意旋转方向。在 22nm 及以下…

C++初阶语法——类型指示符auto和空指针nullptr

前言&#xff1a;本篇文章的重点 1.C中的类型指示符auto 2.借由auto实现的范围for 3.C为什么要创建nullptr而不是用原本的NULL。 目录 一.auto1.auto的含义及使用2.auto使用注意事项3.范围for&#xff08;重头戏&#xff09;范围for注意事项 二.nullptr 一.auto 1.auto的含义及…

【css】添加待小三角的提示框

如需创建在工具提示的指定侧面显示的箭头&#xff0c;在工具提示后添加“空的”内容&#xff0c;并使用伪元素类 ::after 和 content 属性。箭头本身是使用边框创建的。这会使工具提示看起来像气泡。 代码&#xff1a; <style> .tooltip {position: relative;display: …