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

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

1 -.首先说明下项目目的:

之前我有写过一篇  "NPOI操作EXCEL" 

这篇文章主要介绍了如何安装NPOI,以及NPOI具体如何c#教程使用,并且用具体实例介绍了excel导入到datagridview以及 datagridview如何导出到excel并保存。如果不清楚这块的去我公众号去搜索这篇文章阅读。

  今天这篇文章主要是实现多个excel多张表格的合并,这个是我们数据处理时候经常使用的一个功能,其实最佳的途径是用excel自带的power query(excel2016自带,excel2016以下版本需要安装插件),用这个功能你甚至不需要写一句代码,就可以轻轻松松实现百万计甚至千万级数据操作,当然你也可以用excel里面的vba,这些都可以,但是这不是今天要将的内容,今天的内容就是要用C# 实现数据表格的合并。
  1. 源码:

npoi.cs

using System;
using System.Collections.Generic;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System.Data;
using System.IO;namespace npoi1
{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.52015/12/52015-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 DataTable ExcelToTable(string file ,int nSheet){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 = null;if (nSheet < workbook.NumberOfSheets) //为了不让获取超过表格数量最大索引导致报错sheet = workbook.GetSheetAt(nSheet);else{ return null; }//表头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 , int nSheet){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 = new ISheet[nSheet];for (int k = 0; k < nSheet; k++){if (dt[k] != null){sheet[k] = string.IsNullOrEmpty(dt[k].TableName) ? workbook.CreateSheet("Sheet" + (k + 1).ToString()) : workbook.CreateSheet(dt[k].TableName);//表头IRow row = sheet[k].CreateRow(0);for (int i = 0; i < dt[k].Columns.Count; i++){ICell cell = row.CreateCell(i);cell.SetCellValue(dt[k].Columns[i].ColumnName);}//数据for (int i = 0; i < dt[k].Rows.Count; i++){IRow row1 = sheet[k].CreateRow(i + 1);for (int j = 0; j < dt[k].Columns.Count; j++){ICell cell = row1.CreateCell(j);cell.SetCellValue(dt[k].Rows[i][j].ToString());}}}elsecontinue;}//转为字节数组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;}}}}mainForm.cs
using NPOI.SS.UserModel;
using System;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Windows.Forms;namespace npoi1
{public partial class mainForm : Form{public mainForm(){InitializeComponent();}private void Form1_Load(object sender, EventArgs e){}public static int sheetCount=5;//定义表的最大数量DataTable[] lastTable = new DataTable[sheetCount];private void button1_Click(object sender, EventArgs e){Stopwatch sw = new Stopwatch();sw.Start();//dataGridView1.DataSource = NPOIExcel.ExcelToDataTable("电脑统计表.xlsx", true);//方式1DataTable[] tempTable = new DataTable[sheetCount];DirectoryInfo dir = new DirectoryInfo(@"C:\Users\TPS20\Desktop\excel\");for (int i = 0; i < sheetCount; i++) //遍历一个excel的每个sheet{bool flag = true;foreach (FileInfo dChild in dir.GetFiles("*.xlsx"))//遍历文件夹下的xlsx文件{tempTable[i] =  NPOIExcel.ExcelToTable(dChild.FullName, i);//方式2if (flag && lastTable[i] == null&& tempTable[i] != null) //第一次直接赋值,使得lastTable[i]获取表结构不为null{lastTable[i] = tempTable[i];flag = false;}if (tempTable[i]!=null)GetAllDataTable(tempTable[i] , i);//DataTable合并}             }NPOIExcel.TableToExcel(lastTable, @"C:\Users\TPS20\Desktop\excel\1\111.xlsx", sheetCount);//方式2dataGridView1.DataSource = lastTable[0];//调试时候显示用的,可以去掉dataGridView2.DataSource = lastTable[1];//调试时候显示用的,可以去掉dataGridView3.DataSource = lastTable[2];//调试时候显示用的,可以去掉sw.Stop();label1.Text = sw.ElapsedMilliseconds.ToString("数据导入耗时:" + "0000"+"ms");MessageBox.Show("数据导入完成");}public void GetAllDataTable(DataTable dt,int nSheet){if(lastTable[nSheet]!=null)lastTable[nSheet].Merge(dt, false, MissingSchemaAction.AddWithKey);}private void dataGridView1_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e){for (int i = 0; i < dataGridView1.Rows.Count; i++)this.dataGridView1.Rows[i].HeaderCell.Value = (i + 1).ToString();}private void button2_Click(object sender, EventArgs e){//Stopwatch sw = new Stopwatch();//sw.Start();//DataTable dt = (dataGridView1.DataSource as DataTable);////NPOIExcel.DataTableToExcel(dt, "d:\\111.xlsx");//方式1//NPOIExcel.TableToExcel(dt, "d:\\111.xlsx",0);//方式2//sw.Stop();//label2.Text = sw.ElapsedMilliseconds.ToString("数据导出耗时:" + "0000" + "ms");//MessageBox.Show("数据导出完成");}}}

3. 运行效果

在这里插入图片描述

4.源码百度网盘下载地址:

链接:https://pan.baidu.com/s/1L0rv_CM0N4FTZ-fpwS-YXA

提取码:cjj8


http://chatgpt.dhexx.cn/article/8BmljEu5.shtml

相关文章

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;保证数据能按照指定的方式进…

RabbitMQ 详解

RabbitMQ 详解 MQ 的相关概念RabbitMQ 四大核心概念RabbitMQ 的工作原理RabbitMQ 六大核心部分&#xff08;模式&#xff09;简单模式工作模式工作模式案例消息确认&#xff08;消息应答&#xff09;消息持久化 发布确认模式交换机&#xff08;Exchange&#xff09;Exchange 概…

RabbitMq原理及应用

一、简介 MQ(Message Queue),即消息队列&#xff0c;是一种实现应用级别之间的通信手段。不同应用之间可以通过读写消息&#xff0c;以消息为媒介传递应用数据&#xff0c;不需要应用之间建立强连接。此方式与远程调用&#xff08;RPC&#xff09;是应用通信的常见方式。在这个…

RabbitMQ原理解析

场景模拟 在介绍RabbitMQ之前&#xff0c;我们先来看下面一个电商项目的场景&#xff1a; 商品的原始数据保存在数据库中&#xff0c;增删改查都在数据库中完成。搜索服务数据来源是索引库&#xff08;Elasticsearch&#xff09;&#xff0c;如果数据库商品发生变化&#xff0…

Rabbitmq基本原理和架构

全栈工程师开发手册 &#xff08;作者&#xff1a;栾鹏&#xff09; 架构系列文章 rabbitmq官网:https://www.rabbitmq.com/rabbitmqctl.8.html MQ全称为Message Queue, 是一种分布式应用程序的的通信方法&#xff0c;它是消费-生产者模型的一个典型的代表&#xff0c;produc…

RabbitMQ — RabbitMQ使用以及原理解析

RabbitMQ使用以及原理解析 RabbitMQ是一个由erlang开发的AMQP(Advanved Message Queue)的开源实现;在RabbitMQ官网上主要有这样的模块信息, Work queues消息队列,Publish/Subscribe发布订阅服务,Routing, Topics, RPC等主要应用的模块功能. 几个概念说明: Broker:它提供一种传…