C#【必备技能篇】使用NPOI实现对excel的读取和写入

news2025/1/12 21:07:57

文章目录

  • 1、Winform界面布局
  • 2、引用NPOI的dll
  • 3、源码
  • 4、运行效果
  • 5、NPOI的dll下载地址
  • 6、补充【以上步骤只能打开.xls文件(97-2003版本),打不开.xlsx文件(2007版本)】

1、Winform界面布局

在这里插入图片描述

2、引用NPOI的dll

在这里插入图片描述
在这里插入图片描述

3、源码

using NPOI.HSSF.UserModel;//HSSFWorkbook,97-2003版本,excel文件后缀为.xls
using NPOI.SS.UserModel;//IWorkbook,ISheet,IRow,ICell,DateUtil需要此引用
using NPOI.XSSF.UserModel;//XSSFWorkbook,2007版本,excel文件后缀为.xlsx
using System;
using System.Data;
using System.IO;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        public static DataTable NPExcelToDataTable(string fileName, string sheetName = "")
        {
            FileStream fs = null;
            IWorkbook workbook = null;//IWorkbook是一个接口,XSSFWorkbook和HSSFWorkbook都继承自此接口
            ISheet sheet = null;//ISheet也是一个接口
            DataTable dt = new DataTable();
            try
            {
                //【1】读取excel文件,并新建workbook和sheet
                fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
                if (fileName.IndexOf(".xlsx") > 0)      // 2007版本
                    workbook = new XSSFWorkbook(fs);
                else if (fileName.IndexOf(".xls") > 0)  // 97-2003版本
                    workbook = new HSSFWorkbook(fs);
                //workbook = NPOI.SS.UserModel.WorkbookFactory.Create(fs);
                if (sheetName != "")                    //是否有传入表名
                {
                    sheet = workbook.GetSheet(sheetName);
                }
                else
                {
                    sheet = workbook.GetSheetAt(0);    //读取第一个sheet
                }

                //【2】解析excel文件的内容,填充到dt中
                if (sheet == null)//工作表中的内容为null时
                {
                    throw new Exception("未找到工作表");
                }

                dt.TableName = sheet.SheetName;

                //解析sheet的第一行数据,添加dt的列头名
                int startRow = 0;   //开始读取行数 
                IRow firstRow = sheet.GetRow(startRow);   //第一行 
                int cellCount = firstRow.LastCellNum;     //一行最后一个cell的编号,即总的列数
                for (int i = firstRow.FirstCellNum; i < cellCount; i++)
                {
                    ICell cell = firstRow.GetCell(i);
                    if (cell != null)
                    {
                        string cellValue = cell.StringCellValue;
                        if (cellValue != null)
                        {
                            if (dt.Columns.IndexOf(cellValue) > 0)  //如果已经有此列名,则结果>0,列名名称加上“重复列名”和"列的列数i"
                            {
                                DataColumn column = new DataColumn(Convert.ToString("重复列名" + cellValue + i));
                                dt.Columns.Add(column); 
                            }
                            else
                            {
                                DataColumn column = new DataColumn(cellValue);
                                dt.Columns.Add(column);
                            }
                        }
                    }
                }

                //添加dt的所有行内容
                startRow = startRow + 1;
                int rowCount = sheet.LastRowNum;      //总行数                                                     
                for (int i = startRow; i <= rowCount; i++)
                {
                    IRow row = sheet.GetRow(i);
                    if (row == null) continue; //没有数据的行默认是null

                   DataRow dataRow = dt.NewRow();
                    for (int j = row.FirstCellNum; j < cellCount; j++)
                    {
                        ICell cell = row.GetCell(j);
                        if (cell != null)        //同理,没有数据的单元格都默认是null
                        {
                            if (cell.CellType == CellType.Formula)   //公式时
                            {
                                try
                                {
                                    dataRow[j] = cell.StringCellValue;
                                }
                                catch
                                {
                                    if (DateUtil.IsCellDateFormatted(cell))   //日期时
                                    {
                                        dataRow[j] = cell.DateCellValue;
                                    }
                                    else { dataRow[j] = cell.NumericCellValue; }//数字时
                                }
                            }
                            else { dataRow[j] = cell.ToString(); }
                        }
                    }
                    dt.Rows.Add(dataRow);
                }

                //使用完excel文件后,一定要关闭
                fs.Close();
                return dt;
            }
            catch (Exception ex)
            {
                if (fs != null)
                {
                    fs.Close();
                }
                throw new Exception(ex.Message);
            }
        }

        //导入excel数据到datagridview
        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                DataTable dt = new DataTable();
                dt = NPExcelToDataTable(txt_Path.Text, "");
                dataGridView1.DataSource = dt;
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
           
        }

        //打开文件
        private void button2_Click(object sender, EventArgs e)
        {
            openFileDialog1.Filter = "Excel文件|*.xls;*.xlsx";//设置打开文件筛选器
            openFileDialog1.Title = "选择Excel文件";//设置打开对话框标题
            openFileDialog1.Multiselect = false;//设置打开对话框中只能单选
            if (openFileDialog1.ShowDialog() == DialogResult.OK)//判断是否选择了文件
            {
                txt_Path.Text = openFileDialog1.FileName;//在文本框中显示Excel文件名
            }
        }

        //添加一行内容并保存到excel
        private void button3_Click(object sender, EventArgs e)
        {
            try
            {
                HSSFWorkbook wk = new HSSFWorkbook();
                //创建一个sheet
                ISheet sheet = wk.CreateSheet("例子");
                //在第一行创建行
                IRow row = sheet.CreateRow(0);
                //在第一行的第一列创建单元格
                for (int i = 0; i < 10; i++)
                {
                    ICell cell = row.CreateCell(i);
                    cell.SetCellValue("测试" + i);
                }

                using (FileStream fs = File.OpenWrite(".\\excel.xls"))
                {
                    wk.Write(fs);
                }
                MessageBox.Show("已新建和保存excel文件");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        //更改excel中第一行的数据(除了列头)
        private void button4_Click(object sender, EventArgs e)
        {
            try
            {
                string tempPath = ".\\excel.xls";
                HSSFWorkbook wk = null;
                using (FileStream fs = File.Open(tempPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {
                    wk = new HSSFWorkbook(fs);
                    fs.Close();
                }
                //选定名为"例子"的sheet    
                ISheet sheet = wk.GetSheet("例子");
                //在第二行创建单元格 
                IRow row = sheet.CreateRow(1);
               //为第二行中前10列赋值
                for (int i = 0; i < 10; i++)
                {
                    ICell cell = row.CreateCell(i);
                    cell.SetCellValue("SS" + i);
                }

                //将编辑值后的workbook保存到excel中
                using (FileStream fileStream = File.Open(".\\excel.xls", FileMode.OpenOrCreate, FileAccess.ReadWrite))
                {
                    wk.Write(fileStream);
                    fileStream.Close();
                }
                MessageBox.Show("成功编辑excel中的值");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        //更改excel中第一行的单元格样式(除了列头)
        private void button5_Click(object sender, EventArgs e)
        {
            try
            {
                HSSFWorkbook wk = null;
                string tempPath = ".\\excel.xls";
                using (FileStream fs = File.Open(tempPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {
                    wk = new HSSFWorkbook(fs);
                    fs.Close();
                }
                ICellStyle cellStyle = wk.CreateCellStyle();
                //设置单元格上下左右边框线 
                cellStyle.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
                cellStyle.BorderBottom = NPOI.SS.UserModel.BorderStyle.SlantedDashDot;
                cellStyle.BorderLeft = NPOI.SS.UserModel.BorderStyle.SlantedDashDot;
                cellStyle.BorderRight = NPOI.SS.UserModel.BorderStyle.SlantedDashDot;
                //文字水平和垂直对齐方式  
                cellStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;
                cellStyle.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center;
                //是否换行  
                //cellStyle.WrapText = true;  
                //缩小字体填充  
                cellStyle.ShrinkToFit = true;

                //选定名为"例子"的sheet    
                ISheet sheet = wk.GetSheet("例子");

                //在第二行创建单元格 
                IRow row = sheet.GetRow(1);
                //为第二行中前10列赋值
                for (int i = 0; i < 10; i++)
                {
                    ICell cell = row.GetCell(i);
                    cell.CellStyle = cellStyle;
                }

                //将编辑值后的workbook保存到excel中
                using (FileStream fileStream = File.Open(".\\excel.xls", FileMode.OpenOrCreate, FileAccess.ReadWrite))
                {
                    wk.Write(fileStream);
                    fileStream.Close();
                }
                MessageBox.Show("格式设置成功,请打开excel文件查看");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

        }

        //读取excel中第1列第1行的值(除了列头)
        private void button6_Click(object sender, EventArgs e)
        {
            try
            {
                string ExcelFilePath = ".\\excel.xls";

                NPOI.SS.UserModel.IWorkbook wk = null;
                using (FileStream fs = File.Open(ExcelFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {
                    if (ExcelFilePath.IndexOf(".xlsx") > 0) // 2007版本
                        wk = new NPOI.XSSF.UserModel.XSSFWorkbook(fs);
                    else if (ExcelFilePath.IndexOf(".xls") > 0) // 97-2003版本
                        wk = new NPOI.HSSF.UserModel.HSSFWorkbook(fs);
                    fs.Close();
                }
               
                ISheet sheet = wk.GetSheetAt(0);//获取第一个sheet
                //int count = wk.NumberOfSheets;//获取一个excel文件中sheet的总数
                textBox1.Text = sheet.GetRow(0).GetCell(0).StringCellValue;//获取第一行第一列的值
                MessageBox.Show("成功读取excel中的值");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
    }
}

4、运行效果

依次执行下图中的1-6按钮
可以通过查看程序文件夹中的excel文件来加深理解。
在这里插入图片描述
请添加图片描述

5、NPOI的dll下载地址

链接:https://pan.baidu.com/s/19PgQMhCKviw9aBAjmJHSww
提取码:2omi
在这里插入图片描述

6、补充【以上步骤只能打开.xls文件(97-2003版本),打不开.xlsx文件(2007版本)】

需要在源码中增加如下引用。相应的dll已更新到5的下载地址中。
在这里插入图片描述

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

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

相关文章

(十二)devops持续集成开发——jenkins的全局工具配置之sonar qube环境安装及配置

前言 本节内容我们主要介绍一下在jenkins中如何集成sonar qube代码质量检查工具&#xff0c;sonar qube可以在流水化项目集成部署前对我们的代码质量检查。开始本节内容前我们需要先搭建好sonar qube服务&#xff0c;关于sonar qube服务的搭建可参考作者往期博客内容&#xff…

P4391 [BOI2009]Radio Transmission 无线传输

题目描述 给你一个字符串 s_1s1​&#xff0c;它是由某个字符串 s_2s2​ 不断自我连接形成的。但是字符串 s_2s2​ 是不确定的&#xff0c;现在只想知道它的最短长度是多少。 输入格式 第一行一个整数 LL&#xff0c;表示给出字符串的长度。 第二行给出字符串 s_1s1​ 的一个子…

【linux入门】基础知识学习笔记

文章目录【第一章-宏观知识】1.硬件和软件的关系2.操作系统 是什么、作用是什么3.常见的操作系统4.Linux的诞生5.Linux内核 是什么6.Linux发行版 是什么7.WSL是什么8.虚拟机快照9.FinalShell&#xff08;Xshell替代品&#xff09;【第二章-Linux基础命令】1.Linux目录结构2.什么…

Linux---权限

目录 1.文件访问者的分类&#xff08;人/用户&#xff09; 2.文件类型和访问权限&#xff08;事物属性&#xff09; 3.文件权限值的表示方法 a)字符表示方法 b)8进制数值表示方法 4.文件访问权限的相关设置方法 4.1 改属性 4.2 改人&#xff08;改拥有者/所属组&#xff09;…

数组常用方法总结 (3) :map / forEach / every / some

map 遍历数组的每一项。如果是简单数组&#xff0c;不改变原始数组&#xff08;值类型&#xff09;。如果是对象数组&#xff0c;原始数组可以被改变&#xff08;引用类型&#xff09;。遍历原始数组&#xff0c;返回值为原始数组的每一项&#xff0c;最终可组合成新数组。 简…

LeetCode 78 子集 | 解题思路分享

原题链接&#xff1a;78. 子集 - 力扣&#xff08;LeetCode&#xff09; 题目难度&#xff1a;中等 题目描述 给你一个整数数组 nums &#xff0c;数组中的元素 互不相同 。返回该数组所有可能的子集&#xff08;幂集&#xff09;。 解集 不能 包含重复的子集。你可以按 任…

忆享聚焦|5G投资、网络安全市场、云计算、Web3技术……近期热点资讯一览

“忆享聚焦”栏目第11期来啦&#xff01;本栏目汇集近期互联网最新资讯&#xff0c;聚焦前沿科技&#xff0c;关注行业发展动态&#xff0c;筛选高质量讯息&#xff0c;拓宽用户视野&#xff0c;让您以最低的时间成本获取最有价值的行业资讯。目录行业资讯1. SA&#xff1a;全球…

ubuntu虚拟机VmWare与主机共享文件夹

一、说明&#xff1a; 宿主操作系统&#xff1a;Windows 11 64位。 客户操作系统&#xff1a;Ubuntu 18.04.1 64位。 虚拟机软件&#xff1a;VMware Workstation 17 pro 二、步骤&#xff1a; 1、参考教程链接1&#xff0c;在主机设置共享文件夹。 注意&#xff1a;教程链接…

聚焦技术,2022巨杉荣获国内外多家权威机构认可

作为分布式数据库的领先企业 巨杉成立十年来&#xff0c;一直聚焦分布式技术的自研与深耕 在分布式数据库领域已取得丰硕的成果 回望2022&#xff0c;巨杉除在客户案例及产品方面屡获殊荣外 也凭借过硬的技术实力及规模化的行业应用 得到多家国内外权威机构的认可 国际权威…

TensorRT学习笔记--基本概念和推理流程

目录 前言 1--Tensor RT基本概念 2--推理流程 3--实例代码 前言 以下 Tensor RT 的基本概念和推理流程均为博主自我的理解&#xff0c;可能部分内存会存在错误或偏差&#xff0c;仅供参考&#xff01; 1--Tensor RT基本概念 ① Logger&#xff1a;日志记录器&#xff0c;…

ssm:spring定时任务Task和CronExpression表达式

开发一个定时任务&#xff1a;每天晚上23点执行数据归集任务 首先Spring配置文件&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework.org/schema/beans"xmlns:xsi"http://www.w3.or…

Java中的常用的代理模式

本文介绍在Java种常用的3种动态代理。 代理模式是23种模式中的一种&#xff0c;属于结构型设计模式。这种模式的作用就是要创建一个中间对象&#xff08;相当于中介或者代理对象&#xff09;&#xff0c;通过操作中间对象来间接调用目的对象的方法&#xff0c;字段等&#xff0…

Everything搜索知识总结

1.只知道那个文件以 .txt结尾 .*\.txt$ ($表示以什么结尾) 2.搜索某个路径下的文件 D:\ configure.bat (搜索D盘下的该文件,注意要用这种类型的"\",和被搜索的文件之间有空格;要先打出路径,再打出搜索文件.) 3.搜索指定路径下的多个文件 路径\ 文件1 | …

Halcon亚像素边缘缺陷检测案例

一、下面的案例是总结的Halcon边缘缺陷检测的一种情况。本案例是利用阈值分割获取金属区域&#xff0c;并利用boundary和edges_sub_pix获取到亚像素边缘。然后综合利用fit_rectangle2_contour_xld拟合出金属对应的放射矩形&#xff0c;最后利用dist_rectangle2_contour_points_…

【小白课程】openKylin用户手册原理解析,一招教你学会自定义!

openKylin用户手册是详细描述openKylin操作系统的功能和用户界面&#xff0c;让用户了解如何使用该软件的说明书。通过阅读openKylin用户手册&#xff0c;能够更快更好的上手和使用openKylin操作系统。今天就带大家简单了解下openKylin用户手册的实现原理以及如何自定义用户手册…

用EditPlus编译Fortran

一、EditPlus配置 语法点亮 安装好EditPlus后&#xff0c;点击Tool->Prefenrences&#xff0c;在File->Setting&syntex下&#xff0c;点击Add按钮&#xff0c;填Frotran。 到EditPlus官网上 EditPlus - User Files (other files) 下载Fortran语法文件 ​ 二、配置…

设计模式学习(四):Strategy策略模式

一、什么是Strategy模式 Strategy的意思是“策略”&#xff0c;指的是与敌军对垒时行军作战的方法。在编程中&#xff0c;我们可以将它理解为“算法”。无论什么程序&#xff0c;其目的都是解决问题。而为了解决问题&#xff0c;我们又需要编写特定的算法。使用Strategy模式可以…

Redis- 主从复制原理

1、概述 Master节点在平时提供服务&#xff0c;另外一个或多个Slave节点在平时不提供服务&#xff08;或只提供数据读取服务&#xff09;。当Master节点由于某些原因停止服务后&#xff0c;再人工/自动完成Slave节点到Master节点的切换工作&#xff0c;以便整个Redis集群继续向…

Spring依赖注入源码分析

1. 前言 Spring的核心之一就是依赖注入&#xff0c;Spring提供了Autowired注解来给bean注入依赖。除了注入最基本的bean之外&#xff0c;Spring还做了一些扩展&#xff0c;例如你可以注入Optional&#xff0c;以此来判断依赖的bean是否存在&#xff1b;你还可以注入Map来获得所…

Leetcode:617. 合并二叉树(C++)

目录 问题描述&#xff1a; 实现代码与解析&#xff1a; 递归&#xff1a; 原理思路&#xff1a; 迭代&#xff1a; 原理思路&#xff1a; 问题描述&#xff1a; 给你两棵二叉树&#xff1a; root1 和 root2 。 想象一下&#xff0c;当你将其中一棵覆盖到另一棵之上时&am…