vb.net读取写入EXCEl的终极方法-NOPI。

article/2025/10/22 1:00:59

据我浅薄的知识,之前只知道两种操作excel的方法:

一。ODBC操作excel

看下图:

在这里插入图片描述
1.ODBC
由于初期连接不同的数据库通过各种不同的API,ODBC就是将各种不同的API封装成统一的接口。当sql语句进入接口时驱动器管理器会判断将他们送入对应的驱动器(driver),由对应的驱动将sql语句送入对应的数据库。
缺点:不同版本的excel,需要添加不同的ODBC数据源。

2.OLEDB与ODBC
OLEDB:一个基于COM(Componet Object Model,DOS可执行命令文件)的数据存储对象,能提供对所有类型的数据的操作。
我们必须知道,ODBC 是为访问关系型数据库而专门开发的,OLE DB 则用于访问关系型和非关系型信息源,例如主机 ISAM/VSAM 和层次数据库,电子邮件和文件系统存储,文本、图形和地理数据以及自定义业务对象。
OLEDB其实和ODBC类似,都是负责数据库连接的低级接口。而OLEDB不仅支持结构化数据库如SQL server,Oracel Access等,而且还支持非结构化数据源的连接如EXCEL等。
OLEDB(对象连接和嵌入数据库),是一组对象的集合,一种读写数据的方法。在使用OLEDB时,使用步骤为:初始化OLE、连接到数据源、发出命令、处理结果、释放数据源对象并停止初始化OLE。他可以通过ODBC连接到数据库,也可以之间连接到数据库。当不通过ODBC时,这时在这其中并不涉及到驱动器的成分,因此,此时的数据库连接速度会更快。同时,我们可以知道,只要支持ODBC的数据源是一定能够支持OLEDB的。但是反过来则不一定。
也就是说OLEDB包含ODBC

3。ADO
是一个用于存取数据源的COM组件。它提供了编程语言和统一数据访问方式OLE DB的一个中间层。允许开发人员编写访问数据的代码而不用关心数据库是如何实现的,而只用关心到数据库的连接。访问数据库的时候,关于SQL的知识不是必要的,但是特定数据库支持的SQL命令仍可以通过ADO中的命令对象来执行。
https://www.cnblogs.com/dachuang/p/8615754.html
https://blog.csdn.net/ithomer/article/details/6624684

二。OLEDB

这种方式的有点速度非常快,但是excel数据量大的时候,会非常占用内存。当内存不够时会抛出内存溢出异常。
缺点是不能设置单元格格式。
1、操作Excel2007以前(不含2007)的连接字符串
string strConn = “Provider=Microsoft.Jet.OleDb.4.0;” + “data source=” + excelFilePath + “;Extended Properties=‘Excel 8.0; HDR=Yes; IMEX=1’”; //此连接只能操作Excel2007之前(.xls)文件
2、操作2007以后的Excel的连接字符串
string strConn = “Provider=Microsoft.Ace.OleDb.12.0;” + “data source=” + excelFilePath + “;Extended Properties=‘Excel 12.0; HDR=Yes; IMEX=1’”; //此连接可以操作.xls与.xlsx文件 (支持Excel2003 和 Excel2007 的连接字符串)

https://blog.csdn.net/qq_33459369/article/details/79308361
https://www.cnblogs.com/qixu/p/6140215.html

三。终极方法NOPI

终于来到重点了。

NOPI 是开源的 用C#编写的读写excel、word等微软的OLE2组件文档的项目。
准备:
NOPI nuget 包:https://www.nuget.org/packages/NPOI

我上传的https://download.csdn.net/download/weixin_43553234/10862591
注意:2.2.1亲测支持 .net 3.5,其余不确定,2.4.0不支持 .net 3.5,其余不确定。
用到再说。

步骤
1。导入NOPI Nuget包,具体见,https://blog.csdn.net/weixin_43553234/article/details/85108137。

2。调用用例,下面是我写的vb.net导出到EXCEL的类。

Imports System.Reflection
Imports NPOI.SS.UserModel
Imports NPOI.XSSF.UserModel
Imports NPOI.HSSF.UserModel
Imports System.IOPublic Class NopiExcelPrivate workbook As IWorkbook   '’工作簿Private sheetList As List(Of ISheet) = New List(Of ISheet)()  '’sheet列表Private Shared suffixName As String = ".xls"Public Sub New(ByVal suffixName As String)If suffixName = ".xlsx" Thenworkbook = New XSSFWorkbook()ElseIf suffixName = ".xls" Thenworkbook = New HSSFWorkbook()End IfsuffixName = suffixNameEnd Sub''' <summary>''' 共享方法,得到此计算机EXCEL表的后缀名''' </summary>''' <returns></returns>''' <remarks></remarks>Public Shared Function getSuffixName()Dim version As Double = checkExcelVer()If version = -1 ThensuffixName = ".xls"ElseIf version >= 12 ThensuffixName = ".xlsx"ElsesuffixName = ".xls"End IfReturn suffixNameEnd Function''' <summary>''' 创建sheet表''' </summary>''' <param name="sheetName">sheet名</param>''' <returns></returns>''' <remarks></remarks>Public Function creatSheet(ByVal sheetName As String) As ISheetIf workbook Is Nothing ThenMsgBox("IWorkbook的实例为nothing", , "错误")Return NothingEnd IfDim sheet As ISheet = workbook.CreateSheet(sheetName)sheetList.Add(sheet)Return sheetEnd Function''' <summary>''' 把dataTable的值写到excel''' </summary>''' <remarks></remarks>Public Sub write(ByVal dataTable As DataTable, ByVal sheet As ISheet)If sheet Is Nothing ThenMsgBox("ISheet的实例为nothing", , "错误")ReturnEnd IfIf dataTable Is Nothing ThenMsgBox("DataTable的实例为nothing", , "错误")ReturnEnd If''表头  Dim row As IRow = sheet.CreateRow(0)For j = 0 To dataTable.Columns.Count - 1Dim cell As ICell = row.CreateCell(j)cell.SetCellValue(dataTable.Columns(j).ColumnName.ToString)NextFor i = 0 To dataTable.Rows.Count - 1row = sheet.CreateRow(i + 1)For j = 0 To dataTable.Columns.Count - 1Dim cell As ICell = row.CreateCell(j)cell.SetCellValue(dataTable.Rows(i).Item(j).ToString)NextNextEnd Sub''' <summary>''' excel 工作簿保存''' </summary>''' <param name="fileAddress">保存路径</param>''' <remarks></remarks>Public Sub save(ByVal fileAddress As String)''转为字节数组  Dim stream As MemoryStream = New MemoryStream()workbook.Write(stream)Dim buf = stream.ToArray()Dim fs As FileStream = New FileStream(fileAddress, FileMode.Create, FileAccess.Write)''保存为Excel文件  Using (fs)fs.Write(buf, 0, buf.Length)fs.Flush()End UsingEnd Sub''' <summary>''' 检测此计算机EXCEL的版本号''' </summary>''' <returns></returns>''' <remarks></remarks>Public Shared Function checkExcelVer() As DoubleDim objExcelType As Type = Type.GetTypeFromProgID("Excel.Application")Dim objApp = Activator.CreateInstance(objExcelType)If objApp Is Nothing ThenReturn 0End IfDim objVer = objApp.GetType().InvokeMember("Version", BindingFlags.GetProperty, Nothing, objApp, Nothing)If objVer Is Nothing ThenReturn -1End IfDim iVer As Double = Convert.ToDouble(objVer)Return iVerEnd Function''' <summary>''' 得到EXCEL版本''' </summary>''' <returns></returns>''' <remarks></remarks>Public Function getExcelVerStr() As StringDim s1 As StringDim excelver As Doubleexcelver = checkExcelVer()s1 = " Office "If excelver = Nothing ThenMessageBox.Show("無法識別Excel的版本", "錯誤", MessageBoxButtons.OK, MessageBoxIcon.Information)s1 = "無法識別 office 版本"ElseIf (excelver >= 14) Thens1 += "2010或以上"ElseIf (excelver >= 12) Thens1 += "2007"ElseIf (excelver >= 11) Thens1 += "2003"ElseIf (excelver >= 10) Thens1 += "XP"ElseIf (excelver >= 9) Thens1 += "2000"ElseIf (excelver >= 8) Thens1 += "97"ElseIf (excelver >= 7) Thens1 += "95"End IfMsgBox(excelver)Return s1End Function''' <summary>''' 合并单元格''' </summary>''' <param name="sheet">sheet名</param>''' <param name="colIndex">要合并的列序号</param>''' <param name="beginRowsIndex">开始的行序号</param>''' <param name="endRowsIndex">结束的行序号</param>''' <returns>开始和结束行序号的-维数组的量表</returns>''' <remarks></remarks>Public Function mergerCell(ByVal sheet As ISheet, ByVal colIndex As Integer, ByVal beginRowsIndex As Integer, ByVal endRowsIndex As Integer) As List(Of Integer())Dim preCellValue As String = sheet.GetRow(beginRowsIndex).Cells(colIndex).ToStringDim beginIndex As Integer = beginRowsIndexDim beginEndArray As Integer(,) = NothingDim beginEndList As List(Of Integer()) = New List(Of Integer())For i = beginRowsIndex To endRowsIndexDim currentCellValue As String = sheet.GetRow(i).Cells(colIndex).ToStringIf Not currentCellValue = preCellValue ThenIf i > beginIndex + 1 Thensheet.AddMergedRegion(New NPOI.SS.Util.CellRangeAddress(beginIndex, i - 1, colIndex, colIndex))''***之前用数组实现的现在用List***'Dim len0 As Integer = 0'If beginEndArray Is Nothing Then'    len0 = 0'Else'    len0 = beginEndArray.GetLength(0)'End If'Dim tempArray As Integer(,) = beginEndArray'ReDim beginEndArray(len0, 1)'If Not tempArray Is Nothing Then'    For index = 0 To tempArray.GetLength(0) - 1'        For j = 0 To tempArray.GetLength(1) - 1'            beginEndArray(index, j) = tempArray(index, j)'        Next'    Next'End If'beginEndArray(len0, 0) = beginIndex'beginEndArray(len0, 1) = i - 1beginEndList.Add({beginIndex, i - 1})End IfbeginIndex = ipreCellValue = currentCellValueEnd If''当遍历到表格最后一行时If i = endRowsIndex And i > beginIndex Thensheet.AddMergedRegion(New NPOI.SS.Util.CellRangeAddress(beginIndex, i, colIndex, colIndex))''***之前用数组实现的现在用List***'Dim len0 As Integer = 0'If beginEndArray Is Nothing Then'    len0 = 0'Else'    len0 = beginEndArray.GetLength(0)'End If'Dim tempArray As Integer(,) = beginEndArray'ReDim beginEndArray(len0, 1)'If Not tempArray Is Nothing Then'    For index = 0 To tempArray.GetLength(0) - 1'        For j = 0 To tempArray.GetLength(1) - 1'            beginEndArray(index, j) = tempArray(index, j)'        Next'    Next'End If'beginEndArray(len0, 0) = beginIndex'beginEndArray(len0, 1) = ibeginEndList.Add({beginIndex, i})End IfNextReturn beginEndListEnd FunctionEnd Class

http://chatgpt.dhexx.cn/article/7wTvU53O.shtml

相关文章

unity NOPI 创建word文档

unity NOPI 创建word文档 导入NOPI 所需要的DLL ICSharpCode.SharpZipLib.dll&#xff0c;NPOI.dll&#xff0c;NPOI.OOXML.dll&#xff0c;NPOI.OpenXml4Net.dll&#xff0c;NPOI.OpenXmlFormats.dll 打包还需导入I18N.CJK.dll,I18N.dll,I18N.West.dll 如果导入Dll出错,设…

pnpm — Monorepo

1、安装 pnpm npm i pnpm -g 2、创建Monorepo管理文件夹&#xff0c;这里命名 Monorepo&#xff0c;并创建packages文件夹 3、创建用于定义工作空间的根目录的yaml文件&#xff1a; pnpm-workspace.yaml&#xff0c;并添加 packages:- packages/ ** 4、 pnpm init 5、pn…

NOPI用法之自定义单元格背景色(3)

NPOI针对office2003使用HSSFWorkbook&#xff0c;对于offce2007及以上使用XSSFWorkbook&#xff1b;今天我以HSSFWorkbook自定义颜色为例说明&#xff0c;Office2007的未研究呢 在NPOI中默认的颜色类是HSSFColor&#xff0c;它内置的颜色有几十种供我们选择&#xff0c;如果不…

c# 使用NOPI 操作Excel

最近项目需要导出Excel,找来找去,微软有自己的Excel组件 using Microsoft.Office.Core;using Microsoft.Office.Interop.Excel;,但是有一个毛病,就是程序所在电脑安装Office,这个问题简直是致命的,因为导出服务我们要做在服务端,程序直接生成Excel,然后客户端路径去下载,…

C# NOPI 项目实战(经典)(可下载项目源码)

1 -.首先说明下项目目的: 之前我有写过一篇 "NPOI操作EXCEL" 这篇文章主要介绍了如何安装NPOI&#xff0c;以及NPOI具体如何c#教程使用&#xff0c;并且用具体实例介绍了excel导入到datagridview以及 datagridview如何导出到excel并保存。如果不清楚这块的去我公众…

NOPI将数据导出至EXCEL表格

文章目录 前言一、NPOI优势二、运行逻辑三、安装NOPI组件四、导出Excel---实现代码五、最终效果六、总结 前言 NPOI,就是POI的.NET版本。POI是一套用Java写成的库&#xff0c;能够帮助开发者在没有安装微软Office的情况下读写Office 97-2003的文件&#xff0c;支持的文件格式包…

RabbitMQ原理、集群、基本操作及常见故障处理

本次学习主要针对运维人员&#xff0c;和对rabbitmq不熟悉的开发人员。通过本次学习你将掌握rabbitmq 的基本原理、集群、基本运维操作、常见故障处理。 1、原理与概念 简介 AMQP&#xff0c;即Advanced Message Queuing Protocol&#xff0c;高级消息队列协议&#xff0c;是…

RabbitMQ简易原理及使用

黑马程序员RabbitMQ全套教程&#xff0c;rabbitmq消息中间件到实战_哔哩哔哩_bilibili 尚硅谷RabbitMQ教程丨快速掌握MQ消息中间件_哔哩哔哩_bilibili 安装&#xff1a;CentOS8安装RabbitMQ 3.8.9_wcybaonier的博客-CSDN博客 // config改为conf&#xff0c;rabbitmq以后缀识别&…

RabbitMQ-详细讲解原理到使用

这里写目录标题 1.初识MQ1.1.同步和异步通讯1.1.1.同步通讯1.1.2.异步通讯1.2.技术对比&#xff1a; 2.快速入门2.1.安装RabbitMQ1.单机部署1.1.下载镜像1.2.安装MQ 2.2.RabbitMQ消息模型2.3.创建一个Demo工程2.4.入门案例2.4.1.publisher实现2.4.2.consumer实现2.5.总结 3.Spr…

rabbitmq基本原理

AMQP(高级消息队列协议) 是一个异步消息传递所使用的应用层协议规范&#xff0c;作为线路层协议&#xff0c;而不是API&#xff08;例如JMS&#xff09;&#xff0c;AMQP 客户端能够无视消息的来源任意发送和接受信息。 AMQP当中有四个概念非常重要 1. virtual host&#xff…

RabbitMQ 内部结构原理介绍

RabbitMQ简介 RabbitMQ是一个用Erlang语言开发的、实现了AMQP协议的消息中间件。 AMQP :&#xff08;Advanced Message Queue&#xff0c;高级消息队列协议&#xff09;它是应用层协议的一个开放标准&#xff0c;为面向消息的中间件设计&#xff0c;基于此协议的客户端与消息中…

Rabbitmq机制

1.发布与订阅 publish and subscribe 短信发送&#xff0c;消息订阅的功能一般会用到这个模式。 这个模式是通过路由器绑定消息队列来实现的&#xff0c;只要有队列绑定到这个路由器&#xff0c;就会接受改路由器的通知。 2.routing模式 路由模式 在发布订阅模式的基础增加了…

RabbitMQ 架构原理

1.RabbitMQ 架构原理 由于 RabbitMQ 实现了 AMQP 协议&#xff0c;所以 RabbitMQ 的工作模型也是基于 AMQP 的。理解这张图片至关重要。 1.1 Broker 中介 我们要使用 RabbitMQ 来收发消息&#xff0c;必须要安装一个 RabbitMQ 的服务&#xff0c;可以安 装在 Windows 上面也可以…

RabbitMq底层原理分析

RabbitMq消息中间件介绍&为什么要使用消息中间件&什么时候使用消息中间件 我们用java来举例子&#xff0c; 打个比方 我们客户端发送一个下单请求给订单系统&#xff08;order&#xff09;订单系统发送了 一个请求给我们的库存系统告诉他需要更改库存了&#xff0c; 我…

RabbitMQ集群原理介绍

文章目录 一、RabbitMQ默认集群原理1. RabbitMQ集群元数据的同步2. 为何RabbitMQ集群仅采用元数据同步的方式3. RabbitMQ集群发送/订阅消息的基本原理4. 客户端直接连接队列所在节点5. 客户端连接的是非队列数据所在节点7. 集群节点类型磁盘节点内存节点 8. 总结 二、RabbitMQ镜…

RabbitMQ的基本架构与实现原理

目录 1.RabbitMQ Exchange类型 2.RabbitMQ的数据存储 RabbitMQ整体逻辑架构 1.RabbitMQ Exchange类型 常用的交换器类型分为&#xff1a;Direct、Topic、 Fanout、Header 四种。 Fanout fanout类型的交换器会把所有发送到该交换器的消息路由到所有与该交换器绑定的队列中&…

Rabbit Mq 底层原理

为什么要用MQ&#xff1f;MQ有什么好处&#xff1f; 1、异步通信&#xff1a;通过异步通信&#xff0c;可以减少客户端等待时间&#xff0c;实现接口快速响应 2、系统解耦&#xff1a;对于复杂的系统&#xff0c;减小系统与系统之间的依赖 3、流量削峰&#xff1a;对于瞬时访问…

RabbitMQ工作原理以及常见面试题【2022版】

RabbitMQ工作原理图&#xff1a; Broker&#xff1a;接收和分发消息的应用&#xff0c;RabbitMQ Server 就是 Message Broker Virtual host&#xff1a;出于多租户和安全因素设计的&#xff0c;把 AMQP 的基本组件划分到一个虚拟的分组中&#xff0c;类似 于网络中的 namespac…

RabbitMQ原理简单介绍

其实这篇博客&#xff0c;也算不上是什么原理&#xff0c;只是将我知道的一些RabbitMQ的知识简单罗列下&#xff0c;自从我来公司到现在&#xff0c;虽然一直都在用RabbitMQ&#xff0c;也一直想着把这块总结下&#xff0c;却一直在给自己找借口&#xff0c;最近一段时间&#…

MQ - RabbitMQ - 架构及工作原理

参考网址&#xff1a; RabbitMQ的应用场景以及基本原理介绍 RabbitMQ使用详解 RabbitMQ的Java应用(1) -- Rabbit Java Client使用 1. 系统架构 几个概念说明: Broker:它提供一种传输服务,它的角色就是维护一条从生产者到消费者的路线&#xff0c;保证数据能按照指定的方式进…