NPOI 是开源的 POI 项目的.NET版,可以用来读写Excel,Word,PPT文件。

仅需处理 XLS/XLSX 格式的文本和数字读写,最少需要加载 2 个核心 DLL

  1. NPOI.dll
    包含所有格式的通用接口(IWorkbookISheetIRowICell 等),是 NPOI 的基础核心库。

  2. 对应格式的专用 DLL

    • 处理 XLS(97-2003):需 NPOI.HSSF.dll
    • 处理 XLSX(2007+):需 NPOI.XSSF.dll

如果同时需要支持两种格式,则需要加载 3 个 DLLNPOI.dll + NPOI.HSSF.dll + NPOI.XSSF.dll。说明:

  • 不需要额外引用 NPOI.HPSF.dll(处理 OLE2 文档属性,基础读写用不到)。
  • 不需要 NPOI.DDF.dllNPOI.POIFS.dll 等(这些用于复杂功能如图片、公式、加密等)。
  • 若使用 NuGet 安装 NPOI 包,会自动包含所有依赖,但实际运行时仅上述核心 DLL 是必须的。

对于简单的文本和数字读写,这几个 DLL 足以满足需求。

在处理Excel文件上,NPOI 可以同时兼容 xls 和 xlsx。

官网提供了一份 Examples,     给出了很多应用场景的例子,打包好的二进制文件类库,也仅有几MB,使用非常方便。     读Excel

{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);}
}
在这里插入代码片

Excel中的单元格是有不同数据格式的,例如数字,日期,字符串等,在读取的时候可以根据格式的不同设置对象的不同类型,方便后期的数据处理。

//获取cell的数据,并设置为对应的数据类型
public object GetCellValue(ICell cell)
{object value = null;try{if (cell.CellType != CellType.Blank){switch (cell.CellType){case CellType.Numeric:// Date comes hereif (DateUtil.IsCellDateFormatted(cell)){value = cell.DateCellValue;}else{// Numeric typevalue = cell.NumericCellValue;}break;case CellType.Boolean:// Boolean typevalue = cell.BooleanCellValue;break;case CellType.Formula:value = cell.CellFormula;break;default:// String typevalue = cell.StringCellValue;break;}}}catch (Exception){value = "";}return value;
}

AI写代码csharp运行

特别注意的是CellType中没有Date,而日期类型的数据类型是Numeric,其实日期的数据在Excel中也是以数字的形式存储。可以使用DateUtil.IsCellDateFormatted方法来判断是否是日期类型。

有了GetCellValue方法,写数据到Excel中的时候就要有SetCellValue方法,缺的类型可以自己补。

//根据数据类型设置不同类型的cell
public static void SetCellValue(ICell cell, object obj)
{if (obj.GetType() == typeof(int)){cell.SetCellValue((int)obj);}else if (obj.GetType() == typeof(double)){cell.SetCellValue((double)obj);}else if (obj.GetType() == typeof(IRichTextString)){cell.SetCellValue((IRichTextString)obj);}else if (obj.GetType() == typeof(string)){cell.SetCellValue(obj.ToString());}else if (obj.GetType() == typeof(DateTime)){cell.SetCellValue((DateTime)obj);}else if (obj.GetType() == typeof(bool)){cell.SetCellValue((bool)obj);}else{cell.SetCellValue(obj.ToString());}
}

cell.SetCellValue()方法只有四种重载方法,参数分别是string, bool, DateTime, double, IRichTextString
设置公式使用cell.SetCellFormula(string formula)写Excel

以下是简单的例子,更多信息可以参见官网提供的Examples。

public void WriteToExcel(string filePath)
{
//创建工作薄
IWorkbook wb;
string extension = System.IO.Path.GetExtension(filePath);
//根据指定的文件格式创建对应的类
if (extension.Equals(".xls"))
{
wb = new HSSFWorkbook();
}
else
{
wb = new XSSFWorkbook();
}
ICellStyle style1 = wb.CreateCellStyle();//样式
style1.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Left;//文字水平对齐方式
style1.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center;//文字垂直对齐方式
//设置边框
style1.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
style1.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
style1.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
style1.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
style1.WrapText = true;//自动换行ICellStyle style2 = wb.CreateCellStyle();//样式
IFont font1 = wb.CreateFont();//字体
font1.FontName = "楷体";
font1.Color = HSSFColor.Red.Index;//字体颜色
font1.Boldweight = (short)FontBoldWeight.Normal;//字体加粗样式
style2.SetFont(font1);//样式里的字体设置具体的字体样式//设置背景色
style2.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Yellow.Index;
style2.FillPattern = FillPattern.SolidForeground;
style2.FillBackgroundColor = NPOI.HSSF.Util.HSSFColor.Yellow.Index;
style2.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Left;//文字水平对齐方式
style2.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center;//文字垂直对齐方式ICellStyle dateStyle = wb.CreateCellStyle();//样式
dateStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Left;//文字水平对齐方式
dateStyle.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center;//文字垂直对齐方式
//设置数据显示格式
IDataFormat dataFormatCustom = wb.CreateDataFormat();
dateStyle.DataFormat = dataFormatCustom.GetFormat("yyyy-MM-dd HH:mm:ss");//创建一个表单
ISheet sheet = wb.CreateSheet("Sheet0");
//设置列宽
int[] columnWidth = { 10, 10, 20, 10 };
for (int i = 0; i < columnWidth.Length; i++)
{//设置列宽度,256*字符数,因为单位是1/256个字符sheet.SetColumnWidth(i, 256 * columnWidth[i]);
}//测试数据
int rowCount = 3, columnCount = 4;
object[,] data = {{"列0", "列1", "列2", "列3"},{"", 400, 5.2, 6.01},{"", true, "2014-07-02", DateTime.Now}//日期可以直接传字符串,NPOI会自动识别//如果是DateTime类型,则要设置CellStyle.DataFormat,否则会显示为数字
};IRow row;
ICell cell;for (int i = 0; i < rowCount; i++)
{row = sheet.CreateRow(i);//创建第i行for (int j = 0; j < columnCount; j++){cell = row.CreateCell(j);//创建第j列cell.CellStyle = j % 2 == 0 ? style1 : style2;//根据数据类型设置不同类型的cellobject obj = data[i, j];SetCellValue(cell, data[i, j]);//如果是日期,则设置日期显示的格式if (obj.GetType() == typeof(DateTime)){cell.CellStyle = dateStyle;}//如果要根据内容自动调整列宽,需要先setCellValue再调用//sheet.AutoSizeColumn(j);}
}//合并单元格,如果要合并的单元格中都有数据,只会保留左上角的//CellRangeAddress(0, 2, 0, 0),合并0-2行,0-0列的单元格
CellRangeAddress region = new CellRangeAddress(0, 2, 0, 0);
sheet.AddMergedRegion(region);try
{FileStream fs = File.OpenWrite(filePath);wb.Write(fs);//向打开的这个Excel文件中写入表单并保存。  fs.Close();
}
catch (Exception e)
{Debug.WriteLine(e.Message);
}

如果想要设置单元格为只读或可写,可以参考,方法如下:

ICellStyle unlocked = wb.CreateCellStyle();
unlocked.IsLocked = false;//设置该单元格为非锁定
cell.SetCellValue("未被锁定");
cell.CellStyle = unlocked;
...
//保护表单,password为解锁密码//cell.CellStyle.IsLocked = true;的单元格将为只读
sheet.ProtectSheet("password");

cell.CellStyle.IsLocked 默认就是true,

因此sheet.ProtectSheet(“password”)一定要执行,

才能实现锁定单元格,对于不想锁定的单元格,

就一定要设置cell的CellStyle中的IsLocked = false

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

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

相关文章

Perforce P4 Git 连接器

Perforce P4 Git连接器将Git代码库与数字资产集中存储于Perforce P4&#xff08;前身为Helix Core&#xff09;&#xff0c;为所有数字资产&#xff08;源码二进制文件&#xff09;构建单一事实来源。 突破代码库与文件限制 当艺术家、开发者及工程师组成的大型团队仅使用Git时…

day10_寻找用户推荐人

一、题目给出一张customer表&#xff0c;里面有id&#xff08;客户id&#xff09;——主键&#xff0c;name&#xff08;客户姓名&#xff09;&#xff0c;referee_id&#xff08;推荐人客户id&#xff09;三个字段二、题目要求1、找出被id不是2的用户推荐的客户姓名2、没有被任…

python爬虫(三)----Selenium

目录 1. Selenium 1.1 Selenium是啥 1.2 安装chrom Driver 1.3 selenium 使用 1.4 selenium元素定位 1.5 访问元素信息 1.6 交互 2. Phantomjs、Chrom handless 1. Selenium 1.1 Selenium是啥 自动化Web浏览器操作 主要用于Web应用程序的测试 支持多操作系统、多浏览器…

《事务隔离级别与 MVCC 机制深度剖析》

&#x1f50d; 事务隔离级别与 MVCC 机制深度剖析 &#x1f9e0; 前言 在高并发场景下&#xff0c;数据库事务是保证数据一致性的基石。但在 MySQL InnoDB 中&#xff0c;事务的隔离级别、锁策略、MVCC&#xff08;多版本并发控制&#xff09;之间的配合&#xff0c;常常是面…

20250814,通义万相,无限生成权限(慢速)

今天看小红书&#xff0c;发现通义万相可以免费生成慢速图片。研究一下每天10分用完后&#xff0c;按钮就变成0&#xff0c;但是可以点击这个0&#xff0c;进入排队慢速生成状态。原来通义万相的收费主要是用来提速的&#xff08;快速出图&#xff09;&#xff0c;不着急的话也…

Salesforce方案:医疗行业“患者随访与健康管理”

医疗行业“患者随访与健康管理”的Salesforce方案设计 一、业务需求核心解析 医疗行业患者随访与健康管理需实现三大目标&#xff1a; 全周期健康记录&#xff1a;整合患者基本信息、病史、诊疗记录及检查结果&#xff0c;形成完整健康档案个性化随访计划&#xff1a;基于病种和…

vscode使用keil5出现变量跳转不了

vscode使用keil5出现变量跳转不了&#xff0c;或者未包含文件&#xff0c;或者未全局检索&#xff1b; 参考如下文章后还会出现&#xff1b; 为什么vscode搜索栏只搜索已经打开的文件_vscode全局搜索只能搜当前文件-CSDN博客 在机缘巧合之下发现如下解决方式&#xff1a; 下载…

如何查看SQL Server的当前端口

想知道SQL Server用的是哪个端口&#xff1f; 很简单&#xff0c;通过注册表就能查到。第一步&#xff1a;打开注册表按下 Win R&#xff0c;输入&#xff1a;regedit回车&#xff0c;打开注册表编辑器。第二步&#xff1a;找到路径HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSS…

常见的Jmeter压测问题

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快根据在之前的压测过程碰到的问题&#xff0c;今天稍微总结总结&#xff0c;以后方便自己查找。一、单台Mac进行压测时候&#xff0c;压测客户端Jmeter启动超过2000个…

第二十三天:求逆序对

每日一道C题&#xff1a; 问题&#xff1a;给定一个序列a1,a2,…,an&#xff0c;如果存在i<j并且ai>aj&#xff0c;那么我们称之为逆序对&#xff0c;求逆序对的数目。 要求&#xff1a;输入第一行为n,表示序列长度&#xff0c;接下来的n行&#xff0c;第i1行表示序列中的…

Java—CompletableFuture 详解

参考&#xff1a; CompletableFuture原理与实践-外卖商家端API的异步化 - 美团技术团队 CompletableFuture 详解 | JavaGuide 1.CompletableFuture介绍 CompletableFuture是由Java 8引入的&#xff0c;在Java8之前我们一般通过Future实现异步。 Future用于表示异步计算的结…

大模型部署基础设施搭建 - 向量数据库milvus

一、docker方式安装参考官网&#xff1a;https://milvus.io/docs/zh/install_standalone-docker.md#Install-Milvus-in-Docker1.1 安装 curl -sfL https://raw.githubusercontent.com/milvus-io/milvus/master/scripts/standalone_embed.sh -o standalone_embed.shbash standal…

(25.08)Ubuntu20.04复现KISS-ICP

主页&#xff1a;https://github.com/PRBonn/kiss-icp?tabreadme-ov-file 仓库&#xff1a;https://github.com/PRBonn/kiss-icp.git 非 ROS 使用流程 1. 克隆仓库 git clone https://github.com/PRBonn/kiss-icp.git cd kiss-icp 2. 使用 micromamba 创建 Python 虚拟环…

linux 软硬链接详解

一、核心区别总览特性硬链接&#xff08;Hard Link&#xff09;软链接&#xff08;Symbolic Link&#xff09;本质直接指向文件的 inode&#xff08;数据块的入口地址&#xff09;指向文件的 路径名&#xff08;相当于快捷方式&#xff09;跨文件系统支持❌ 仅限同一文件系统✅…

基于SpringBoot+Vue的房屋匹配系统(WebSocket实时通讯、协同过滤算法、地图API、Echarts图形化分析)

&#x1f388;系统亮点&#xff1a;WebSocket实时通讯、协同过滤算法、地图API、Echarts图形化分析&#xff1b;一.系统开发工具与环境搭建1.系统设计开发工具后端使用Java编程语言的Spring boot框架 项目架构&#xff1a;B/S架构 运行环境&#xff1a;win10/win11、jdk17前端&…

第2节:多模态的核心问题(多模态大模型基础教程)

前言 本节课我们聚焦多模态大模型最核心的问题&#xff1a;文本、图像、语音这些“不同语言”的信息&#xff0c;是怎么被模型“翻译”并互相理解的&#xff1f;我们从“差异”入手&#xff0c;一步步搞懂其中的逻辑。 一、先搞懂&#xff1a;什么是“模态差异”&#xff1f; 生…

Java stream distinct findAny anyMatch实现 :DistinctOp、FindOp、MatchOp

DistinctOpsDistinctOps 是一个专门用于实现 Stream.distinct() 操作的工厂类。正如它的名字所示&#xff0c;它的核心职责就是创建能够去除流中重复元素的操作。distinct() 是一个有状态的中间操作 (stateful intermediate operation)&#xff0c;这意味着它通常需要看到所有元…

锁的基本介绍

锁 并发编程的一个最基本问题就是原子性地执行一系列指令。锁有助于直接解决这一问题。 锁的基本思想 锁就是一个变量。这个变量保存了锁在某一时刻的状态。它要么是可用的&#xff0c;表示没有线程持有锁&#xff0c;要么是被占用的&#xff0c;表示有线程持有锁&#xff0c;正…

【读代码】开源流式语音编码器SecoustiCodec

引言:从LLM到深度语义 在大型语言模型(LLM)驱动的语音交互时代,神经语音编解码器 (Neural Speech Codec) 扮演着至关重要的角色。它如同 LLM 的“耳朵”和“嘴巴”,负责将连续的语音波形转换为离散的、可供模型处理的 token,并将模型生成的 token 还原为自然的人声。 一…

P5967 [POI 2016] Korale 题解

P5967 [POI 2016] Korale 题目描述 有 nnn 个带标号的珠子&#xff0c;第 iii 个珠子的价值为 aia_iai​。 现在你可以选择若干个珠子组成项链&#xff08;也可以一个都不选&#xff09;&#xff0c;项链的价值为所有珠子的价值和。 给出所有可能的项链排序&#xff0c;先按…