Java多线程导入Excel示例

在导入Excel的时候,如果文件比较大,行数很多,一行行读往往速度比较慢,为了加快导入速度,我们可以采用多线程的方式
话不多说直接上代码
首先是Controller

import com.sakura.base.service.ExcelService;
import com.sakura.common.api.ApiResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;@RestController
@RequestMapping("/excel")
public class ExcelController {@Autowiredprivate ExcelService excelService;@PostMapping("/import")public ApiResult<Boolean> importExcel(@ModelAttribute MultipartFile file) throws Exception {boolean flag = excelService.importExcel(file);return ApiResult.result(flag);}
}

然后Service

import org.springframework.web.multipart.MultipartFile;public interface ExcelService {boolean importExcel(MultipartFile file) throws Exception;}

ServiceImpl

import com.sakura.base.entity.User;
import com.sakura.base.mapper.UserMapper;
import com.sakura.base.service.ExcelService;
import lombok.extern.java.Log;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;@Service
@Log
public class ExcelServiceImpl implements ExcelService {@Autowiredprivate UserMapper userMapper;@Overridepublic boolean importExcel(MultipartFile file) throws Exception {// 文件为空这些校验大家自己加,这里只是做一个示例// 每次处理的数据量,大家可以自己调整,比如每次处理1000条int batchSize = 5;// 最大线程数,大家可以自己调整,根据自己服务器性能来调整int maxThreads = 3;// 创建一个线程池并设置最大线程数ExecutorService executorService = Executors.newFixedThreadPool(maxThreads);Workbook workbook = null;try {workbook = new XSSFWorkbook(file.getInputStream());// 获取第一页Sheet sheet = workbook.getSheetAt(0);// 获取总行数int rowCount = sheet.getLastRowNum();// 第0行一般为表头,从第一行开始int startRow = 1;// 结束行,Math.min用来比较两个数的大小,取最小值int endRow = Math.min(batchSize, rowCount);while (startRow <= rowCount) {// 提交任务到线程池executorService.execute(new ExcelRowProcessorTask(sheet, startRow, endRow));// 下一批数据的起始行startRow = endRow + 1;// 下一批数据的结束行endRow = Math.min(startRow + batchSize - 1, rowCount);}// 关闭线程池executorService.shutdown();} catch (Exception e) {e.printStackTrace();} finally {// 关闭流if (workbook != null) {try {workbook.close();} catch (IOException e) {e.printStackTrace();}}}return true;}private class ExcelRowProcessorTask implements Runnable {private final Sheet sheet;private final int startRow;private final int endRow;public ExcelRowProcessorTask(Sheet sheet, int startRow, int endRow) {this.sheet = sheet;this.startRow = startRow;this.endRow = endRow;}@Overridepublic void run() {// _________________________________________// 测试用,模拟处理数据的耗时,实际应用删除try {Thread.sleep(2000);} catch (InterruptedException e) {throw new RuntimeException(e);}// _________________________________________for (int i = startRow; i <= endRow; i++) {Row row = sheet.getRow(i);if (row != null) {Cell nameCell = row.getCell(0); // 第一列Cell phoneCell = row.getCell(1); // 第二列nameCell.setCellType(CellType.STRING);String name = nameCell.getStringCellValue();phoneCell.setCellType(CellType.STRING);String phoneNumber = phoneCell.getStringCellValue();User user = new User();user.setName(name);user.setPhoneNumber(phoneNumber);userMapper.insert(user);}}}}
}

实体类User就不贴了没啥好说的

还有就是poi的jar包

		<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.15</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.15</version></dependency>

用postman验证上面的代码

在这里插入图片描述

可以看下数据库的数据,因为我限制了每次处理的数据为5条,同时最多有3个线程,所以可以看到同一时间段导进去的数据为15条

在这里插入图片描述

上面这个还有一个问题就是主线程不会等数据导入完就会返回,如果你需要主线程等待数据导入完可以加上下面这行代码

executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS); // 等待所有任务执行完毕 Long.MAX_VALUE为超时时间,可以自由设置

就放在关闭线程池后面就可以了

在这里插入图片描述

有想看下怎么用多线程导出Excel的移步 Java多线程导出Excel示例

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/720704.shtml

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

相关文章

智慧城市中的数字孪生:数字孪生技术助力智慧城市提高公共服务水平

目录 一、引言 二、数字孪生技术概述 三、数字孪生技术在智慧城市中的应用 1、智慧交通管理 2、智慧能源管理 3、智慧环保管理 4、智慧公共安全 四、数字孪生技术助力智慧城市提高公共服务水平的价值 五、挑战与前景 六、结论 一、引言 随着信息技术的飞速发展&…

【LeetCode】升级打怪之路 Day 13:优先级队列的应用

今日题目&#xff1a; 23. 合并 K 个升序链表 | LeetCode378. 有序矩阵中第 K 小的元素 | LeetCode373. 查找和最小的 K 对数字 | LeetCode703. 数据流中的第 K 大元素 | LeetCode347. 前 K 个高频元素 | LeetCode 目录 Problem 1&#xff1a;合并多个有序链表 【classic】LC 2…

【蓝牙协议栈】【BR/EDR】【AVDTP】音视频分布传输协议

1. AVDTP概念 AVDTP即 AUDIO/VIDEO DISTRIBUTION TRANSPORT PROTOCOL(音视频分配传输协议),主要负责 A/V stream的协商、建立及传输程序,还指定了设备之前传输A/V stream的消息格式. AVDTP的传输机制和消息格式是以 RTP为基础的。RTP由 RTP Data Transfer Protocol (RTP)和…

【国产MCU】-CH32V307-实时时钟(RTC)

实时时钟(RTC) 文章目录 实时时钟(RTC)1、实时时钟(RTC)介绍2、RTC驱动API介绍3、RTC使用实例RTC 实时时钟是一组32 位可编程计数器,时基支持20 位预分频,用于较长时间段的测量。时钟基准来源高速的外部时钟128分频(HSE/128)、外部晶体低频振荡器(LSE)或内部低功耗RC…

【软考高项】【计算专题】- 5 - 进度类 - 横道图/甘特图

一、知识点 1、基本定义 甘特图(Gantt chart )又称为横道图、条状图(Bar chart)&#xff0c;通过条状图来显示项目各活动的进 度情况。以提出者亨利劳伦斯甘特( Henry Laurence Gantt)先生的名字命名。 目前许多文档工具都可以画甘特图。 &#xff08;1&#xff09;我的举例 …

NodeJS 21 的新功能

从使 fetch 和 WebStreams 稳定化到引入实验性的 WebSocket 客户端&#xff0c;Node.js 21 正在为服务器端 JavaScript 执行设定新的标准。 V8 11.8 的更新不仅提升了性能&#xff0c;还添加了开发者一直期待的新语言功能。 让我们来看看所有 Node.js 21 的功能&#xff01; …

07. Nginx进阶-Nginx负载均衡

简介 负载均衡 什么是负载均衡&#xff1f; 负载均衡&#xff0c;英文名称为Load Balance&#xff0c;其含义就是指将负载&#xff08;工作任务&#xff09;进行平衡、分摊到多个操作单元上进行运行。 Nginx负载均衡 什么是Nginx负载均衡&#xff1f; Nginx负载均衡可以大…

【Oracle不停库迁移, 迁移完成无法启动】

MD[Oracle不停库迁移, 迁移完成无法启动] Oracle不停库迁移, 迁移完成无法启动 说明: 1. 在企业上云的大背景下, 自建数据库迁移到云服务器内, 场景较为常见。本文意在解决Oracle迁移到云服务器内&#xff0c;无法启动的问题。 2. 用云厂商的迁移服务(如, 华为云SMS)&#xf…

计算机网络-典型网络组网架构

前面基本网络知识已经能够满足中小企业的需要了&#xff0c;今天来看下一些基本网络组网架构。 首先网络是分层架构&#xff0c;从接入层到汇聚层再到核心层&#xff0c;然后接入运营商出口。内部包括有线网络、无线网络&#xff0c;出口一般可以使用路由器或者防火墙进行安全防…

StarRocks实战——vivo基于 StarRocks 构建实时大数据平台

目录 前言 一、数据挑战 1.1 时效性挑战&#xff0c;业务分析决策需加速 1.2 访问量挑战&#xff0c;性能与稳定性亟待提高&#xff0c;支撑业务稳定运行 1.3 计算场景挑战&#xff0c;难以满足业务复杂查询需求 1.4. 运维挑战&#xff0c;用户查询体验需优化 二、OLA…

WebDAV之π-Disk派盘+人生Life

人生Life是一款日程软件,在这款待办的日程软件当中各种功能极为的完善,完全的足够用户在日常当中的使用,你的待办方面的各种内容都能够在软件上面进行规划和填充,通过待办事项来帮助用户提高在日常当中的效率,对于用户来说这款待办事项的软件是绝佳的选择。 π-Disk派盘 …

java面试(jvm)

JVM内存模型 细分Eden&#xff1a; java类加载过程&#xff1f;双亲委派机制&#xff1f;一个对象从加载到JVM&#xff0c;再到被GC清除过程&#xff1f; JAVA类加载器&#xff1a;AppClassLoader - ExtClassLoader - BootStrapClassLoader。每种类加载器都有他自己的加载目录…

浅谈网络爬虫与Web安全

网络爬虫(Web Crawler)&#xff0c;又称网络蜘蛛(Web Spider)或网络机器人(Web Robot)&#xff0c;是一种按照一定的规则自动抓取万维网资源的程序或者脚本&#xff0c;已被广泛应用于互联网领域。搜索引擎使用网络爬虫抓取Web网页、文档甚至图片、音频、视频等资源&#xff0c…

2024年聚合工艺证模拟考试题库及聚合工艺理论考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年聚合工艺证模拟考试题库及聚合工艺理论考试试题是由安全生产模拟考试一点通提供&#xff0c;聚合工艺证模拟考试题库是根据聚合工艺最新版教材&#xff0c;聚合工艺大纲整理而成&#xff08;含2024年聚合工艺证…

ANSYS穿孔板随机微孔隙构建及力学模拟

多孔结构板在减轻结构重量、满足吸声功能等环境下应用广泛&#xff0c;本案例采用ANSYS Workbench对曲线边界孔洞的随机多孔板进行轴心受拉力学分析。 随机微穿孔板可采用CAD Voronoi插件构建&#xff0c;三维模型构建如下。 CAD Voronoi插件采用参数化建模方式&#xff0c;根…

Mysql去除重复项:力扣182. 查找重复的电子邮箱

题目链接&#xff1a;182. 查找重复的电子邮箱 - 力扣&#xff08;LeetCode&#xff09; 题目描述 sql语句 方法1&#xff1a;使用临时表 select Email from (select Email, count(Email) as numfrom Persongroup by Email ) as statistic where num > 1 ;方法2&#xff…

树状图怎么做?这个方法教你轻松制作

树状图怎么做&#xff1f;在日常生活和工作中&#xff0c;我们经常需要用到树状图来整理和展示信息。树状图不仅能够帮助我们清晰地表达层级关系&#xff0c;还能够让复杂的数据和信息一目了然。那么&#xff0c;如何制作一个既美观又实用的树状图呢&#xff1f;本文将为你详细…

Vue父组件和子组件生命周期的执行顺序

父子组件生命周期概览 在Vue中&#xff0c;组件的生命周期可以分为几个主要阶段&#xff1a;创建&#xff08;creation&#xff09;、挂载&#xff08;mounting&#xff09;、更新&#xff08;updating&#xff09;和销毁&#xff08;destruction&#xff09;。每个阶段都有相…

【回溯算法】【组合问题】Leetcode 77.组合 216. 组合总和 III

【回溯算法】【回溯算法剪枝】 Leetcode 77.组合 216. 组合总和 III 回溯算法可以解决的问题Leetcode 77.组合解法1 回溯法三部曲&#xff0c;函数参数、终止条件和单层搜索逻辑解法一plus 回溯法剪枝 另一道组合回溯问题 216. 组合总和 III解法&#xff1a;回溯解法&#xff1…

ArcGIS学习(十一)公服设施服务区划分与评价

ArcGIS学习(十一)公服设施服务区划分与评价 本任务带来的内容是公服设施服务区划分与公服设施服务区评价。本任务包括两个关卡: 公服设施服务区划分公服设施服务区空间价值评价1.公服设施服务区划分 首先,来看看这个案例的场景和基础数据。我们以上海市图书馆为例进行分析…