【小白专用】在 vs 中使用 nuget 安装NPOI

C#操作Excel有多种方法,如通过数据库的方式来读写Excel的OleDb方式,但是OleDb方式需要安装微软office,还可以通过COM组件方式操作Excel,也需要安装微软Excel。如果不想安装微软办公套餐可以使用ClosedXML、EPPlus、NPOI。本文主要是介绍NPOI的常用使用方法。
Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。

1. OleDb:

这种方式是把整个Excel文件当做一个数据源来进行数据的读取操作。

优点:实现方式简单,读取速度快;

缺点:读取Excel数据的过程不太灵活,对内存的占用比较高,当数据量变的很大时,容易由于内存空间不足导致内存溢出异常。(不过貌似对于今天电脑的硬件配置来说,内存问题不大)

2. Com组件

这种方式是通过Com组件 Microsoft.Office.Interop.Excel.dll实现Excel文件的操作。

优点:读取Excel数据非常灵活,可以实现Excel具有的各种数据处理功能;

缺点:对数据的访问时基于单元格方式实现的,所以读写数据较慢,特别是当数据量较大时,访问效率问题更为突出。另一点是要求本机安装了Microsoft Office组件。

3. NPOI

这种方式是通过NPOI库实现Excel文件操作,可以在没有安装微软Office的情况下使用。

优点:读取Excel数据速度较快,操作方式灵活;

缺点:试了再说!

NPOI中N指代的是.Net,POI是一个完全开源的Java写成的库,能够在没有安装微软Office或者相应环境的情况下读写Excel、Word等微软OLE2组件文档,几乎支持所有的Office97~Office2007的文件格式。所以NPOI就是POI项目的.Net版本。目前NPOI的最新版本是

NPOI支持的文件格式处理xls、xlsx外,还包括doc、ppt、vsd等,功能强大,人称Excel一哥。本文就准备单独谈一谈NPOI对Excel的基本操作。


 

NuGet安装NPOI

一、环境

工具:VS2022

项目类型:C# Windows 窗体应用(.NET Framework)

框架:.NET Framework 4.8

二、NPOI组件配置

(一)NOPI组件下载:NuGet Gallery | NPOI 2.6.2

将上图中,红色框住的部分复制下来,后面有用。

(二)VS中组件配置

打开VS,点击“工具”——>“NuGet包管理器(N)”——>"程序包管理器控制台(O)",将刚刚复制的内容粘贴到“PM>”后面,点击键盘“Enter”键自动安装

这时候,会发现项目的“引用”这块多了些东西

组件安装成功!

点击【工具】-【NuGet程序包管理器】-【管理解决方案的NuGet程序包(N)...】,搜索NPOI,可以看到安装包,点击下载

一、安装NPOI库

首先,我们需要安装NPOI库。在Visual Studio中,右击项目,选择“管理NuGet程序包”。在搜索栏中输入“NPOI”,选择NPOI并点击“安装”按钮进行安装。

1.新建Windows窗体应用程序员项目,重命名为AliWorkbenchWinForms

2.在Form1界面中控件。添加button1、button2控件用于导入、导出excel,label1、label2用来显示导入、导出所需时间,dataGridView1用来查看Excel文件。

6.右键AliWorkbenchWinForms->添加->类

7.将类命名为NPOIExcel.cs->添加

8.为NPOIExcel.cs添加代码

HSSFWorkbook:是操作Excel2003以前(包括2003)的版本,扩展名是.xls 
XSSFWorkbook:是操作Excel2007的版本,扩展名是.xlsx

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;using System.Data;
using System.IO;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using NPOI.HSSF.UserModel;namespace AliWorkbenchWinForms
{public class NPOIExcel{/// <summary>/// 将excel导入到datatable/// </summary>/// <param name="filePath">excel路径</param>/// <param name="isColumnName">第一行是否是列名</param>/// <returns>返回datatable</returns>public static DataTable ExcelToDataTable(string filePath, bool isColumnName){DataTable dataTable = null;FileStream fs = null;DataColumn column = null;DataRow dataRow = null;IWorkbook workbook = null;ISheet sheet = null;IRow row = null;ICell cell = null;int startRow = 0;try{using (fs = File.OpenRead(filePath)){// 2007版本if (filePath.IndexOf(".xlsx") > 0)workbook = new XSSFWorkbook(fs);// 2003版本else if (filePath.IndexOf(".xls") > 0)workbook = new HSSFWorkbook(fs);if (workbook != null){sheet = workbook.GetSheetAt(0);//读取第一个sheet,当然也可以循环读取每个sheetdataTable = new DataTable();if (sheet != null){int rowCount = sheet.LastRowNum;//总行数if (rowCount > 0){IRow firstRow = sheet.GetRow(0);//第一行int cellCount = firstRow.LastCellNum;//列数//构建datatable的列if (isColumnName){startRow = 1;//如果第一行是列名,则从第二行开始读取for (int i = firstRow.FirstCellNum; i < cellCount; ++i){cell = firstRow.GetCell(i);if (cell != null){if (cell.StringCellValue != null){column = new DataColumn(cell.StringCellValue);dataTable.Columns.Add(column);}}}}else{for (int i = firstRow.FirstCellNum; i < cellCount; ++i){column = new DataColumn("column" + (i + 1));dataTable.Columns.Add(column);}}//填充行for (int i = startRow; i <= rowCount; ++i){row = sheet.GetRow(i);if (row == null) continue;dataRow = dataTable.NewRow();for (int j = row.FirstCellNum; j < cellCount; ++j){cell = row.GetCell(j);if (cell == null){dataRow[j] = "";}else{//CellType(Unknown = -1,Numeric = 0,String = 1,Formula = 2,Blank = 3,Boolean = 4,Error = 5,)switch (cell.CellType){case CellType.Blank:dataRow[j] = "";break;case CellType.Numeric:short format = cell.CellStyle.DataFormat;//对时间格式(2015.12.5、2015/12/5、2015-12-5等)的处理if (format == 14 || format == 31 || format == 57 || format == 58)dataRow[j] = cell.DateCellValue;elsedataRow[j] = cell.NumericCellValue;break;case CellType.String:dataRow[j] = cell.StringCellValue;break;}}}dataTable.Rows.Add(dataRow);}}}}}return dataTable;}catch (Exception){if (fs != null){fs.Close();}return null;}}/// <summary>/// 写入excel/// </summary>/// <param name="dt">datatable</param>/// <param name="strFile">strFile</param>/// <returns></returns>public static bool DataTableToExcel(DataTable dt, string strFile){bool result = false;IWorkbook workbook = null;FileStream fs = null;IRow row = null;ISheet sheet = null;ICell cell = null;try{if (dt != null && dt.Rows.Count > 0){workbook = new XSSFWorkbook();//HSSFWorkbook:是操作Excel2003以前(包括2003)的版本,扩展名是.xls  XSSFWorkbook:是操作Excel2007的版本,扩展名是.xlsxsheet = workbook.CreateSheet("Sheet0");//创建一个名称为Sheet0的表int rowCount = dt.Rows.Count;//行数int columnCount = dt.Columns.Count;//列数//设置列头row = sheet.CreateRow(0);//excel第一行设为列头for (int c = 0; c < columnCount; c++){cell = row.CreateCell(c);cell.SetCellValue(dt.Columns[c].ColumnName);}//设置每行每列的单元格,for (int i = 0; i < rowCount; i++){row = sheet.CreateRow(i + 1);for (int j = 0; j < columnCount; j++){cell = row.CreateCell(j);//excel第二行开始写入数据cell.SetCellValue(dt.Rows[i][j].ToString());}}using (fs = File.OpenWrite(strFile)){workbook.Write(fs);//向打开的这个xls文件中写入数据result = true;}}return result;}catch (Exception ex){if (fs != null){fs.Close();}Console.WriteLine(ex.StackTrace + ex.Message);return false;}}/// <summary>/// Excel导入成Datable/// </summary>/// <param name="file">导入路径(包含文件名与扩展名)</param>/// <returns></returns>public static String EXCEL_XLS = "application/vnd.ms-excel";public static String EXCEL_XLSX = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";public static DataTable ExcelToTable(string file){DataTable dt = new DataTable();IWorkbook workbook;string fileExt = Path.GetExtension(file).ToLower();using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read)){//XSSFWorkbook 适用XLSX格式,HSSFWorkbook 适用XLS格式if (fileExt == ".xlsx") { workbook = new XSSFWorkbook(fs); }else if (fileExt == ".xls"){workbook = new HSSFWorkbook(fs);}else { workbook = null; }if (workbook == null) { return null; }ISheet sheet = workbook.GetSheetAt(0);//表头IRow header = sheet.GetRow(sheet.FirstRowNum);List<int> columns = new List<int>();for (int i = 0; i < header.LastCellNum; i++){object obj = GetValueType(header.GetCell(i));if (obj == null || obj.ToString() == string.Empty){dt.Columns.Add(new DataColumn("Columns" + i.ToString()));}elsedt.Columns.Add(new DataColumn(obj.ToString()));columns.Add(i);}//数据for (int i = sheet.FirstRowNum + 1; i <= sheet.LastRowNum; i++){DataRow dr = dt.NewRow();bool hasValue = false;foreach (int j in columns){dr[j] = GetValueType(sheet.GetRow(i).GetCell(j));if (dr[j] != null && dr[j].ToString() != string.Empty){hasValue = true;}}if (hasValue){dt.Rows.Add(dr);}}}return dt;}/// <summary>/// Datable导出成Excel/// </summary>/// <param name="dt"></param>/// <param name="file">导出路径(包括文件名与扩展名)</param>public static void TableToExcel(DataTable dt, string file){IWorkbook workbook;string fileExt = Path.GetExtension(file).ToLower();if (fileExt == ".xlsx") { workbook = new XSSFWorkbook(); } else if (fileExt == ".xls") { workbook = new HSSFWorkbook(); } else { workbook = null; }if (workbook == null) { return; }ISheet sheet = string.IsNullOrEmpty(dt.TableName) ? workbook.CreateSheet("Sheet1") : workbook.CreateSheet(dt.TableName);//表头IRow row = sheet.CreateRow(0);for (int i = 0; i < dt.Columns.Count; i++){ICell cell = row.CreateCell(i);cell.SetCellValue(dt.Columns[i].ColumnName);}//数据for (int i = 0; i < dt.Rows.Count; i++){IRow row1 = sheet.CreateRow(i + 1);for (int j = 0; j < dt.Columns.Count; j++){ICell cell = row1.CreateCell(j);cell.SetCellValue(dt.Rows[i][j].ToString());}}//转为字节数组MemoryStream stream = new MemoryStream();workbook.Write(stream);var buf = stream.ToArray();//保存为Excel文件using (FileStream fs = new FileStream(file, FileMode.Create, FileAccess.Write)){fs.Write(buf, 0, buf.Length);fs.Flush();}}/// <summary>/// 获取单元格类型/// </summary>/// <param name="cell"></param>/// <returns></returns>private static object GetValueType(ICell cell){if (cell == null)return null;switch (cell.CellType){case CellType.Blank: //BLANK:return null;case CellType.Boolean: //BOOLEAN:return cell.BooleanCellValue;case CellType.Numeric: //NUMERIC:return cell.NumericCellValue;case CellType.String: //STRING:return cell.StringCellValue;case CellType.Error: //ERROR:return cell.ErrorCellValue;case CellType.Formula: //FORMULA:default:return "=" + cell.CellFormula;}}//其他功能函数public void ReadFromExcelFile(string filePath){IWorkbook wk = null;string extension = System.IO.Path.GetExtension(filePath);try{FileStream fs = File.OpenRead(filePath);if (extension.Equals(".xls")){//把xls文件中的数据写入wk中wk = new HSSFWorkbook(fs);}else{//把xlsx文件中的数据写入wk中wk = new XSSFWorkbook(fs);}fs.Close();//读取当前表数据ISheet sheet = wk.GetSheetAt(0);IRow row = sheet.GetRow(0);  //读取当前行数据//LastRowNum 是当前表的总行数-1(注意)int offset = 0;for (int i = 0; i <= sheet.LastRowNum; i++){row = sheet.GetRow(i);  //读取当前行数据if (row != null){//LastCellNum 是当前行的总列数for (int j = 0; j < row.LastCellNum; j++){//读取该行的第j列数据string value = row.GetCell(j).ToString();Console.Write(value.ToString() + " ");}Console.WriteLine("\n");}}}catch (Exception e){//只在Debug模式下才输出Console.WriteLine(e.Message);}}}
}

9.在Form1.cs中分别双击button1、button2控件,为按钮添加按钮点击事件。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;using System.Diagnostics;namespace AliWorkbenchWinForms
{public partial class Form1 : Form{public Form1(){InitializeComponent();}/// <summary>/// 导入/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void button1_Click(object sender, EventArgs e){Stopwatch sw = new Stopwatch();sw.Start();OpenFileDialog openfile = new OpenFileDialog();openfile.Multiselect = false;if (openfile.ShowDialog() == DialogResult.OK){//dataGridView1.DataSource = NPOIExcel.ExcelToDataTable("数据表.xlsx", true);//方式1dataGridView1.DataSource = NPOIExcel.ExcelToTable(openfile.FileName);//方式2sw.Stop();label1.Text = sw.ElapsedMilliseconds.ToString("数据导入耗时:" + "0000" + "ms");MessageBox.Show("数据导入完成");}}/// <summary>/// 导出/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void button2_Click(object sender, EventArgs e){Stopwatch sw = new Stopwatch();sw.Start();DataTable dt = DgvToDt(dataGridView1);SaveFileDialog save = new SaveFileDialog();//设置文件类型save.Filter = "Excel表格(*.xls)|*.xls|Excel表格(*.xlsx)|*.xlsx";//设置默认文件类型显⽰顺序save.FilterIndex = 1;//保存对话框是否记忆上次打开的记录save.RestoreDirectory = true;if (save.ShowDialog() == DialogResult.OK){//string localFilePath = save.FileName.ToString(); //获得⽂件路径//string fileNameExt =localFilePath.Substring(localFilePath.LastIndexOf("\\") + 1); //获取⽂件名,不带路径NPOIExcel.TableToExcel(dt, save.FileName);sw.Stop();label2.Text = sw.ElapsedMilliseconds.ToString("数据导出耗时:" + "0000" + "ms");MessageBox.Show("数据导出完成");}}private DataTable DgvToDt(DataGridView dgv){DataTable dt = new DataTable();//把DataGridView控件数据,转成DataTablefor (int count = 0; count < dgv.Columns.Count; count++){DataColumn dc = new DataColumn(dgv.Columns[count].Name.ToString());dt.Columns.Add(dc);}for (int count = 0; count < dgv.Rows.Count; count++){DataRow dr = dt.NewRow();for (int countsub = 0; countsub < dgv.Columns.Count; countsub++){dr[countsub] = Convert.ToString(dgv.Rows[count].Cells[countsub].Value);}dt.Rows.Add(dr);}return dt;}  }
}

11.点击运行按钮运行项目。可以导入导出Excel文件。

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

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

相关文章

Ubuntu22.04 LTS + CUDA12.3 + CUDNN8.9.7 + PyTorch2.1.1

简介 本文记录Ubuntu22.04长期支持版系统下的CUDA驱动和cuDNN神经网络加速库的安装&#xff0c;并安装PyTorch2.1.1来测试是否安装成功。 安装Ubuntu系统 如果是旧的不支持UEFI启动的主板&#xff0c;请参考本人博客U盘系统盘制作与系统安装&#xff08;详细图解&#xff09…

mac苹果电脑清除数据软件CleanMyMac X4.16

在数字时代&#xff0c;保护个人隐私变得越来越重要。当我们出售个人使用的电脑&#xff0c;亦或者离职后需要上交电脑&#xff0c;都需要对存留在电脑的个人信息做彻底的清除。随着越来越多的人选择使用苹果电脑&#xff0c;很多人想要了解苹果电脑清除数据要怎样做才是最彻底…

深入理解Sentinel系列-1.初识Sentinel

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码、Kafka原理、分布式技术原理&#x1f525;如果感觉博主的文章还不错的话&#xff…

低多边形游戏风格3D模型纹理贴图

在线工具推荐&#xff1a; 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 当谈到游戏角色的3D模型风格时&#xff0c;有几种不同的风格&#xf…

《安富莱嵌入式周报》第328期:自主微型机器人,火星探测器发射前失误故障分析,微软推出12周24期免费AI课程,炫酷3D LED点阵设计,MDK5.39发布

周报汇总地址&#xff1a;嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 更新一期视频教程&#xff1a; 【实战技能】 单步运行源码分析&#xff0c;一期视频整明白FreeRTOS内核源码框架和运行…

模电·放大电路的分析方法——图解法

放大电路的分析方法——图解法 静态工作点的分析电压放大倍数的分析波形非线性失真的分析直流负载线与交流负载线图解法的适用范围 在实际测出放大管的输入特性、输出特性和已知放大电路中其它各元件参数的情况下&#xff0c;利用作图的方法对放大电路进行分析即为图解法。 静…

BUU SQL COURSE 1

四 发现有登录框&#xff0c;爆破半天也爆破不出来&#xff0c;只能从别的地方下手了 F12一下 发现了一个传参 进去发现id可以传参&#xff0c;sql注入一下试试 前三个都有回显&#xff0c;当id4的时候页面没有回显了&#xff0c;正好验证 了页面 有三个新闻 当order by 3的时…

CSPNet: A New Backbone that can Enhance Learning Capability of CNN(2019)

文章目录 -Abstract1 Introduction2 Related workformer work 3 Method3.1 Cross Stage Partial Network3.2 Exact Fusion Model 4 Experiments5 Conclusion 原文链接 源代码 - 梯度信息重用&#xff08;有别于冗余的梯度信息&#xff09;可以减少计算量和内存占用提高效率&am…

内存学习——堆(heap)

目录 一、概念二、自定义malloc函数三、Debug运行四、heap_4简单分析4.1 heap管理链表结构体4.2 堆初始化4.3 malloc使用4.4 free使用 一、概念 内存分为堆和栈两部分&#xff1a; 栈&#xff08;Stack&#xff09;是一种后进先出&#xff08;LIFO&#xff09;的数据结构&…

Flutter自定义下拉选择框dropDownMenu

利用PopupMenuButton和PopupMenuItem写了个下拉选择框&#xff0c;之所以不采用系统的&#xff0c;是因为自定义的更能适配项目需求&#xff0c;话不多说&#xff0c;直接看效果 下面直接贴出代码、代码中注释写的都很清楚&#xff0c;使用起来应该很方便&#xff0c;如果有任何…

Navicat 技术指引 | 适用于 GaussDB 分布式的数据生成功能

Navicat Premium&#xff08;16.3.3 Windows 版或以上&#xff09;正式支持 GaussDB 分布式数据库。GaussDB 分布式模式更适合对系统可用性和数据处理能力要求较高的场景。Navicat 工具不仅提供可视化数据查看和编辑功能&#xff0c;还提供强大的高阶功能&#xff08;如模型、结…

得帆云助力容百科技构建CRM系统,实现LTC全流程管理

宁波容百新能源科技股份有限公司 宁波容百新能源科技股份有限公司&#xff08;以下简称“容百科技”&#xff09;于2014年9月建立&#xff0c;是高科技新能源材料行业的跨国型集团公司。专业从事锂电池正极材料的研发、生产和销售&#xff0c;于2019年登陆上交所科创板&#x…

Docker 部署 2FAuth 服务

拉取最新版本的 2FAuth 镜像&#xff1a; $ sudo docker pull 2fauth/2fauth:latest在本地预先创建好 2fauth 目录, 用于映射 2FAuth 容器内的 /2fauth 目录。 使用以下命令, 在 前台 运行 2FAuth 容器: $ sudo docker run -it --rm --name 2fauth -p 10085:8000/tcp -v /ho…

阻抗控制下机器人接触刚性环境振荡不稳定进行阻抗调节

在阻抗控制下&#xff0c;当机器人接触刚性环境时&#xff0c;可能会出现振荡不稳定的情况。这可以通过调整机器人的阻抗参数来进行调节。 阻抗接触 阻抗参数中的质量、阻尼和刚度都会对机器人控制系统的性能和稳定性产生重要影响。质量主要影响系统的惯性&#xff0c;从而影响…

打破常规思维:Scrapy处理豆瓣视频下载的方式

概述 Scrapy是一个强大的Python爬虫框架&#xff0c;它可以帮助我们快速地开发和部署各种类型的爬虫项目。Scrapy提供了许多方便的功能&#xff0c;例如请求调度、数据提取、数据存储、中间件、管道、信号等&#xff0c;让我们可以专注于业务逻辑&#xff0c;而不用担心底层的…

如何用Qt配置git项目并上传Gitee

1.进入到Qt项目文件夹内&#xff0c;打开 “Git Bash Here” 2.初始化&#xff0c;在“Git Bash Here”中输入 git init 3.加入所有文件&#xff0c;在“Git Bash Here”中输入 git add . (需要注意&#xff0c;git add 后面还有一个点) 4.添加备注&#xff0c;git com…

Hive数据库系列--Hive数据类型/Hive字段类型/Hive类型转换

文章目录 一、Hive数据类型1.1、数值类型1.2、字符类型1.3、日期时间类型1.4、其他类型1.5、集合数据类型1.5.1、Struct举例1.5.2、Array举例1.5.3、Map举例 二、数据类型转换2.1、隐式转换2.2、显示转换 三、字段类型的使用3.1、DECIMAL(precision&#xff0c;scale) 本章主要…

linux驱动开发——内核调试技术

目录 一、前言 二、内核调试方法 2.1 内核调试概述 2.2 学会分析内核源程序 2.3调试方法介绍 三、内核打印函数 3.1内核镜像解压前的串口输出函数 3.2 内核镜像解压后的串口输出函数 3.3 内核打印函数 四、获取内核信息 4.1系统请求键 4.2 通过/proc 接口 4.3 通过…

ES 如何将国际标准时间格式进行格式化与调整时区

需求&#xff0c;日志收集的时候&#xff0c;时间格式是国际标准时间格式。形如yyyy-MM-ddTHH:mm:ss.SSS。 &#xff08;2023-12-05T02:45:50.282Z&#xff09;这个时区也不对&#xff0c;那如何将此类型的时间&#xff0c;进行格式化呢&#xff1f; 本篇文章体统一个案例&…

STM32F103的启动过程及BootLoader作用

1.STM32的启动过程 1.1 复位后的启动模式选择 我们知道的复位方式有三种&#xff1a;上电复位&#xff0c;硬件复位和软件复位。当产生复位&#xff0c;并且离开复位状态后&#xff0c;CM3 内核做的第一件事就是读取下列两个32 位整数的值&#xff1a; &#xff08;1&#xff0…