C# 使用NPOI操作Excel的工具类

写在前面

NPOI是POI项目的.NET迁移版本。POI是一个开源的Java 读写 Excel、Word 等微软Ole2组件文档的项目;使用NPOI可以在没有安装Office或者相应环境的机器上对Word或Excel文档进行读写操作。

NPOI类库中操作EXCEL有两个模块分别是:

1️.HSSF模块,操作拓展名为.xls的Excel,对应Excel2003及以前的版本。
2️.XSSF模块,操作拓展名为.xlsx的Excel,对应Excel2007及以后的版本,可向下兼容xls,故本例使用XSSF下的XSSFWorkbook来操作。

通过NuGet获取NPOI

需要引用的命名空间如下:

using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System.Collections;
using System.Data;

代码实现

   public class ExcelProcessor{#region 私有变量private int _perSheetCount = 40000;//每个sheet要保存的条数private string _filePath;private IWorkbook _currentWorkbook;private List<string> _sheets;private Dictionary<string, DataTable> _dataDict;#endregion#region 属性public List<string> Sheets{get { return _sheets ?? (_sheets = GetSheets(_filePath)); }}#endregion#region 构造器/// <summary>/// 默认构造器/// </summary>/// <param name="filePath"></param>public ExcelProcessor(string filePath){_filePath = filePath;_dataDict = new Dictionary<string, DataTable>();}/// <summary>/// 加载数据/// </summary>public bool LoadData(){try{using (var fs = new FileStream(_filePath, FileMode.OpenOrCreate, FileAccess.Read)){_currentWorkbook = new XSSFWorkbook(fs);}return true;}catch (Exception ex){return false;}}/// <summary>/// 最大接收5万条每页,大于5万时,使用系统默认的值(4万)/// </summary>/// <param name="perSheetCounts"></param>public ExcelProcessor(int perSheetCounts){if (_perSheetCount <= 50000)_perSheetCount = perSheetCounts;}#endregion#region 公有方法public List<string> GetSheets(string fileName){var sheets = new List<string>();if (_currentWorkbook == null)return sheets;for (int i = 0; i < _currentWorkbook.NumberOfSheets; i++){sheets.Add(_currentWorkbook.GetSheetName(i));}return sheets;}public object GetNumericCellValue(string sheetName, int rowIndex, int colIndex){if (!Sheets.Contains(sheetName))return null;var cell = _currentWorkbook.GetSheet(sheetName).GetRow(rowIndex).GetCell(colIndex - 1);return cell.NumericCellValue;}public object GetStringCellValue(string sheetName, int rowIndex, int colIndex){if (!Sheets.Contains(sheetName))return null;var cell = _currentWorkbook.GetSheet(sheetName).GetRow(rowIndex).GetCell(colIndex - 1);if (cell == null)return null;if (cell.CellType == CellType.Formula){if (cell.CachedFormulaResultType == CellType.String)return cell.StringCellValue;if (cell.CachedFormulaResultType == CellType.Numeric)return cell.NumericCellValue;if (cell.CachedFormulaResultType == CellType.Boolean)return cell.BooleanCellValue;return null;}if (cell.CellType == CellType.Numeric)return cell.NumericCellValue;if (cell.CellType == CellType.Boolean)return cell.NumericCellValue;return cell.StringCellValue;}public object GetDateTimeCellValue(string sheetName, int rowIndex, int colIndex){if (!Sheets.Contains(sheetName))return null;var cell = _currentWorkbook.GetSheet(sheetName).GetRow(rowIndex).GetCell(colIndex - 1);if (cell.CellType == CellType.String)return cell.StringCellValue;return cell.DateCellValue;}public ICell GetCell(string sheetName, int rowIndex, int colIndex){if (!Sheets.Contains(sheetName))return null;var sheet = _currentWorkbook.GetSheet(sheetName);if (sheet == null)return null;var row = sheet.GetRow(rowIndex);if (row == null)return null;var cell = row.GetCell(colIndex - 1);if (cell == null)return null;return cell;}/// <summary>/// 获取单元格里面的值/// </summary>/// <param name="sheetName">表名</param>/// <param name="x">行索引从1开始</param>/// <param name="y">列索引从1开始</param>/// <returns></returns>public object GetCellValue(string sheetName, int rowIndex, int colIndex){if (!Sheets.Contains(sheetName))return null;DataTable dt = null;if (!_dataDict.ContainsKey(sheetName)){dt = Import(sheetName);_dataDict.Add(sheetName, dt);}else{dt = _dataDict[sheetName];}if (dt == null)return null;if (dt.Rows.Count < rowIndex)return null;var rowIdx = rowIndex - 1;var row = dt.Rows[rowIdx];var colIdx = colIndex - 1;return row[colIdx];}public void SetCellValues(ICell cell, string cellType, string cellValue){switch (cellType){case "System.String": //字符串类型double result;if (double.TryParse(cellValue, out result))cell.SetCellValue(result);elsecell.SetCellValue(cellValue);break;case "System.DateTime": //日期类型DateTime dateV;DateTime.TryParse(cellValue, out dateV);cell.SetCellValue(dateV);break;case "System.Boolean": //布尔型bool boolV = false;bool.TryParse(cellValue, out boolV);cell.SetCellValue(boolV);break;case "System.Int16": //整型case "System.Int32":case "System.Int64":case "System.Byte":int intV = 0;int.TryParse(cellValue, out intV);cell.SetCellValue(intV);break;case "System.Decimal": //浮点型case "System.Double":double doubV = 0;double.TryParse(cellValue, out doubV);cell.SetCellValue(doubV);break;case "System.DBNull": //空值处理cell.SetCellValue("");break;default:cell.SetCellValue("");break;}}public DataTable Import(string sheetName){sheetName = string.IsNullOrEmpty(sheetName) ? "Sheet1" : sheetName;ISheet sheet = _currentWorkbook.GetSheet(sheetName);if (sheet == null){sheet = _currentWorkbook.GetSheetAt(0);}IEnumerator ie = sheet.GetRowEnumerator();IRow row = null;var maxCol = 0;while (ie.MoveNext()){row = ie.Current as IRow;//取一行,为了得到column的总数if (row.LastCellNum > maxCol)maxCol = row.LastCellNum;}var dt = new DataTable();for (int i = 0; i < maxCol; i++){dt.Columns.Add(string.Format("Col{0}", i));}ie.Reset();DataRow drow = null;ICell cell = null;var isHeader = true;while (ie.MoveNext()){if (isHeader){isHeader = false;continue;}row = ie.Current as IRow;drow = dt.NewRow();for (int i = 0; i < row.LastCellNum; i++){if (row.GetCell(i) == null){drow[i] = null;continue;}cell = row.GetCell(i) as ICell;switch (cell.CellType){case CellType.Blank:drow[i] = string.Empty;break;case CellType.Boolean:drow[i] = cell.BooleanCellValue;break;case CellType.Error:drow[i] = cell.ErrorCellValue;break;case CellType.Formula:drow[i] = "=" + cell.CellFormula;break;case CellType.Numeric:if (DateUtil.IsCellDateFormatted(cell)){drow[i] = cell.DateCellValue;}else{drow[i] = cell.NumericCellValue;}break;case CellType.String:drow[i] = cell.StringCellValue;break;case CellType.Unknown:break;default:drow[i] = null;break;}}dt.Rows.Add(drow);}return dt;}public string Export(string excelFileName, List<DataTable> dataTables){var workbook = new HSSFWorkbook();ISheet sheet = null;IRow row = null;ICell cell = null;var index = 0;foreach (var dataTable in dataTables){var tableName = dataTable.TableName;if (string.IsNullOrEmpty(tableName))tableName = "Sheet" + (++index);sheet = workbook.CreateSheet(tableName);//填充表头row = sheet.CreateRow(0);for (int i = 0; i < dataTable.Columns.Count; i++){cell = row.CreateCell(i);cell.SetCellValue(dataTable.Columns[i].ColumnName);}//填充内容for (int i = 0; i < dataTable.Rows.Count; i++){row = sheet.CreateRow(i + 1);for (int j = 0; j < dataTable.Columns.Count; j++){cell = row.CreateCell(j);SetCellValues(cell, dataTable.Columns[j].DataType.ToString(), dataTable.Rows[i][j].ToString());}}}if (File.Exists(excelFileName)) File.Delete(excelFileName);using (var fs = new FileStream(excelFileName, FileMode.CreateNew, FileAccess.Write)) workbook.Write(fs);return excelFileName;}public string Export(string excelFileName, DataTable dataTable){HSSFWorkbook workbook = new HSSFWorkbook();ISheet sheet = null;IRow row = null;ICell cell = null;int sheetCount = 1;//当前的sheet数量int currentSheetCount = 0;//循环时当前保存的条数,每页都会清零//表头样式ICellStyle style = workbook.CreateCellStyle();style.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;//内容样式style = workbook.CreateCellStyle();style.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;sheet = workbook.CreateSheet("Sheet" + sheetCount);//填充表头row = sheet.CreateRow(0);for (int i = 0; i < dataTable.Columns.Count; i++){cell = row.CreateCell(i);cell.SetCellValue(dataTable.Columns[i].ColumnName);cell.CellStyle = style;}//填充内容for (int i = 0; i < dataTable.Rows.Count; i++){if (currentSheetCount >= _perSheetCount){sheetCount++;currentSheetCount = 0;sheet = workbook.CreateSheet("Sheet" + sheetCount);}if (sheetCount == 1)//因为第一页有表头,所以从第二页开始写row = sheet.CreateRow(currentSheetCount + 1);else//以后没有表头了,所以从开始写,都是基于0的row = sheet.CreateRow(currentSheetCount);currentSheetCount++;for (int j = 0; j < dataTable.Columns.Count; j++){cell = row.CreateCell(j);cell.CellStyle = style;SetCellValues(cell, dataTable.Columns[j].DataType.ToString(), dataTable.Rows[i][j].ToString());}}FileStream fs = new FileStream(excelFileName, FileMode.CreateNew, FileAccess.Write);workbook.Write(fs);fs.Close();return excelFileName;}#endregion}

总结

本例中主要侧重对目标excel的单元格数据进行访问,对单元格的数据格式进行了比较详细的区分,可自行参考删减。

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

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

相关文章

【UCAS自然语言处理作业二】训练FFN, RNN, Attention机制的语言模型,并计算测试集上的PPL

文章目录 前言前馈神经网络数据组织Dataset网络结构训练超参设置 RNN数据组织&Dataset网络结构训练超参设置 注意力网络数据组织&Dataset网络结构Attention部分完整模型 训练部分超参设置 结果与分析训练集Loss测试集PPL 前言 本次实验主要针对前馈神经网络&#xff0…

#define例题

我们已经学了#define的所有知识&#xff0c;让我们来看这道题&#xff0c;可不要又陷入陷阱 题目要求&#xff1a; #define N 4 #define Y(n) ((N2)*n) int main() {int z 2 * (N Y(5 1));printf("z%d\n", z);return 0; } 求这个z的值是多少&#xff1f; 我们直接…

机器学习算法——主成分分析(PCA)

目录 1. 主体思想2. 算法流程3. 代码实践 1. 主体思想 主成分分析&#xff08;Principal Component Analysis&#xff09;常用于实现数据降维&#xff0c;它通过线性变换将高维数据映射到低维空间&#xff0c;使得映射后的数据具有最大的方差。主成分可以理解成数据集中的特征…

Linux加强篇005-用户身份与文件权限

目录 前言 1. 用户身份与能力 2. 文件权限与归属 3. 文件的特殊权限 4. 文件的隐藏属性 5. 文件访问控制列表 6. su命令与sudo服务 前言 悟已往之不谏&#xff0c;知来者之可追。实迷途其未远&#xff0c;觉今是而昨非。舟遥遥以轻飏&#xff0c;风飘飘而吹衣。问征夫以…

ssm+vue的物资物流系统的设计与实现(有报告)。Javaee项目,ssm vue前后端分离项目。

演示视频&#xff1a; ssmvue的物资物流系统的设计与实现&#xff08;有报告&#xff09;。Javaee项目&#xff0c;ssm vue前后端分离项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体…

JDK源码系列:StringBuffer与StringBuilder对比

一、源码分析StringBuffer与StringBuilder的区别 1、StringBuffer是多线程安全的&#xff0c;StringBuilder是多线程不安全的 多线程安全指的是 多个线程同时对一个对象进行append 等操作&#xff0c;不会出现覆盖、丢失的情况。 看下StringBuffer是如何做到多线程安全的&#…

BART 并行成像压缩感知重建:联合重建

本文使用 variavle-density possion-disc 采样的多通道膝盖数据进行并行重建和压缩感知重建。 0 数据欠采样sampling pattern 1 计算ESPIRiT maps % A visualization of k-space dataknee = readcfl(data/knee); ksp_rss = bart(rss 8, knee);ksp_rss = squeeze(ksp_rss); figu…

基于单片机的肺活量检测系统(论文+源码)

1.系统设计 在基于单片机的肺活量检测系统中&#xff0c;在硬件上整个系统通过利用主控制器STC89C52单片机来实现对整个系统进行控制的功能&#xff0c;通过采用LCD1602实现实时液晶显示数据的功能&#xff0c;通过肺活量传感器XGZP6847ADC0832实现监测肺活量的工作&#xff0…

终端移动性管理

联系前面所学的知识我们知道&#xff0c;移动性管理主要分为两大类&#xff1a;空闲状态下的移动性管理、连接状态下的移动性管理。我们今天来详细了解他们的工作原理~ 目录 移动性管理分类 1、空闲状态下的移动性管理 2、连接状态下的移动性管理 手机选择天线的原则 4G天…

使用Kibana让es集群形象起来

部署Elasticsearch集群详细步骤参考本人&#xff1a; https://blog.csdn.net/m0_59933574/article/details/134605073?spm1001.2014.3001.5502https://blog.csdn.net/m0_59933574/article/details/134605073?spm1001.2014.3001.5502 kibana部署 es集群设备 安装软件主机名…

Kafka系列 - 生产者客户端架构以及3个重要参数

整体架构 整个生产者客户端由两个县城协调运行&#xff0c;这两个线程分别为主线程和Sender线程&#xff08;发送线程&#xff09;。 主线程中由KafkaProducer创建消息&#xff0c;然后通过可能的拦截器&#xff0c;序列化器和分区器之后缓存到消息累加器&#xff08;RecordAc…

nodejs+vue+python+PHP+微信小程序-健身俱乐部在线管理平台的设计与实现-安卓-计算机毕业设计

随着经济的发展、财富的累积&#xff0c;人们生活水平、生活质量大幅度提高&#xff0c;生活环境得到明显改善&#xff0c;但是竞争激烈、人们生活压力大、生活节奏快加上饮食习惯和生活方式不合理导致国内 亚健康人群逐年增多。统计数据表明当前我国亚健康人群比例已经超过了7…

VScode

一、VSCode设置中文 1、首先我们打开vscode&#xff0c;进入编辑页面后点击左边栏的图示图标进入“EXTENSIONS”面板 2、进入后&#xff0c;在上方搜索“Chinese”&#xff0c;搜索到中文&#xff08;简体&#xff09;后&#xff0c;点击“install”按钮。 3、等待自动下载安装…

【一文讲清楚 Anaconda 相关环境配置】

文章目录 0 前言1 Package 与环境1.1 module1.2 package1.3 环境 2 Conda、Miniconda、Anaconda和Pip & PyPI2.1 Conda2. 2 Miniconda2.3 Anaconda2.3.1 Anaconda Navigator2.3.2 Anaconda PowerShell Prompt & Anaconda Prompt2.3.3 Jupyter notebook 2.4 Pip & P…

深度学习第二天:RNN循环神经网络

☁️主页 Nowl &#x1f525;专栏《机器学习实战》 《机器学习》 &#x1f4d1;君子坐而论道&#xff0c;少年起而行之 文章目录 介绍 记忆功能对比展现 任务描述 导入库 处理数据 前馈神经网络 循环神经网络 编译与训练模型 模型预测 可能的问题 梯度消失 梯…

2023/11/24JAVAweb学习

age只会执行成立的,show其实都展示了,通过display不展示 使用Vue,必须引入Vue.js文件 假如运行报错,以管理员身份打开vscode,再运行 ------------------------------------------------------------------- 更改端口号

HarmonyOS简述及开发环境搭建

一、HarmonyOS简介 1、介绍 HarmonyOS是一款面向万物互联时代的、全新的分布式操作系统。有三大系统特性&#xff0c;分别是&#xff1a;硬件互助&#xff0c;资源共享&#xff1b;一次开发&#xff0c;多端部署&#xff1b;统一OS&#xff0c;弹性部署。 HarmonyOS通过硬件互…

微服务实战系列之Nginx(技巧篇)

前言 今天北京早晨竟然飘了一些“雪花”&#xff0c;定睛一看&#xff0c;似雪非雪&#xff0c;像泡沫球一样&#xff0c;原来那叫“霰”。 自然中&#xff0c;雨雪霜露雾&#xff0c;因为出场太频繁&#xff0c;认识门槛较低&#xff0c;自然不费吹灰之力&#xff0c;即可享受…

基于 STM32 的温度测量与控制系统设计

本文介绍了如何基于 STM32 微控制器设计一款温度测量与控制系统。首先&#xff0c;我们将简要介绍 STM32 微控制器的特点和能力。接下来&#xff0c;我们将详细讨论温度传感器的选择与接口。然后&#xff0c;我们将介绍如何使用 STM32 提供的开发工具和相关库来进行温度测量和控…

电脑技巧:电脑常见蓝屏、上不了网等故障及解决办法

目录 一、电脑蓝屏 常见原因1: 病毒木马 常见原因2: 安装了不兼容的软件 二、电脑不能上网 常见原因1: 新装系统无驱动 常见原因2: DNS服务器异常 常见原因3: 硬件问题 三、电脑没声音 常见原因1: 未安装驱动 常见原因2: 硬件故障 四、电脑屏幕不显示 常见原因1: 显…