当前位置: 首页 > news >正文

java动态导入excel按照表头生成数据库表

1、创建接口接收文件


//controller层
@PostMapping("/importExcel1")public void importExcel1(HttpServletRequest request, MultipartFile file) {try {waterMeterService.importExcel1(request,file);} catch (Exception e) {throw new RuntimeException(e);}}//service层
void importExcel1(HttpServletRequest request, MultipartFile file);//实现类层
@Overridepublic void importExcel1(HttpServletRequest request, MultipartFile file) {try {//获取用户信息String fileName = file.getOriginalFilename().substring(0, file.getOriginalFilename().lastIndexOf("."));//文件后缀String fileSuffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));//1.首先获取文件名生成一条记录String directoryName = StringUtils.isEmpty("sheet1") ? fileName : "sheet1";
//            String uuid = createDataSets(directoryName, null, excelReq.getId(), sysUser, excelReq.getDataType(), excelReq.getAddressType());String uuid = UUID.randomUUID().toString();EasyExcel.read(file.getInputStream(), new ConfigFilterListener(waterMeterMapper)).sheet(0).doRead();} catch (IOException e) {throw new RuntimeException(e);}}

2、创建easyexcel导入监听器

package com.wang.test.listener;import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.read.listener.ReadListener;
import com.wang.test.mapper.WaterMeterMapper;
import lombok.SneakyThrows;
import org.springframework.scheduling.annotation.Async;import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;/*** @BelongsPackage: com.wang.test.listener* @Author: wangqian* @CreateTime: 2024-01-24  09:51:59* @Describe:*/
public class ConfigFilterListener implements ReadListener<LinkedHashMap<String, String>> {/*** 每隔5条存储数据库,实际使用中可以100条,然后清理list ,方便内存回收*/private static final int BATCH_COUNT = 1000;private String tableName;//表名private String columnNames;//字段名private List<LinkedHashMap<String, String>> dataSetList = new ArrayList<>();@Resourceprivate WaterMeterMapper waterMeterMapper;//构造函数public ConfigFilterListener(WaterMeterMapper waterMeterMapper) {this.waterMeterMapper = waterMeterMapper;}/*** 这个每一条数据解析都会来调用* 这个接口作用是将excel数据全部添加到dataSetList中,然后达到BATCH_COUNT的时候触发新增数据操作*/@SneakyThrows@Overridepublic void invoke(LinkedHashMap<String, String> linkedHashMap, AnalysisContext analysisContext) {//log.info("解析到一条数据:{}", linkedHashMap);LinkedHashMap<String, String> map = new LinkedHashMap<>();map.put("uuid", UUID.randomUUID().toString());Set set = linkedHashMap.keySet();Iterator iterator = set.iterator();while (iterator.hasNext()) {Object next = iterator.next();map.put(next.toString(), linkedHashMap.get(next));}dataSetList.add(map);//  达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOMif (dataSetList.size() >= BATCH_COUNT) {//创建插入语句StringBuffer sb = new StringBuffer("insert into ");sb.append(this.tableName + " (");sb.append(this.columnNames + " )");// 这里也要保存数据,确保最后遗留的数据也存储到数据库batchInsert(sb.toString(), dataSetList);// 存储完成清理 listdataSetList.clear();}}/*** 所有数据解析完成了 都会来调用*这个方法的作用就是将excel数据插入到生成的表中如果数据大于BATCH_COUNT,则不足与BATCH_COUNT的会做新增操作* @param analysisContext*/
//    @SneakyThrows@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {if (dataSetList.size() > 0) {//创建插入语句StringBuffer sb = new StringBuffer("insert into ");sb.append(this.tableName + " (");//表名称sb.append(this.columnNames + " )");//插入的数据// 这里也要保存数据,确保最后遗留的数据也存储到数据库batchInsert(sb.toString(), dataSetList);dataSetList.clear();}}/**** 读取Excel表格表头* 这个方法的作用就是获取表头,创建数据库表* @param headMap* @param context*/@Overridepublic void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) {try {//每次执行前需求清除上次的结果this.columnNames = null;// 当前sheet的名称 编码获取类似String tableName = context.readSheetHolder().getSheetName();int tableCount = waterMeterMapper.existsTable(tableName);//判断表名是否存在List<String> heads = new ArrayList<>();heads.add("uuid");if (tableCount > 0) {//按照业务需求是创建新表还是提示错误tableName += "_"+System.currentTimeMillis();}StringBuffer createTableStr = new StringBuffer("CREATE TABLE ");createTableStr.append(tableName);createTableStr.append(" (uuid varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,");Collection<ReadCellData<?>> values = headMap.values();//这个是我自己写的,大家按照自己的需求来设置for (int i = 0; i < values.size(); i++) {createTableStr.append("column_"+(i+1) + " varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,");heads.add("column_"+(i+1));}
//这个value.getStringValue()会获取表头的数据,生成的表字段则是按照表头配置的
//            for (ReadCellData<?> value : values) {
//                createTableStr.append(value.getStringValue() + " varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,");
//                heads.add(value.getStringValue());
//            }createTableStr.append("PRIMARY KEY (`uuid`) USING BTREE)");int updateCount = waterMeterMapper.createTable(createTableStr.toString());if (updateCount != 0) {throw new RuntimeException("创建数据库表失败!");}//创建成功后,得插入一条对应记录
//            createDataSets(tableName, tableName, uuid, sysUser, dataType, sort, addressType);this.tableName = tableName;this.columnNames = heads.stream().collect(Collectors.joining(","));} catch (Exception ex) {//waterMeterService.removeById(uuid);//throw new RuntimeException("导入失败!请联系管理员!");}}@Overridepublic boolean hasNext(AnalysisContext context) {return true;}@Asyncpublic void batchInsert(String tableString, List<LinkedHashMap<String, String>> list){try {waterMeterMapper.insertTableData(tableString, list);} catch (Exception e) {throw new RuntimeException(e);}}
}

3、mapper层

 //判断表是否存在int existsTable(@Param("tableName") String tableName);//生成新的表int createTable(@Param("tableString")String tableString);void insertTableData(@Param("tableString") String tableString,@Param("dataSetList") List<LinkedHashMap<String, String>> dataSetList);

4、xml层


<!--    判断表是否存在--><select id="existsTable" resultType="java.lang.Integer">SELECT COUNT(*) FROM information_schema.tables WHERE table_name = #{tableName} AND table_schema = 'test';</select><!--    创建新表--><update id="createTable">${tableString}</update><!--    新增数据--><insert id="insertTableData">insert into ${tableString} values<foreach collection='dataSetList' item='line' index='index'  separator=','><foreach collection='line.values' item='value' open='(' separator=',' close=')'>#{value}</foreach></foreach></insert>

5、里面有些逻辑按照需求来处理,比如表重复,中间出现异常等
后面查询这些数据的时候,可以做配置表(建立一张表),文件名和表名做配置关系,如果要查询这些动态导入数据,则需要知道查哪些表,还有别的需求可以讨论,一起学习

相关文章:

java动态导入excel按照表头生成数据库表

1、创建接口接收文件 //controller层 PostMapping("/importExcel1")public void importExcel1(HttpServletRequest request, MultipartFile file) {try {waterMeterService.importExcel1(request,file);} catch (Exception e) {throw new RuntimeException(e);}}//se…...

Java 集合List相关面试题

&#x1f4d5;作者简介&#xff1a; 过去日记&#xff0c;致力于Java、GoLang,Rust等多种编程语言&#xff0c;热爱技术&#xff0c;喜欢游戏的博主。 &#x1f4d7;本文收录于java面试题系列&#xff0c;大家有兴趣的可以看一看 &#x1f4d8;相关专栏Rust初阶教程、go语言基…...

k8s-基础知识(Pod,Deployment,ReplicaSet)

k8s职责 自动化容器部署和复制随时扩展或收缩容器容器分组group&#xff0c;并且提供容器间的负载均衡实时监控&#xff0c;即时故障发现&#xff0c;自动替换 k8s概念及架构 pod pod是容器的容器&#xff0c;可以包含多个container pod是k8s最小可部署单元&#xff0c;容器…...

matlab查看源代码

matlab函数源代码-查看 CtrlD 最简单方便的一种方法&#xff0c;鼠标划中函数名&#xff0c;按CTRLD即可打开函数的m文件...

【数据库学习】PostgreSQL优化

1&#xff0c;思路 2&#xff0c;执行计划 explain sql语句&#xff1b; #查看执行计划。也可以使用navicat的解释功能查看。结果说明&#xff1a; QUERY PLAN Index Scan using tenk1_unique1 on tenk1 (cost0.00..10.01 rows1 width244) --Index 使用索引 --cost&#x…...

微信小程序分页加载功能,结合后端实现上拉底部加载下一页数据,数据加载中和暂无数据提示

&#x1f935; 作者&#xff1a;coderYYY &#x1f9d1; 个人简介&#xff1a;前端程序媛&#xff0c;目前主攻web前端&#xff0c;后端辅助&#xff0c;其他技术知识也会偶尔分享&#x1f340;欢迎和我一起交流&#xff01;&#x1f680;&#xff08;评论和私信一般会回&#…...

idea 打包跳过测试

IDEA操作 点击蓝色的小球 手动命令 mvn clean package -Dmaven.test.skiptrue...

python sqlite3 线程池封装

1. 封装 sqlite3 1.1. 依赖包引入 # -*- coding: utf-8 -*- #import os import sys import datetime import loggingimport sqlite31.2. 封装类 class SqliteTool(object):#def __init__(self, host, port, user, password, database):def __init__(self, host, database):s…...

亚马逊运营:如何通过自养号测评有效防关联,避免砍单

店铺安全对于跨境电商卖家至关重要&#xff0c;它是我们业务稳定运营的基础。一旦店铺遭到亚马逊的封禁&#xff0c;往往意味着巨大的损失。因此&#xff0c;合规运营已经成为了卖家们的共识。然而&#xff0c;许多卖家可能会因为一些看似微小的失误&#xff0c;导致店铺被关联…...

winfrom图像加速渲染时图像不显示

winform中加入这段代码&#xff0c;即使不调用也会起作用&#xff1b;当图像不显示时&#xff0c;可以注释掉这段代码...

Redash 默认key漏洞(CVE-2021-41192)复现

Redash是以色列Redash公司的一套数据整合分析解决方案。该产品支持数据整合、数据可视化、查询编辑和数据共享等。 Redash 10.0.0及之前版本存在安全漏洞&#xff0c;攻击者可利用该漏洞来使用已知的默认值伪造会话。 1.漏洞级别 中危 2.漏洞搜索 fofa "redash"…...

Git学习笔记:3 git tag命令

文章目录 git tag 基本用法1. 创建标签2. 查看标签3. 删除标签4. 推送标签到远程仓库5. 检出标签 普通提交和标签的区别1. 提交&#xff08;Commit&#xff09;2. 标签&#xff08;Tag&#xff09; git tag 基本用法 git tag 是 Git 中用于管理和操作标签&#xff08;tag&…...

10年软件测试经验,该有什么新的职业规划?

个人觉得&#xff0c;最关键是识别个人的兴趣和长期目标&#xff0c;以及市场需求&#xff0c;制定符合自己职业发展的规划&#xff0c;列了几个常见的方向&#xff1a; 1. 技术深化 专业领域专长&#xff1a;在某一测试领域&#xff08;如自动化测试、性能测试、安全测试等&am…...

重构改善既有代码的设计-学习(四):简化条件逻辑

1、分解条件表达式&#xff08;Decompose Conditional&#xff09; 可以将大块代码分解为多个独立的函数&#xff0c;根据每个小块代码的用途&#xff0c;为分解而得的新函数命名。对于条件逻辑&#xff0c;将每个分支条件分解成新函数还可以带来更多好处&#xff1a;可以突出条…...

【代码---利用一个小程序,读取文件夹中图片,将其合成为一个视频】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言程序详细说明总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 创建一个程序将图像合成为视频通常需要使用图像处理和视频编码库。 …...

MVC 和 MVVM的区别

MVC&#xff1a; M&#xff08;model数据&#xff09;、V&#xff08;view视图&#xff09;&#xff0c;C&#xff08;controlle控制器&#xff09; 缺点是前后端无法独立开发&#xff0c;必须等后端接口做好了才可以往下走&#xff1b; 前端没有自己的数据中心&#xff0c;太…...

redis—Set集合

目录 前言 1.常见命令 2.使用场景 前言 集合类型也是保存多个字符串类型的元素的&#xff0c;但和列表类型不同的是&#xff0c;集合中1)元素之间是无序的2)元素不允许重复&#xff0c;如图2-24所示。一个集合中最多可以存储22 - 1个元素。Redis 除了支持集合内的增删查改操…...

【jetson笔记】vscode远程调试

vscode安装插件 vscode安装远程插件Remote-SSH 安装完毕点击左侧远程资源管理器 打开SSH配置文件 添加如下内容&#xff0c;Hostname为jetson IP&#xff0c;User为登录用户名需替换为自己的 Host aliasHostName 192.168.219.57User jetson配置好点击连接&#xff0c;控制台输…...

大数据处理流程包括哪些环节

大数据处理流程作为当今信息时代的关键技术之一&#xff0c;已经成为各个行业的必备工具。这个流程涵盖了从数据收集、存储、处理、分析到应用的各个环节&#xff0c;确保了数据的有效利用和价值的最大化。 一、数据收集 随着物联网、移动互联网、社交媒体等领域的快速发展&a…...

C++入门篇章1(C++是如何解决C语言不能解决的问题的)

目录 1.C关键字(以C98为例)2.命名空间2.1 命名空间定义2.2命名空间使用 3.C输入&输出4.缺省参数4.1缺省参数概念4.2 缺省参数分类 5. 函数重载5.1函数重载概念5.2 C支持函数重载的原理--名字修饰(name Mangling) 1.C关键字(以C98为例) C总计63个关键字&#xff0c;C语言32…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI

前一阵子在百度 AI 开发者大会上&#xff0c;看到基于小智 AI DIY 玩具的演示&#xff0c;感觉有点意思&#xff0c;想着自己也来试试。 如果只是想烧录现成的固件&#xff0c;乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外&#xff0c;还提供了基于网页版的 ESP LA…...

反射获取方法和属性

Java反射获取方法 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的机制&#xff0c;允许程序在运行时访问和操作类的内部属性和方法。通过反射&#xff0c;可以动态地创建对象、调用方法、改变属性值&#xff0c;这在很多Java框架中如Spring和Hiberna…...

【生成模型】视频生成论文调研

工作清单 上游应用方向&#xff1a;控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

基于Java+MySQL实现(GUI)客户管理系统

客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息&#xff0c;对客户进行统一管理&#xff0c;可以把所有客户信息录入系统&#xff0c;进行维护和统计功能。可通过文件的方式保存相关录入数据&#xff0c;对…...

基于Java+VUE+MariaDB实现(Web)仿小米商城

仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意&#xff1a;运行前…...

c++第七天 继承与派生2

这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分&#xff1a;派生类构造函数与析构函数 当创建一个派生类对象时&#xff0c;基类成员是如何初始化的&#xff1f; 1.当派生类对象创建的时候&#xff0c;基类成员的初始化顺序 …...

毫米波雷达基础理论(3D+4D)

3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文&#xff1a; 一文入门汽车毫米波雷达基本原理 &#xff1a;https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...