当前位置: 首页 > 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…...

页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…...

视频字幕质量评估的大规模细粒度基准

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用&#xff0c;因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型&#xff08;VLMs&#xff09;在字幕生成方面…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)

本期内容并不是很难&#xff0c;相信大家会学的很愉快&#xff0c;当然对于有后端基础的朋友来说&#xff0c;本期内容更加容易了解&#xff0c;当然没有基础的也别担心&#xff0c;本期内容会详细解释有关内容 本期用到的软件&#xff1a;yakit&#xff08;因为经过之前好多期…...

ip子接口配置及删除

配置永久生效的子接口&#xff0c;2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

用机器学习破解新能源领域的“弃风”难题

音乐发烧友深有体会&#xff0c;玩音乐的本质就是玩电网。火电声音偏暖&#xff0c;水电偏冷&#xff0c;风电偏空旷。至于太阳能发的电&#xff0c;则略显朦胧和单薄。 不知你是否有感觉&#xff0c;近两年家里的音响声音越来越冷&#xff0c;听起来越来越单薄&#xff1f; —…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表

##鸿蒙核心技术##运动开发##Sensor Service Kit&#xff08;传感器服务&#xff09;# 前言 在运动类应用中&#xff0c;运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据&#xff0c;如配速、距离、卡路里消耗等&#xff0c;用户可以更清晰…...

【JVM】Java虚拟机(二)——垃圾回收

目录 一、如何判断对象可以回收 &#xff08;一&#xff09;引用计数法 &#xff08;二&#xff09;可达性分析算法 二、垃圾回收算法 &#xff08;一&#xff09;标记清除 &#xff08;二&#xff09;标记整理 &#xff08;三&#xff09;复制 &#xff08;四&#xff…...

嵌入式常见 CPU 架构

架构类型架构厂商芯片厂商典型芯片特点与应用场景PICRISC (8/16 位)MicrochipMicrochipPIC16F877A、PIC18F4550简化指令集&#xff0c;单周期执行&#xff1b;低功耗、CIP 独立外设&#xff1b;用于家电、小电机控制、安防面板等嵌入式场景8051CISC (8 位)Intel&#xff08;原始…...

Element-Plus:popconfirm与tooltip一起使用不生效?

你们好&#xff0c;我是金金金。 场景 我正在使用Element-plus组件库当中的el-popconfirm和el-tooltip&#xff0c;产品要求是两个需要结合一起使用&#xff0c;也就是鼠标悬浮上去有提示文字&#xff0c;并且点击之后需要出现气泡确认框 代码 <el-popconfirm title"是…...