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

java通过Excel批量上传数据

一、首先在前端写一个上传功能。

<template><!-- 文件上传 --><el-upload class="upload-demo" :on-change="onChange" :auto-upload="false"><el-button type="primary">上传Excel</el-button></el-upload><a target="_blank" type="success" href="/api/upload/write">导出Excle</a></template><script lang="ts" setup>
import { ref } from "vue";
import { uploadApi } from "@/api/index";
import { ElMessage } from "element-plus";
//定义文件上传的函数
const onChange = (file: any, _uploadFiles: any) => {let reader = new FileReader();reader.readAsDataURL(file.raw);reader.onload = (f) => {callUploadApi(file.name, f.target?.result);};
};
//文件上传的函数
const callUploadApi = (name: any, base64: any) => {uploadApi.uploadExcel.call({ name, base64 }).then((res: any) => {ElMessage.success("上传成功");});
};
</script>
请求配置:uploadApi.tsuploadExcel: {name: "上传文件",url: "/api/upload/excel",call: async function name(params: any) {return await http.post(this.url, params);},},

二、后端代码实现

准备工作:1、一个与你上传数据相对于的实体类;

              2、定义一个上传信息对象;

实体类:为了方便演示我就定义两个字段,以供参考:

@Data
public class Person {private Integer id;private String name;private Integer age;
}

上传信息对象:


@Data
public class UploadInfo {private String name;private String base64;
}

Controller层代码:

/** Copyright (c) 2020, 2024,  All rights reserved.**/
package com.by.upload;import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.StopWatch;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.by.dao.PersonMapper;
import com.by.model.FileInfo;
import com.by.model.Upload;
import com.by.service.UploadService;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;@RestController
@RequestMapping("/api/upload")
public class UploadExcel {@Autowiredprivate SqlSessionFactory sqlSessionFactory;@Autowiredprivate PersonMapper personMapper;@Autowiredprivate UploadService uploadService;/*** 导入excle* @param uploadInfo* @return* @throws Exception*/@PostMapping("/excel")public String upload(@RequestBody Upload uploadInfo) throws Exception {String name = uploadInfo.getName();String base64 = uploadInfo.getBase64();String[] strArray = StrUtil.splitToArray(base64, "base64,");byte[] bytes = Base64.decode(strArray[1]);//用于创建一个基于字节数组的输入流。它允许你从一个字节数组中读取数据。ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);// 使用Hutool读取Excel文件ExcelReader reader = ExcelUtil.getReader(byteArrayInputStream);//将读取到的 reader 转化为 List<Man>集合List<Person> persons = reader.readAll(Person.class);//StopWatch类是 Hutool 工具库中的类,用于测量代码执行时间StopWatch stopWatch = new StopWatch();//读取数据的结束时间同时也是写入数据库的开始时间stopWatch.start();//sqlSessionFactory是通过ioc容器注入的  设置其SqlSession的执行器格式ExecutorType.SIMPLE(默认)SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);//循环将List<Man>中的数据插入数据库 方法一//for (Person person : persons) {//    PoItemMapper.xml.insert(person);//}//方法二:mapper.insertBatch(persons);sqlSession.commit();stopWatch.stop();sqlSession.close();System.out.println("插入数据库最终的结果为:" + stopWatch.getTotalTimeSeconds());return "ok";}/*** 导出Excel* @param response* @throws IOException*/@GetMapping("/write")public void exportExcel(HttpServletResponse response) throws IOException {// 创建Excel写入器   参数 true 表示追加数据,即在已有的 Excel 文件上追加新数据。如果设为 false,则会覆盖已有的数据。List<Person> person = personMapper.selectAll();// 创建ExcelWriter对象ExcelWriter writer = ExcelUtil.getWriter(true);int i = 0;while (true) {List<Person> list = person.stream().skip(i * 100000).limit(100000).parallel().collect(Collectors.toList());if (list.isEmpty()) {break;}writer.setSheet("person" + i);// 写入表头writer.addHeaderAlias("id", "Id");writer.addHeaderAlias("name", "姓名");writer.addHeaderAlias("age", "年龄");// 写入当前批次的数据writer.write(list, true);i++;}//response为HttpServletResponse对象   设置响应的内容类型为Excel文件response.setContentType("application/xlsx;charset=utf-8");//test.xls是弹出下载对话框的文件名,不能为中文,中文请自行编码//设置响应头,告诉浏览器以附件形式下载文件,文件名为test.xlsx。这样设置可以让浏览器弹出文件下载对话框。response.setHeader("Content-Disposition", "attachment;filename="+"test.xlsx");//获取响应输出流,它是用于将响应的数据发送给客户端的流。ServletOutputStream out = response.getOutputStream();//将Excel数据写入输出流。第二个参数为true表示追加写入,即将数据追加到已有的Excel文件中。writer.flush(out, true);writer.close();//关闭输出流out.close();}
}

dao层代码:

package com.by.dao;

import com.by.upload.Person;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

public interface PersonMapper {

void insert(Person person);void insertBatch(List<Person> persons);List<Person> selectAll();

}

Mapper.xml:```java
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.by.dao.PersonMapper"><!--新增数据--><insert id="insert">insert into person(name,age)values (#{name},#{age})</insert><!-- 批量新增数据 --><insert id="insertBatch" >insert into person(name,age)values<foreach collection="persons" item="entity" separator=",">(#{entity.name},#{entity.age})</foreach></insert><select id="selectAll" resultType="com.by.upload.Person">select * from person</select>
</mapper>

注意:poi的版本号

org.apache.poi poi-ooxml 5.0.0 三、文件导出。 前端代码: 导出Excle 特别注意:如果你有拦截器和Spring Sercurity,这两个都需要放开请求。

相关文章:

java通过Excel批量上传数据

一、首先在前端写一个上传功能。 <template><!-- 文件上传 --><el-upload class"upload-demo" :on-change"onChange" :auto-upload"false"><el-button type"primary">上传Excel</el-button></el-up…...

VS2022 配置QT5.9.9

QT安装 下载地址&#xff1a;https://download.qt.io/archive/qt/ 下载安装后进行配置 无法运行 rc.exe 下载VS2022 官网下载 配置 1.扩展-管理扩展-下载Qt Visual Studio Tools 安装 2.安装完成后&#xff0c;打开vs2022,点击扩展&#xff0c;会发现多出了QT VS Tools,点…...

接收用户输入的数字,判断是否是质数(素数)以及输出1-100之间的所有质数

问题描述&#xff1a;接收用户输入的数字&#xff0c;判断是否是质数(素数)以及输出1-100之间的所有质数 质数的概念&#xff1a;一个大于1的自然数&#xff0c;除了1和它本身外&#xff0c;不能被其他自然数整除的数叫做质数&#xff0c;也称为素数 规定&#xff1a;1既不是…...

人脸识别AI视觉算法---豌豆云

人脸识别AI算法是一种基于计算机视觉和深度学习技术的系统&#xff0c;用于自动识别和验证人脸。 这些算法在多种领域有着广泛的应用&#xff0c;包括安全认证、身份验证、监控、社交媒体、医疗保健和零售等。 以下是有关人脸识别AI算法的技术背景和应用场景的介绍&#xff1…...

Apache SeaTunnel MongoDB CDC 使用指南

随着数据驱动决策的重要性日益凸显&#xff0c;实时数据处理成为企业竞争力的关键。SeaTunnel MongoDB CDC(Change Data Capture) 源连接器的推出&#xff0c;为开发者提供了一个高效、灵活的工具&#xff0c;以实现对 MongoDB 数据库变更的实时捕获和处理。 本文将深入探讨该连…...

智能合约 之 部署ERC-20

Remix介绍 Remix是一个由以太坊社区开发的在线集成开发环境&#xff08;IDE&#xff09;&#xff0c;旨在帮助开发者编写、测试和部署以太坊智能合约。它提供了一个简单易用的界面&#xff0c;使得开发者可以在浏览器中直接进行智能合约的开发&#xff0c;而无需安装任何额外的…...

【C++】用红黑树模拟实现set、map

目录 前言及准备&#xff1a;一、红黑树接口1.1 begin1.2 end1.3 查找1.4 插入1.5 左单旋和右单旋 二、树形迭代器&#xff08;正向&#xff09;2.1 前置 三、模拟实现set四、模拟实现map 前言及准备&#xff1a; set、map的底层结构是红黑树&#xff0c;它们的函数通过调用红…...

实现:mysql-5.7.42 到 mysql-8.2.0 的升级(二进制方式)

实现&#xff1a;mysql-5.7.42 到 mysql-8.2.0 的升级&#xff08;二进制方式&#xff09; 1、操作环境1、查看当前数据库版本2、操作系统版本3、查看 Linux 系统上的 glibc&#xff08;GNU C 库&#xff09;版本&#xff08;**这里很重要&#xff0c;要下载对应的内核mysql版本…...

深入探讨医保购药APP的技术架构与设计思路

随着移动互联网的发展&#xff0c;医疗保健行业也迎来了数字化转型的浪潮。医保购药APP作为医保体系数字化的一部分&#xff0c;其技术架构和设计思路至关重要。接下来&#xff0c;小编将为您讲解医保购药APP的技术架构与设计思路&#xff0c;为相关从业者提供参考和启发。 一、…...

react中点击按钮不能获取最新的state时候

在这个问题中&#xff0c;用户希望在点击确认按钮时触发handleChange函数&#xff0c;并且能够正确获取到最新的bzText值。最初的代码中&#xff0c;在handleOpen函数中弹出一个确认框&#xff0c;并在确认框的onOk回调函数中调用handleChange函数。然而&#xff0c;由于组件传…...

2、鸿蒙学习-申请调试证书和调试Profile文件

申请发布证书 发布证书由AGC颁发的、为HarmonyOS应用配置签名信息的数字证书&#xff0c;可保障软件代码完整性和发布者身份真实性。证书格式为.cer&#xff0c;包含公钥、证书指纹等信息。 说明 请确保您的开发者帐号已实名认证。每个帐号最多申请1个发布证书。 1、登录AppGa…...

蓝桥杯算法基础(13):十大排序算法(希尔排序) (快速排序)c语言版

希尔排序 优化版的插入排序&#xff0c;优化的地方就是步长&#xff08;增量&#xff09;增大了&#xff0c;原来的插入排序的步长&#xff08;增量&#xff09;是1&#xff0c;而希尔排序的步长&#xff08;增量&#xff09;可以很大&#xff0c;然后逐渐减小直到1形成插入排…...

web学习笔记(三十二)

目录 1.函数的call、apply、bind方法 1.1call、apply、bind的相同点 1.2call、apply、bind的不同点 1.3call、apply、bind的使用场景 2. 对象的深拷贝 2.1对象的浅拷贝 2.1对象的深拷贝 1.函数的call、apply、bind方法 1.1call、apply、bind的相同点 在没有传参数时&…...

Android 地图SDK 绘制点 删除 指定

问题 Android 地图SDK 删除指定绘制点 详细问题 笔者进行Android 项目开发&#xff0c;对于已标记的绘制点&#xff0c;提供撤回按钮&#xff0c;即删除绘制点&#xff0c;如何实现。 解决方案 新增绘制点 private List<Marker> markerList new ArrayList<>…...

Nodejs 第五十八章(大文件上传)

在现代网站中&#xff0c;越来越多的个性化图片&#xff0c;视频&#xff0c;去展示&#xff0c;因此我们的网站一般都会支持文件上传。 文件上传的方案 大文件上传&#xff1a;将大文件切分成较小的片段&#xff08;通常称为分片或块&#xff09;&#xff0c;然后逐个上传这…...

Linux编译器--gcc/g++的使用

1. gcc与g gcc与g分别是c语言与c代码的编译器&#xff0c;但同时g也兼容c语言。 我们知道在Linux中&#xff0c;系统并不以文件后缀来区分文件类别。但对于gcc与g等编译器而言却是需要的。Linux中c代码文件的后缀是.c&#xff0c;c代码文件的后缀是.cpp(.cc)(.cxx)。 在Linu…...

苍穹外卖-day13:vue基础回顾+进阶

vue基础回顾进阶 课程内容 VUE 基础回顾路由 Vue-Router状态管理 vuexTypeScript 1. VUE 基础回顾 1.1 基于脚手架创建前端工程 1.1.1 环境要求 要想基于脚手架创建前端工程&#xff0c;需要具备如下环境要求&#xff1a; ​ node.js 前端项目的运行环境 学习web阶段已安…...

蓝桥杯/慈善晚会/c\c++

问题描述 热心公益的G哥哥又来举办慈善晚会了&#xff0c;这次他邀请到了巴菲特、马云等巨富&#xff0c;还邀请到了大V、小C等算法界泰斗。晚会一共邀请了n位尊贵的客人&#xff0c;每位客人都位于不同的城市&#xff0c;也就是说每座城市都有且仅有一位客人。这些城市的编号为…...

2024.3.19

思维导图...

【Python】新手入门学习:详细介绍单一职责原则(SRP)及其作用、代码示例

【Python】新手入门学习&#xff1a;详细介绍单一职责原则&#xff08;SRP&#xff09;及其作用、代码示例 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyT…...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

Nuxt.js 中的路由配置详解

Nuxt.js 通过其内置的路由系统简化了应用的路由配置&#xff0c;使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

华为OD机试-食堂供餐-二分法

import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

【2025年】解决Burpsuite抓不到https包的问题

环境&#xff1a;windows11 burpsuite:2025.5 在抓取https网站时&#xff0c;burpsuite抓取不到https数据包&#xff0c;只显示&#xff1a; 解决该问题只需如下三个步骤&#xff1a; 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

PAN/FPN

import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...