如何提高读取Excel的效率,NPOI多线程读取详解
如何提高读取Excel的效率
当Excel中的数据量大,达到几十万条,使用Excel文件可能会变得很慢. 以下是一些建议来提高读取Excel的效率:
1. 选择合适的Excel库
在读取Excel文件时, 选择合适的Excel库可以显著提高效率. 一些常用的Excel库包括:
- EPPlus: 用于读写Excel文件的开源库
- NPOI: 用于读写Excel文件的开源库
- Microsoft.Office.Interop.Excel: Microsoft官方提供的Excel库
2. 使用单元格范围
在读取Excel数据时, 不要逐行读取, 而是使用单元格范围. 这种方式可以减少对Excel文件的读取次数, 从而提高读取效率.
以下是一个使用单元格范围的示例:
using (var package = new ExcelPackage(new FileInfo(filePath)))
{ExcelWorksheet worksheet = package.Workbook.Worksheets[worksheetName];var range = worksheet.Cells[2, 1, 50000, 20]; // 选择2-50000行, 1-20列的单元格范围var data = range.Value; // 读取单元格范围中的数据
}
3. 使用多线程
使用多线程可以在读取Excel文件时提高效率. 例如, 可以使用一个线程读取Excel文件, 另一个线程处理数据.
以下是一个使用多线程的示例:
using (var package = new ExcelPackage(new FileInfo(filePath)))
{ExcelWorksheet worksheet = package.Workbook.Worksheets[worksheetName];var range = worksheet.Cells[2, 1, 50000, 20]; // 选择2-50000行, 1-20列的单元格范围// 使用多线程读取单元格范围中的数据var thread = new Thread(() => {var data = range.Value; // 读取单元格范围中的数据// 进行数据处理});thread.Start();
}
4. 关闭Excel应用程序
在读取Excel文件后, 要确保关闭Excel应用程序. 否则, Excel应用程序可能会保留在后台, 导致系统内存占用过高.
以下是一个关闭Excel应用程序的示例:
using (var package = new ExcelPackage(new FileInfo(filePath)))
{ExcelWorksheet worksheet = package.Workbook.Worksheets[worksheetName];var range = worksheet.Cells[2, 1, 50000, 20]; // 选择2-50000行, 1-20列的单元格范围var data = range.Value; // 读取单元格范围中的数据// 关闭Excel应用程序package.Dispose();
}
以上是一些改善读取Excel效率的建议. 根据Excel文件的大小和数据结构, 可以选择不同的方法来提高读取效率.
以下是使用NPOI多线程读取Excel的实例:
using System.Threading.Tasks;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;// ...public void ReadExcelWithMultipleThreads(string filePath, string worksheetName)
{var workbook = new XSSFWorkbook(filePath);var worksheet = workbook.GetSheet(worksheetName);var range = new CellRangeAddress(1, worksheet.LastRowNum, 0, worksheet.GetRow(0).LastCellNum - 1); // 获取单元格范围// 将单元格范围中的数据分块, 每块1000行var chunks = range.Chunks(1000);var tasks = new List<Task>();foreach (var chunk in chunks){var task = Task.Run(() =>{for (var i = chunk.FirstRow; i <= chunk.LastRow; i++){var row = worksheet.GetRow(i);if (row == null) continue;for (var j = chunk.FirstColumn; j <= chunk.LastColumn; j++){var cell = row.GetCell(j);if (cell == null) continue;var cellValue = cell.ToString();// 处理单元格数据}}});tasks.Add(task);}Task.WaitAll(tasks.ToArray());workbook.Close();
}
在此示例中, 使用CellRangeAddress.Chunks()方法将单元格范围分成多个块, 每个块包含1000行. 然后, 使用Task.Run()方法将每个块的读取操作分配给一个线程. 最后, 使用Task.WaitAll()等待所有线程完成后关闭Excel工作簿.
请注意, 在此示例中, 仅使用了一个工作表. 如果要同时读取多个工作表, 则需要根据需要进行修改.
CellRangeAddress.Chunks()方法在NPOI的2.5.x版本及以上版本中可以使用。
CellRangeAddress在NPOI中的命名空间为NPOI.SS.Util。
感谢您的提醒,确实在NPOI的早期版本中没有CellRangeAddress.Chunks()方法。如果您使用的是早期版本,可以考虑手动分块,或者升级NPOI到2.5.x及以上版本。在NPOI 2.5.x及以上版本中,CellRangeAddress.Chunks()方法可以用于将单元格范围分成多个块,以便于在多线程环境下高效读取Excel文件。
另外,CellRangeAddress的命名空间是NPOI.SS.Util。
以下是手动实现分块的代码,达到Chunks()方法的效果:
using System.Collections.Generic;
using NPOI.SS.Util;// ...public void ReadExcelManually(string filePath, string worksheetName)
{var workbook = new XSSFWorkbook(filePath);var worksheet = workbook.GetSheet(worksheetName);var range = new CellRangeAddress(1, worksheet.LastRowNum, 0, worksheet.GetRow(0).LastCellNum - 1); // 获取单元格范围var chunkSize = 1000; // 每个块的大小var chunks = new List<CellRangeAddress>();// 将单元格范围分成多个块, 每个块包含chunkSize行for (var i = range.FirstRow; i <= range.LastRow; i += chunkSize){var firstRow = i;var lastRow = i + chunkSize - 1;if (lastRow > range.LastRow) lastRow = range.LastRow;chunks.Add(new CellRangeAddress(firstRow, lastRow, range.FirstColumn, range.LastColumn));}foreach (var chunk in chunks){for (var i = chunk.FirstRow; i <= chunk.LastRow; i++){var row = worksheet.GetRow(i);if (row == null) continue;for (var j = chunk.FirstColumn; j <= chunk.LastColumn; j++){var cell = row.GetCell(j);if (cell == null) continue;var cellValue = cell.ToString();// 处理单元格数据}}}workbook.Close();
}
在此示例中,我们手动将单元格范围分成多个块,每个块包含1000行,然后使用嵌套循环逐个读取单元格,并在每个单元格上执行必要的操作。需要注意的是,手动分块可能需要更多的代码,但是它可以在NPOI的早期版本中使用。
不过,可能需要根据自己的具体情况进行调整。如果你的数据结构与示例代码不同,你可能需要修改块的大小或循环的索引。
相关文章:
如何提高读取Excel的效率,NPOI多线程读取详解
如何提高读取Excel的效率 当Excel中的数据量大,达到几十万条,使用Excel文件可能会变得很慢. 以下是一些建议来提高读取Excel的效率: 1. 选择合适的Excel库 在读取Excel文件时, 选择合适的Excel库可以显著提高效率. 一些常用的Excel库包括: EPPlus: 用于读写Excel文件的开源…...
【算法】【算法杂谈】从1到n的自然数组中,1出现的次数如何计算?
目录 前言问题介绍解决方案代码编写java语言版本c语言版本c语言版本 思考感悟写在最后 前言 当前所有算法都使用测试用例运行过,但是不保证100%的测试用例,如果存在问题务必联系批评指正~ 在此感谢左大神让我对算法有了新的感悟认识! 问题介…...
日常笔记-Flutter build命令参数
Flutter build命令参数 Flutter build命令参数 Flutter build命令参数 flutter build apk 命令支持以下参数: --debug:构建一个调试版本的 APK。--release:构建一个发布版本的 APK。--target-platform<value>:指定目标平台…...
【利用AI让知识体系化】入门Koa框架
思维导图 文章目录 思维导图一、介绍Koa什么是KoaKoa的历史Koa的特点 二、基本使用安装KoaHello World中间件路由错误处理 三、进阶使用静态资源管理Session管理文件上传表单处理HTTPS支持 四、Koa中间件中间件的概念Koa的洋葱模型常用中间件的介绍自定义中间件的编写 五、异步…...
边缘计算:数据采集、清洗与处理的新时代
近日,又一家边缘计算企业成功获得了融资。这家公司名为DeepWalk,致力于提供边缘计算技术,为企业提供安全、快速的数据采集、清洗和处理解决方案。其融资将用于产品研发和市场推广。 DeepWalk成立于2018年,总部位于美国硅谷&#x…...
分区计量管理项目应用
为充分发挥分区计量管理项目在漏损控制的效用,应构建科学完备的应用体系,如下图 分区计量应用体系 1. 基于水量平衡分析的漏损现状评估方法 分区计量管理项目通过监控分析DMA 分区内流量、压力、水质、大用户用水等情况,结合营业抄收系统的营…...
LayoutInflater中inflate()参数解析
1、关于LayoutInflater,它是如何通过 inflate 方法获取到具体View的? 获得LayoutInflater实例的方式有以下三种: LayoutInflater inflater getLayoutInflater();LayoutInflater inflater LayoutInflater.from(this);LayoutInflater infla…...
星河案例ㅣ中国电信 X 冲量在线:基于智算中心的隐私计算应用实践
▏摘要 中国电信是中国三大运营商之一,为响应国家“东数西算”工程的全新数据中心形态,中国电信引入隐私计算平台,对内实现数据确权跟踪、对外实现数据共享交易,盘活中国电信分布在全国不同区域的数据资源和算力资源,…...
开发笔记之:JAVA读取QT QDataStream输出
1.背景 之前的标题是【JAVA反序列化QT序列化内容】,觉得太大太绕,最后改为现在的标题。 本篇内容是对用JAVA解析QT(用的是QDataSteam)所输出(序列化)的内容的小结。 本文涉及类型包括:QString…...
Docker入门实战---修改Docker镜像源
前言 现在大部分互联网公司在实施项目时几乎都会以微服务架构进行落地,那么微服务一旦多了之后就会面临一个如何友好的治理的问题,本人不会重点介绍治理的问题,而是会简单就治理的其中一个环节服务部署运维的问题进行介绍,服务部…...
Java构建高并发高可用的电商平台(静态架构蓝图之剖析架构)
静态架构蓝图 整个架构是分层的分布式的架构,纵向包括CDN,负载均衡/反向代理,web应用,业务层,基础服务层,数据存储层。水平方向包括对整个平台的配置管理部署和监控。 剖析架构 1. CDN CDN系统能够实时…...
SpringBoot核心运行原理解析之------@Conditional条件注解
在SpringBoot核心运行原理解析之------@EnableAutoConfiguration文档中我们完成了自动配置类的读取和筛选,在这个过程中已经涉及了像@ConditionalOnClass这样的条件注解。打开每个自动配置类,都会看到@Conditional或其衍生的条件注解,本节我们来认识下@Conditional注解。 认…...
systemverilog 001 内建数据类型logic
Verilog 有两种基本数据类型,reg 和wire ,都是4值逻辑 0 1 x z,默认值是x。 reg[7:0] m 为无符号 Integer 为有符号32位 time为64位无符号 real为浮点数 systemverilog新引进了logic,logic既可以作为变量(reg功能),也可以作为线网功能(…...
Flink Kafka-Source
文章目录 Kafka Source1. 使用方法2. Topic / Partition 订阅3. 消息解析4. 起始消费位点5. 有界 / 无界模式6. 其他属性7. 动态分区检查8. 事件时间和水印9. 空闲10. 消费位点提交11. 监控12. 安全 Apache Kafka 连接器 Flink 提供了 Apache Kafka 连接器使用精确一次…...
VoxelNeXt:用于3D检测和跟踪的纯稀疏体素网络
VoxelNeXt:Fully Sparse VoxelNet for 3D Object Detection and Tracking 目前自动驾驶场景的3D检测框架大多依赖于dense head,而3D点云数据本身是稀疏的,这无疑是一种低效和浪费计算量的做法。我们提出了一种纯稀疏的3D 检测框架 VoxelNeXt。该方法可以…...
必须了解的内存屏障
目录 一,内存屏障1,概念2,内存屏障的效果3,cpu中的内存屏障 二,JVM中提供的四类内存屏障指令三,volatile 特性1,保证内存可见性定义2,禁止指令重排序3,不保证原子性 一&a…...
【设计模式】状态模式
文章目录 前言状态模式1、状态模式介绍1.1 存在问题1.2 解决问题1.3 状态模式结构图 2、具体案例说明状态模式2.1 不使用状态模式2.2 使用状态模式 3、状态模式总结 前言 状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示…...
内核驱动支持浮点数运算
最近在调 iio 下的 ICM42686 驱动,因项目求需要在驱动对加速度和陀螺raw数据进行换算,避免不了浮点运算。内核编译时出现了报错,提示如下: drivers/iio/imu/tdk_icm42686/icm42686.o: In function gyro_data2float: /home/share/…...
Flink学习(一)
分布式计算框架 Java可以使用分布式计算来处理大规模的数据和计算任务,提高计算效率和性能。以下是一些Java分布式计算的例子: Apache Hadoop:Hadoop是一个开源的分布式计算框架,可以处理大规模数据集的分布式存储和处理。它使用Java编写,可以在分布式环境中运行MapReduc…...
linux 常用命令awk
AWK 是一种处理文本文件的语言,是一个强大的文本分析工具。之所以叫 AWK 是因为其取了三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的 Family Name 的首字符。 AWK用法 awk 用法:awk pattern {action} files 1.RS, ORS, F…...
docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...
多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...
项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
jmeter聚合报告中参数详解
sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample(样本数) 表示测试中发送的请求数量,即测试执行了多少次请求。 单位,以个或者次数表示。 示例:…...
Ubuntu Cursor升级成v1.0
0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开,快捷键也不好用,当看到 Cursor 升级后,还是蛮高兴的 1. 下载 Cursor 下载地址:https://www.cursor.com/cn/downloads 点击下载 Linux (x64) ,…...
《Docker》架构
文章目录 架构模式单机架构应用数据分离架构应用服务器集群架构读写分离/主从分离架构冷热分离架构垂直分库架构微服务架构容器编排架构什么是容器,docker,镜像,k8s 架构模式 单机架构 单机架构其实就是应用服务器和单机服务器都部署在同一…...
