NPOI 操作详解(操作Excel)
目录
1. 安装 NPOI
2. 使用 NPOI 创建新 Excel 文件
3. 设置列宽和行高
1. 设置列宽
2. 设置行高
3. 同时设置列宽和行高
4. 设置统一的行高
5. 设置统一的列宽
6. 应用统一的行高和列宽
4. 合并单元格
5. 设置单元格样式(字体、边框、背景色等)
5. 向现有的 Excel 文件追加数据
6. 综合操作示例
概述:NPOI 是一个功能强大的第三方库,支持 .xls 和 .xlsx 格式,且完全开源。NPOI 可以在任何平台上运行,无需安装 Excel。
优点:跨平台,支持 .xls 和 .xlsx 格式,性能较好。
缺点:与原生 Excel 功能兼容性较低,格式化和高级功能支持相对有限。
1. 安装 NPOI

2. 使用 NPOI 创建新 Excel 文件
以下代码演示了如何使用 NPOI 创建一个新的 Excel 文件,并向其中写入 DataTable 数据。
using System.Data;
using System.IO;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel; // 对于 .xlsx 文件
using NPOI.HSSF.UserModel; // 对于 .xls 文件public void CreateNewExcel(string filePath, DataTable dataTable)
{IWorkbook workbook;if (filePath.EndsWith(".xlsx"))workbook = new XSSFWorkbook(); // 创建 .xlsx 文件elseworkbook = new HSSFWorkbook(); // 创建 .xls 文件var sheet = workbook.CreateSheet("Sheet1");// 写入表头var headerRow = sheet.CreateRow(0);for (int i = 0; i < dataTable.Columns.Count; i++){headerRow.CreateCell(i).SetCellValue(dataTable.Columns[i].ColumnName);}// 写入数据for (int i = 0; i < dataTable.Rows.Count; i++){var dataRow = sheet.CreateRow(i + 1);for (int j = 0; j < dataTable.Columns.Count; j++){dataRow.CreateCell(j).SetCellValue(dataTable.Rows[i][j].ToString());}}// 保存文件using (var stream = new FileStream(filePath, FileMode.Create, FileAccess.Write)){workbook.Write(stream);}
}
3. 设置列宽和行高
1. 设置列宽
public void SetColumnWidth(IWorkbook workbook, int sheetIndex, int columnIndex)
{var sheet = workbook.GetSheetAt(sheetIndex);// 设置列宽(单位是 1/256 字符宽度)sheet.SetColumnWidth(columnIndex, 20 * 256); // 设置第 1 列宽度为 20
}
2. 设置行高
public void SetColumnRowHeight(IWorkbook workbook, int sheetIndex, int rowIndex)
{var sheet = workbook.GetSheetAt(sheetIndex);// 设置行高(单位是点数)var row = sheet.GetRow(rowIndex) ?? sheet.CreateRow(rowIndex);row.HeightInPoints = 25; // 设置行高为 25 点
}
3. 同时设置列宽和行高
public void SetColumnWidthAndRowHeight(IWorkbook workbook, int sheetIndex, int columnIndex, int rowIndex)
{var sheet = workbook.GetSheetAt(sheetIndex);// 设置列宽(单位是 1/256 字符宽度)sheet.SetColumnWidth(columnIndex, 20 * 256); // 设置第 1 列宽度为 20// 设置行高(单位是点数)var row = sheet.GetRow(rowIndex) ?? sheet.CreateRow(rowIndex);row.HeightInPoints = 25; // 设置行高为 25 点
}
4. 设置统一的行高
在 NPOI 中,行高是通过每一行对象来设置的。可以遍历所有行并设置它们的行高,也可以在每次创建行时直接设定统一的高度。
public void SetUniformRowHeight(ISheet sheet, float heightInPoints)
{for (int i = 0; i <= sheet.LastRowNum; i++){var row = sheet.GetRow(i) ?? sheet.CreateRow(i);row.HeightInPoints = heightInPoints; // 设置行高}
}
5. 设置统一的列宽
列宽可以直接对整个列进行设置,无需单独遍历单元格。列宽是以 1/256 字符宽度为单位的,设置时需要乘以 256。
public void SetUniformColumnWidth(ISheet sheet, int widthInCharacters)
{for (int i = 0; i < sheet.GetRow(0).LastCellNum; i++) // 以第一行的单元格数量为列数{sheet.SetColumnWidth(i, widthInCharacters * 256); // 设置列宽}
}
6. 应用统一的行高和列宽
可以将行高和列宽设置封装在一个方法中调用:
public void SetUniformRowHeightAndColumnWidth(ISheet sheet, float rowHeightInPoints, int columnWidthInCharacters)
{SetUniformRowHeight(sheet, rowHeightInPoints);SetUniformColumnWidth(sheet, columnWidthInCharacters);
}
使用示例:
假设我们有一个表格 sheet,要将所有行高统一设置为 20 点,列宽统一设置为 15 个字符宽:
SetUniformRowHeightAndColumnWidth(sheet, 20, 15);
这样就能高效地将整个表格的行高和列宽统一设置,无需遍历每个单元格。
4. 合并单元格
合并单元格可以通过 CellRangeAddress 设置,需要定义起始和结束的行列。
using NPOI.SS.Util;public void MergeCells(IWorkbook workbook, int sheetIndex, int firstRow, int lastRow, int firstCol, int lastCol)
{var sheet = workbook.GetSheetAt(sheetIndex);// 合并单元格var cellRangeAddress = new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);sheet.AddMergedRegion(cellRangeAddress);// 可以对合并后的单元格设置样式var cell = sheet.GetRow(firstRow).GetCell(firstCol) ?? sheet.GetRow(firstRow).CreateCell(firstCol);var style = workbook.CreateCellStyle();style.Alignment = HorizontalAlignment.Center;cell.CellStyle = style;
}
5. 设置单元格样式(字体、边框、背景色等)
使用 ICellStyle 进行字体、对齐、边框、背景等样式的配置:
public void SetCellStyle(IWorkbook workbook, int sheetIndex, int rowIndex, int colIndex)
{var sheet = workbook.GetSheetAt(sheetIndex);var cell = sheet.GetRow(rowIndex).GetCell(colIndex) ?? sheet.GetRow(rowIndex).CreateCell(colIndex);var style = workbook.CreateCellStyle();// 设置字体var font = workbook.CreateFont();font.FontHeightInPoints = 12;font.FontName = "Arial";font.IsBold = true;style.SetFont(font);// 设置边框style.BorderBottom = BorderStyle.Thin;style.BorderLeft = BorderStyle.Thin;style.BorderRight = BorderStyle.Thin;style.BorderTop = BorderStyle.Thin;// 设置背景颜色style.FillForegroundColor = IndexedColors.LightBlue.Index;style.FillPattern = FillPattern.SolidForeground;cell.CellStyle = style;cell.SetCellValue("示例文本");
}
5. 向现有的 Excel 文件追加数据
追加数据时,可以定位到现有数据的末尾,创建新行并写入。
public void AppendDataToExistingExcel(string filePath, DataTable dataTable)
{IWorkbook workbook;using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read)){workbook = filePath.EndsWith(".xlsx") ? (IWorkbook)new XSSFWorkbook(stream) : new HSSFWorkbook(stream);}var sheet = workbook.GetSheetAt(0);int lastRowNum = sheet.LastRowNum;for (int i = 0; i < dataTable.Rows.Count; i++){var dataRow = sheet.CreateRow(lastRowNum + i + 1);for (int j = 0; j < dataTable.Columns.Count; j++){dataRow.CreateCell(j).SetCellValue(dataTable.Rows[i][j].ToString());}}using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Write)){workbook.Write(stream);}
}
6. 综合操作示例
将所有设置组合在一起,确保不同操作可以在一个文件中同时应用:
public void FullExample(string filePath, DataTable dataTable)
{IWorkbook workbook = filePath.EndsWith(".xlsx") ? (IWorkbook)new XSSFWorkbook() : new HSSFWorkbook();var sheet = workbook.CreateSheet("Sheet1");// 设置表头var headerRow = sheet.CreateRow(0);for (int i = 0; i < dataTable.Columns.Count; i++){headerRow.CreateCell(i).SetCellValue(dataTable.Columns[i].ColumnName);}// 写入数据for (int i = 0; i < dataTable.Rows.Count; i++){var dataRow = sheet.CreateRow(i + 1);for (int j = 0; j < dataTable.Columns.Count; j++){dataRow.CreateCell(j).SetCellValue(dataTable.Rows[i][j].ToString());}}// 设置列宽和行高SetColumnWidthAndRowHeight(workbook, 0, 1, 1);// 合并单元格(比如合并第 2 行第 1 列到第 2 列)MergeCells(workbook, 0, 1, 1, 0, 1);// 设置单元格样式SetCellStyle(workbook, 0, 1, 1);// 保存文件using (var stream = new FileStream(filePath, FileMode.Create, FileAccess.Write)){workbook.Write(stream);}
}
总结:
- 创建、读取、追加、设置样式等基本操作可以涵盖常见的 NPOI 使用场景。
- NPOI 适合处理数据量较大的 Excel 文件,不依赖于 Excel 安装,并且支持 .xls 和 .xlsx 格式。
相关文章:
NPOI 操作详解(操作Excel)
目录 1. 安装 NPOI 2. 使用 NPOI 创建新 Excel 文件 3. 设置列宽和行高 1. 设置列宽 2. 设置行高 3. 同时设置列宽和行高 4. 设置统一的行高 5. 设置统一的列宽 6. 应用统一的行高和列宽 4. 合并单元格 5. 设置单元格样式(字体、边框、背景色等…...
2024年北京海淀区中小学生信息学竞赛校级预选赛试题
2024年北京海淀区中小学生信息学竞赛校级预选赛试题 题目总数:24 总分数:100 编程基础知识单选题 第 1 题 单选题 关于 2024年海淀区信息学竞赛的描述错误的是( ) A.报名在网上报名系统进行 B.必须经过学籍所在学校的指导教师审核 C.学校…...
GPT-SoVITS 部署方案
简介 当前主流的开源TTS框架,这里介绍部署该服务的主要流程和我在使用过程中出现的问题。 使用的技术 Docker、Jupyter、Python、C# 部署 docker的使用 拉取命令 docker pull jupyter/base-notebook:python-3.10.11jupyter的访问 docker运行以后可以直接使用…...
pdf添加目录标签python(手动配置)
先安装对应的库: pip install pypdf 代码分为两个部分,一部分是config.py,代码如下: offset=10 catgorys=[("第一章",12),("第二章",45), ] 需要自己手动更改offset,和目录列表 下面是主要代码: import pypdf # import sys from config import…...
Ngrok 在树莓派上的配置与使用教程
Ngrok 是一个便捷的工具,用于将本地服务器暴露到互联网上,常用于开发和调试。 1. 更新树莓派 首先,更新树莓派的系统: sudo apt update sudo apt upgrade -y2. 安装 Ngrok (1)下载 Ngrok: 访…...
多核架构的基本概念
目录 1.为什么使用多核 2.多核分类 2.1 同构和异构 2.2 SMP和AMP 3 小结 1.为什么使用多核 这个问题个人认为可以从两个方面来看: 性能问题 随着汽车ECU对集成化的要求越来越高,把多个ECU功能集中到一个多核MCU的需求也越来越明显。 以汽车制动…...
yolov8模型推理测试代码(pt/onnx)
🦖yolov8训练出来的模型,不使用detect.py代码进行模型测试🦖 pt格式模型测试 import cv2 import os from ultralytics import YOLO # 定义输入和输出文件夹路径 input_folder /input/folder # 输入文件夹 output_folder /output/folder …...
二叉树 最大深度(递归)
给定一个二叉树 root ,返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1: 输入:root [3,9,20,null,null,15,7] 输出:3示例 2: 输入:root [1,null,2] 输出…...
C++详细笔记(五)
1.类和对象 1.1运算符重载(补) 1.运算符重载中,参数顺序和操作数顺序是一致的。 2.一般成员函数重载为成员函数,输入流和输出流重载为全局函数。 3.由1和2只正常的成员函数默认第一个参数为this指针而重载中参数顺序和操作数顺…...
简易CPU设计入门:译码模块(一)
项目代码下载 还是请大家首先准备好本项目所用的源代码。如果已经下载了,那就不用重复下载了。如果还没有下载,那么,请大家点击下方链接,来了解下载本项目的CPU源代码的方法。 下载本项目代码 准备好了项目源代码以后ÿ…...
力扣题目解析--三数之和
题目 给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k ,同时还满足 nums[i] nums[j] nums[k] 0 。请你返回所有和为 0 且不重复的三元组。 注意:答案中不可以包含重复的三元组。 示…...
qt QTabWidget详解
1、概述 QTabWidget是Qt框架中的一个控件,它提供了一个标签页式的界面,允许用户在不同的页面(或称为标签)之间切换。每个页面都可以包含不同的内容,如文本、图像、按钮或其他小部件。QTabWidget非常适合用于创建具有多…...
linux shell脚本学习(1):shell脚本基本概念与操作
1.什么是shell脚本 linux系统中,shell脚本或称之为bash shell程序,通常是由vim编辑,由linux命令、bash shell指令、逻辑控制语句、注释信息组成的可执行文件 *linux中常以.sh后缀作为shell脚本的后缀。linux系统中文件乃至脚本的后缀并没有…...
Savitzky-Golay(SG)滤波器
Savitzky-Golay(SG)滤波器是一种在时域内基于局域多项式最小二乘法拟合的滤波方法,它最初由Savitzky A和Golay M于1964年提出,并广泛应用于数据流平滑除噪。 基本介绍 一、基本原理 SG滤波器通过在滑动窗口内拟合多项式来平滑数…...
Webserver(2.7)共享内存
目录 共享内存共享内存实现进程通信 共享内存 共享内存比内存映射效率更高,因为内存映射关联了一个文件 共享内存实现进程通信 write.c #include <stdio.h> #include <sys/ipc.h> #include <sys/shm.h> #include <string.h>int main(){…...
【网安案例学习】凭证填充Credential Stuffing
### 凭证填充的深入讨论 凭证填充(Credential Stuffing)是一种网络攻击技术,攻击者利用从数据泄露中获取的大量用户名和密码组合,尝试在其他网站和服务上进行自动化登录。这种攻击依赖于用户在多个网站上重复使用相同密码的习惯。…...
网站建设公司怎么选?网站制作公司怎么选才不会出错?
寻找适合靠谱的网站设计公司,不要盲目选广告推最多的几家,毕竟要实现自身品牌营销,还是需要多方面考量。以下几个方面可以作为选择的参考: 1. 专业能力如何? 一个公司的专业能力,决定了最后网站设计的成果…...
19. 架构重要需求
文章目录 第19章 架构重要需求19.1 从需求文档中收集架构重要需求(ASRs)不要抱太大希望从需求文档中找出架构重要需求 19.2 通过访谈利益相关者收集架构重要需求19.3 通过理解业务目标收集架构重要需求19.4 在效用树中捕获架构重要需求19.5 变化总会发生…...
iOS 再谈KVC、 KVO
故事背景:大厂面试,又问道了基本的kvc kvo的原理和使用,由于转了前端,除了个setter和getter,我全忘记了,其实还是没有理解记忆,下面再看一下kvc 和kvo ,总结一个让人通过理解而无法忘记的方法&a…...
java、excel表格合并、指定单元格查找、合并文件夹
#创作灵感# 公司需求 记录工作内容 后端:JAVA、Solon、easyExcel、FastJson2 前端:vue2.js、js、HTML 模式1:合并文件夹 * 现有很多文件夹 想合并全部全部的文件夹的文件到一个文件夹内 * 每个部门发布的表格 合并全部的表格为方便操作 模…...
大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...
招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...
