【SpringBoot】自定义工具类实现Excel数据新建表存入MySQL数据库

《RabbitMQ》《Spring》《SpringMVC》《项目实战》
文章目录
- 前言
- 一、EasyExcel转CSV
- 二、分割建表入库
- 总结
前言
本文主要介绍使用EasyExcel读取Excel内数据并转换为csv格式数据(String字符串),然后实现字符串分割,分割出属性名和属性值建表插入MySQL数据库中。
一、EasyExcel转CSV
使用EasyExcel读取Excel文件,转换为csv数据,也就是转化为一个字符串。
工具类:
/*** @Version: 1.0.0* @Author: Dragon_王* @ClassName: ExcelUtils* @Description: Excel相关工具类* @Date: 2024/3/9 11:24*/import cn.hutool.core.collection.CollUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;/*** Excel 相关工具类*/
@Slf4j
public class ExcelUtils {/*** excel 转 csv** @param multipartFile* @return*/public static String excelToCsv(MultipartFile multipartFile) {// 读取数据List<Map<Integer, String>> list = null;try {list = EasyExcel.read(multipartFile.getInputStream()).excelType(ExcelTypeEnum.XLSX).sheet().headRowNumber(0).doReadSync();} catch (IOException e) {log.error("表格处理错误", e);}if (CollUtil.isEmpty(list)) {return "";}// 转换为 csvStringBuilder stringBuilder = new StringBuilder();// 读取表头LinkedHashMap<Integer, String> headerMap = (LinkedHashMap) list.get(0);List<String> headerList = headerMap.values().stream().filter(ObjectUtils::isNotEmpty).collect(Collectors.toList());stringBuilder.append(StringUtils.join(headerList, ",")).append("\n");// 读取数据for (int i = 1; i < list.size(); i++) {LinkedHashMap<Integer, String> dataMap = (LinkedHashMap) list.get(i);List<String> dataList = dataMap.values().stream().filter(ObjectUtils::isNotEmpty).collect(Collectors.toList());stringBuilder.append(StringUtils.join(dataList, ",")).append("\n");}return stringBuilder.toString();}
}
实际运用中,只需要如下调用:
//传入的是Excel文件,不是路径哦
ExcelUtils.excelToCsv(Excel文件);
Excel文件格式如下:

读取的数据如下格式(这里我用加号拼接更清晰,实际上就是一个包含换行符的字符串,并不包含+号):
"日期,阅读量\n" +"3,253\n" +"4,408\n" +"5,363\n" +"6,955\n" +"7,496\n" +"8,1310\n" +"9,748";
二、分割建表入库
- 将获取的csv数据,其实这里就是一个String字符串,记住现在是字符串不是数组。
- 首先我们分析一下,如何从字符串从分割出属性名(日期、阅读量)以及插入表中的每行属性值(3 253;4 408…):
- 找出第一个换行符(\n)的位置index,然后从第一位切割到index,这时候就得到属性名的字符串。再以英文逗号为分割符进行分割,得到属性名数组。
- 从index切割到字符串最后的位置就是全部属性值,那么如何分割得到每行的属性值呢?同样以换行符为分割符进行分割得到每行属性值的数组。(这里注意一下,数组中的每个元素是一个包含一行值的字符串,如:“3,253”)
- 分割得到的属性值数组内的每个元素再以英文逗号为分割符进行分割得到每行属性值,如"3"和"253"
- 最后根据属性名和属性值动态构建sql语句进行创建表,插入值的操作。
分割csv数据并调用自定义建表和插入函数:
//定义表名String tableName = "test";//获取第一个换行符的索引int index = csvData.indexOf("\n");//分割出属性名字符串,如"日期,阅读量"String colum = csvData.substring(0,index);//得到属性名数组,如{"日期","阅读量"}String[] colums = colum.split(",");//得到全部属性值字符串,如"3,253\n4,408\n5,363\n6,955\n7,496\n8,1310\n9,748"String data = csvData.substring(index).trim();//得到全部属性值数组,如:{"3,253","4,408","5,363""6,955".......}String[] split_data = data.split("\n");//调用建表tableCreationUtils.createTable(tableName,colums);//调用插入tableCreationUtils.Dynamicinsert(tableName,colums,split_data);
动态构造建表sql和插入sql工具类:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;import javax.sql.DataSource;
import java.sql.SQLException;/*** 构建生成表sql** @version 1.0.0* @Author: dragon_王* @Date: 2024/3/11 20:45:16*/
@Component
public class TableCreationUtils {private final JdbcTemplate jdbcTemplate;@Autowiredpublic TableCreationUtils(DataSource dataSource){this.jdbcTemplate = new JdbcTemplate(dataSource);}/*** 动态构建创建表的sql语句并执行** @param tableName 表名字符串* @param columnNames 属性名数组* @return: void* @Date: 2024-03-13 23:23:36*/public void createTable(String tableName, String[] columnNames) {String sql = "CREATE TABLE " + tableName + " (";for (int i = 0; i < columnNames.length; i++) {sql += columnNames[i] + " VARCHAR(255)";if (i < columnNames.length - 1) {sql += ", ";}}sql += ");";jdbcTemplate.execute(sql);}/*** 动态构建插入sql语句并执行** @param tableName 表名字符串* @param columnName 属性名数组,如{"日期","阅读"}* @param rowData 属性值数组,如{"3,253","4,408","5,363""6,955".......}* @return: void* @Date: 2024-03-13 23:24:09*/public void Dynamicinsert(String tableName, String[] columnName,String[] rowData) throws SQLException {//属性值为空就抛出异常if (rowData == null || rowData.length == 0) {throw new IllegalArgumentException("Row data must not be null or empty");}for (int i = 0;i < rowData.length;i++){//传进来的是所有属性值数组,如:{"3,253","4,408","5,363""6,955".......}//所以以将每个元素取出以英文逗号分割,得到插入的每行元素如["3","253"]String[] row = rowData[i].split(",");// 构建占位符StringBuilder columnNames = new StringBuilder();StringBuilder placeholders = new StringBuilder();for (int j = 0; j < row.length; j++) {if (j > 0) {columnNames.append(", ");placeholders.append(", ");}columnNames.append(columnName[j]);placeholders.append("?"); // 使用?作为PreparedStatement的占位符}// 构建完整的SQL语句String sql = "INSERT INTO " + tableName + " (" + columnNames + ") VALUES (" + placeholders + ")";// 使用JdbcTemplate执行插入操作,如第一次循环:insert into tablename (日期,阅读) values (?,?)//row:["3","253"]jdbcTemplate.update(sql,row);}}}
上面代码有以上面EXcel数据为例子的详细讲解,我就不再赘诉,很简单的思路。
总结
以上就是使用EasyExcel读取Excel内数据并转换为csv格式数据(String字符串),然后实现字符串分割,分割出属性名和属性值建表插入MySQL数据库中的详细讲解。
相关文章:
【SpringBoot】自定义工具类实现Excel数据新建表存入MySQL数据库
🏡浩泽学编程:个人主页 🔥 推荐专栏:《深入浅出SpringBoot》《java对AI的调用开发》 《RabbitMQ》《Spring》《SpringMVC》《项目实战》 🛸学无止境,不骄不躁,知行合一 文章目录 …...
Retelling|Facebook1
录音 Facebook 1 Retelling|Facebook1 复述转写 Today Im totally going to talk about Facebook. The aspects of this (its)rising fame and fortune, and the rise (小停顿)in(rising) fame and fortune of s founder Mark Zuckerberg, Mark Zuckerberg created this plat…...
【2024-03-12】设计模式之模板模式的理解
实际应用场景:制作月饼 过程描述: 一开始,由人工制作月饼, 第一个:根据脑子里面月饼的形状,先涅出月饼的形状,然后放入面粉和馅料把开口合并起来。 第二个:根据脑子里面月饼的形状&…...
Transformer模型引领NLP革新之路
在不到4 年的时间里,Transformer 模型以其强大的性能和创新的思想,迅速在NLP 社区崭露头角,打破了过去30 年的记录。BERT、T5 和GPT 等模型现在已成为计算机视觉、语音识别、翻译、蛋白质测序、编码等各个领域中新应用的基础构件。因此&#…...
【Kotlin】运算符函数、解构函数、中缀函数
1 一元运算符 1.1 符号和函数 符号函数aa.unaryPlus()-aa.unaryMinus()!aa.not()aa.dec()a--a.inc() 1.2 案例 fun main() {var stu Student("Tom", 13)println(-stu) // 打印: [moT, 31] }class Student(var name: String, var age: Int) {operator fun unaryM…...
springboot268码头船只货柜管理系统
码头船只出行和货柜管理系统的设计与实现 摘要 针对于码头船只货柜信息管理方面的不规范,容错率低,管理人员处理数据费工费时,采用新开发的码头船只货柜管理系统可以从根源上规范整个数据处理流程。 码头船只货柜管理系统能够实现货柜管理…...
Java面试题11MySQL之执行计划到事务及慢查询
你对MySQL执行计划怎么看 执行计划就是SQL的执行查询的顺序,以及如何使用索引查询,返回的结果集的行数 在MySQL中,我们可以通过explain命令来查看执行计划。其语法如下: EXPLAIN SELECT * FROM table_name WHERE conditions;在…...
算法时空复杂度分析:大O表示法
文章目录 前言大O表示法3个时间复杂度分析原则常见的时间复杂度量级空间复杂度参考资料 前言 算法题写完以后,面试官经常会追问一下你这个算法的时空复杂度是多少?(好像作为一名算法工程师,我日常码代码的过程中,并没…...
threejs简单创建一个几何体(一)
1.下包引入 //下包 npm install three yarn add three//引入 import * as THREE from three2.创建场景,摄像机 // 1.创建场景const scene new THREE.Scene()// 2.创建摄像机//第一个参数是视角,一般在60-90之间,第二个参数是场景的尺寸,一般取显示器的宽高,第三个参数是开始位…...
msfconsole数据库连接不了的问题【已解决】
msfconsole数据库连接 1.msf数据库端口 msf使用的是postgresql,这个数据库默认端口是5432 单个模块的使用可以不需要数据库,但是模块与模块之间需要沟通的时候就会用到数据库。 2.查看msf数据库连接状态 db_status #msf内部查看systemctl status p…...
7. Linux进程环境
进程是操作系统运行程序的一个实例,也是操作系统分配资源的单位。在Linux环境中,每个进程都有独立的进程空间,以便对不同的进程进行隔离,使之不会互相影响。深入理解Linux下的进程环境, 可以帮助我们写出更健壮的代码。 在 Linux 中,进程是程序的一次执行过程,它包含了程…...
[linux] 静态图和动态图
动态图(Dynamic Graphs)和静态图(Static Graphs)通常用来描述深度学习框架中模型的构建方式。 静态图(Static Graphs) 静态图是指模型的计算图在运行前就被定义好并且编译优化的方式。也就是说,…...
1.Spring核心功能梳理
概述 本篇旨在整体的梳理一下Spring的核心功能,让我们对Spring的整体印象更加具体深刻,为接下来的Spring学习打下基础。 本片主体内容如下: Bean的生命周期依赖注入的实现Bean初始化原理推断构造方法原理AOP的实现这里要说明一下,我们这里说到的Spring,一般指的是Spring F…...
活动预告:如何培养高质量应用型医学人才?
在大数据时代与“新医科”建设的背景下,掌握先进的医学数据处理技术成为了医学研究与应用的重要技能。 为了更好地培养社会所需要的高质量应用型医学人才,许多高校已经在广泛地开展面向医学生的医学数据分析教学工作。 在“课-训-赛”育人才系列活动的…...
蓝桥杯算法错题记录-基础篇
文章目录 本文还在跟新,最新跟新时间3/11!!! 格式一定要符合要求,(输入,输出格式)1. nextInt () next() nextLine() 的注意事项2 .数的幂 a^2等3.得到最大长度(最大...&a…...
Java知识点之单例模式
1、单例模式(Binary Search) 单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资…...
Flutter第三弹:常用的Widget
目标: 1)常用的Widget有哪些?有什么特征? 2)开发一个简单的登录页面。 一、Flutter常用Widget 对于Flutter来说,一切皆Widget. 常用的Widget,包括一些基础功能的Widget. 控件名称功能备注…...
Dynamic Wallpaper v17.4 mac版 动态视频壁纸 兼容 M1/M2
Dynamic Wallpaper Engine 是一款适用于 Mac 电脑的视频动态壁纸, 告别单调的静态壁纸,拥抱活泼的动态壁纸。内置在线视频素材库,一键下载应用,也可导入本地视频,同时可以将视频设置为您的电脑屏保。 应用介绍 Dynam…...
Windows / Mac应用程序在Linux系统中的兼容性问题 解决方案
Linux系统可以通过多种方式提高与Windows或Mac应用程序的兼容性。这里有一些解决方案 Windows应用程序兼容性解决方案: Wine Wine是一个允许Linux和Unix系统上运行Windows应用程序的兼容层。 它不是模拟器,而是实现了Windows API的开源实现。 许多W…...
Net Core 使用Mongodb操作文件(上传,下载)
Net Core 使用Mongodb操作文件(上传,下载) 1.Mongodb GridFS 文件操作帮助类。 GridFS 介绍 https://baike.baidu.com/item/GridFS/6342715?fraladdin DLL源码:https://gitee.com/chenjianhua1985/mongodb-client-encapsulati…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...
蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...
智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
