C# 使用NPOI操作EXCEL

1.添加NOPI

        引用->管理NuGet程序包->添加NOPI

2.相关程序集

3.添加命名空间

using NPOI.HSSF;
using NPOI.XSSF;
using System.IO;
using NPOI.XSSF.UserModel;
using NPOI.HSSF.UserModel;

4.从Excel导入的dgv样例

//NPOI读入dgv
private void button1_Click(object sender, EventArgs e)
{
    DataTable dtNpoi = new DataTable();
    string fileName = @"D:\desktop\tmp\test.xlsx";
    string sheetName = "sheet1";
    bool isColumnName = true;
    IWorkbook workBook;

    string fileExt = Path.GetExtension(fileName).ToLower(); //获取文件拓展名
    using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
    {
        if(fileExt == ".xlsx")  //新版
        {
            workBook = new XSSFWorkbook(fs);
        }
        else if(fileExt == ".xls")  //旧版
        {
            workBook = new HSSFWorkbook(fs);
        }
        else
        {
            workBook=null;
        }

        //实例化sheet(指定名称没加载出来就通过索引加载sheet)
        ISheet sheet = null;
        if(sheetName != null &&  sheetName.Length > 0) 
        {
            sheet = workBook.GetSheet(sheetName);   //获取指定名称的工作表
            if(sheet == null )
            {
                sheet = workBook.GetSheetAt(0); //工作簿没有内容,通过索引0返回空worksheet对象,不会null报错
            }
        }
        else
        {
            sheet = workBook.GetSheetAt(0); //获取第一个工作表
        }


        //获取表头FirstRowNum第一行索引就是0
        IRow header = sheet.GetRow(sheet.FirstRowNum);  //获取第一行
        int startRow = 0;  //数据的第一行索引
        if(isColumnName)    //表示第一行是列名信息
        {
            startRow = sheet.FirstRowNum + 1;   //第一行应该是从1开始的
            //遍历第一行的单元格 列名 0
            for (int i = header.FirstCellNum; i < header.LastCellNum; i++)
            {
                //获取指定索引单元格
                ICell cell = header.GetCell(i);
                if(cell != null)
                {
                    //获取列名的值
                    string cellValue = cell.ToString();
                    if(cellValue != null)
                    {
                        DataColumn col = new DataColumn(cellValue); //记住可以这样子添加
                        dtNpoi.Columns.Add(col);
                    }
                    else
                    {
                        DataColumn col = new DataColumn();
                        dtNpoi.Columns.Add(col);
                    }
                }
            }
        }

        //数据    LastRowNum最后一行的索引 如第九行索引是8
        for (int i = startRow; i <= sheet.LastRowNum; i++)
        {
            IRow row = sheet.GetRow(i); //获取第i行
            if(row == null )
            {
                continue;
            }

            DataRow dr = dtNpoi.NewRow();

            //遍历每行的单元格
            for (int j = row.FirstCellNum; j < row.LastCellNum; j++)
            {
                if(row.GetCell(j) != null)
                    dr[j] = row.GetCell(j).ToString();
            }
            dtNpoi.Rows.Add(dr);
        }

    }
    this.dataGridView1.DataSource = dtNpoi;
    
}

5.从dgv导入到Excel

DataTable dtTable = this.dataGridView1.DataSource as DataTable; //表1转换为DataTable
string sheetName = "sheet1";
//创建工作簿
IWorkbook wb = new HSSFWorkbook();
//这个创建sheet很巧妙
ISheet sheet = string.IsNullOrEmpty(sheetName) ? wb.CreateSheet("sheet1") : wb.CreateSheet(sheetName);
int rowIndex = 0;
if(dtTable.Columns.Count > 0)
{
    IRow header = sheet.CreateRow(rowIndex);    //创建第一行
    for (int i = 0; i < dtTable.Columns.Count; i++)
    {
        ICell cell = header.CreateCell(i);  //给第一行赋值
        cell.SetCellValue(dtTable.Columns[i].ColumnName);
    }
}

//添加数据
if(dtTable.Rows.Count > 0)
{
    for (int i = 0; i < dtTable.Rows.Count; i++)
    {
        rowIndex++;
        IRow row = sheet.CreateRow(rowIndex);
        for (int j = 0; j < dtTable.Columns.Count; j++)
        {
            ICell cell = row.CreateCell(j);
            cell.SetCellValue(dtTable.Rows[i][j].ToString());
        }
    }
}


//列的大小为自动
for (int i = 0; i < dtTable.Columns.Count; i++)
{
    //sheet.AutoSizeColumn(i);
}

string fileName = @"D:\desktop\tmp\NPOI导出.xls";
using(FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write))
{
    wb.Write(fs);   //这个workbook竟然可以直接写
}

MessageBox.Show("导出成功!");

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【C++练习】C++中读取.txt文件中的数据(由简到难)

1 将数据写入.txt文本中&#xff0c;再从.txt中读取到string字符串里&#xff0c;输出到终端 #include <iostream> #include <fstream>//包头文件 using namespace std;int main() {//1. 创建流对象ofstream ofs;//2. 以写的方式打开文件&#xff08;若文件不存在…

视频汇聚/视频监控管理平台EasyCVR接入海康SDK协议后无法播放该如何解决?

开源EasyDarwin视频监控/安防监控/视频汇聚EasyCVR能在复杂的网络环境中&#xff0c;将分散的各类视频资源进行统一汇聚、整合、集中管理&#xff0c;在视频监控播放上&#xff0c;视频安防监控汇聚平台可支持1、4、9、16个画面窗口播放&#xff0c;可同时播放多路视频流&#…

即时通讯开发中的性能优化技巧

即时通讯开发在如今的数字化社会中扮演着重要角色&#xff0c;然而&#xff0c;随着用户对即时通讯应用的需求不断增长&#xff0c;开发者们面临着使其应用保持高性能和可靠性的挑战。本文将探讨即时通讯开发中关键的性能优化技巧&#xff0c;帮助开发者们提升应用的用户体验和…

基于java Swing 和 mysql实现的飞机订票系统(源码+数据库+ppt+ER图+流程图+架构说明+论文+运行视频指导)

一、项目简介 本项目是一套基于java Swing 和 mysql实现的飞机订票系统&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。 包含&#xff1a;项目源码、项目文档、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过…

使用GoLand进行远程调试

对部署进行配置 在此配置远程服务器地址&#xff0c;映射&#xff0c;是否自动上传(更新)等 选择SFTP类型 选择上传 另外给自动上传选项打钩 此时在本地修改某个文件&#xff0c;远程机器相应目录的文件&#xff0c;也会被同步修改 对远程调试进行配置 远程机器需要安装delve 而…

JavaSE(四)

详细知识点可以点击标题超链接 一、多线程&JUC 并发与并行 多线程的三种实现方式 第一种继承Thread类 第二种实现Runnable接口 第三种实现Callable接口 对比 常用方法 基础 优先级 守护线程 礼让线程 &#xff08;了解&#xff09; 结果尽量均匀 插入线程&#xff08…

智慧水产养殖方案,守护养殖水产品安全!

水产品在人们的饮食文化中占据着举足轻重的地位&#xff0c;更是人们摄入蛋白质的重要来源。因此&#xff0c;保障食品安全&#xff0c;提升养殖水产品的品质至关重要然。而传统的人工观察水产养殖方式较为单一&#xff0c;难以及时发现水质问题和投喂情况&#xff0c;容易导致…

Linux 多线程同步机制(上)

文章目录 前言一、线程同步二、互斥量 mutex三、死锁总结 前言 一、线程同步 在多线程环境下&#xff0c;多个线程可以并发地执行&#xff0c;访问共享资源&#xff08;如内存变量、文件、网络连接 等&#xff09;。 这可能导致 数据不一致性, 死锁, 竞争条件等 问题。 为了解…

RedisDesktopManager(redis客户端,可输入用户名密码)

RedisDesktopManager&#xff08;redis客户端&#xff0c;可输入用户名密码&#xff09; Redis桌面管理器&#xff08;又名RDM&#xff09; - 是一个用于Windows&#xff0c;Linux和MacOS的快速开源Redis数据库管理应用程序。可以使用url连接或账号密码。 redis设置账号密码后…

【Rust日报】2023-08-27 Collie:专为您打造的简约 RSS 阅读器

第一个 Rust 项目&#xff1a;模板引擎 大家好&#xff01; 我是 Rust 新手&#xff0c;决定为我的第一个 Rust 项目编写一个模板引擎。并不是出于需要&#xff0c;因为生态系统已经有一些不错的选择&#xff0c;而是为了乐趣和学习。 这是我第一次尝试这种类型的库&#xff0c…

Python框架【模板继承、继承模板实战、装饰器、蓝图(介绍、单文件、目录结构、模版文件、静态文件 url_for函数子域名实现)】(五)

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱敲代码的小王&#xff0c;CSDN博客博主,Python小白 &#x1f4d5;系列专栏&#xff1a;python入门到实战、Python爬虫开发、Python办公自动化、Python数据分析、Python前后端开发 &#x1f4e7;如果文章知识点有错误…

C语言练习题解析:挑战与突破,开启编程新篇章!(1)

&#x1f493;博客主页&#xff1a;江池俊的博客⏩收录专栏&#xff1a;C语言刷题专栏&#x1f449;专栏推荐&#xff1a;✅C语言初阶之路 ✅C语言进阶之路&#x1f4bb;代码仓库&#xff1a;江池俊的代码仓库&#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐&a…

政府科技项目验收全流程分享

科技验收测试 &#xff08;验收申请→主管部门初审→科技厅审核→组织验收→归档备案→信用管理&#xff09;&#xff1a; &#xff08;一&#xff09;验收申请 项目承担单位通过省科技业务管理系统提交验收申请。 按期完成的项目&#xff0c;项目承担单位应当在项目合同书…

Kotlin的Lambda闭包语法

Lambda 表达式是一种在现代编程语言中常见的特性&#xff0c;它可以用来创建匿名函数或代码块&#xff0c;使得将函数作为参数传递、简化代码以及实现函数式编程范式变得更加便捷。Lambda 表达式在函数式编程语言中得到广泛应用&#xff0c;也在诸如 Java 8 和 Kotlin 等主流编…

设计模式之桥接模式

文章目录 一、介绍二、案例1. 组件抽象化2. 桥梁抽象化 一、介绍 桥接模式&#xff0c;属于结构型设计模式。通过提供抽象与实现之间的桥接结构&#xff0c;把抽象化与实现化解耦&#xff0c;使得二者可以独立变化。 《Head First 设计模式》&#xff1a; 将抽象和实现放在两…

TensorFlow-slim包进行图像数据集分类---具体流程

TensorFlow中slim包的具体用法 1、训练脚本文件&#xff08;该文件包含数据下载打包、模型训练&#xff0c;模型评估流程&#xff09;3、模型训练1、数据集相关模块&#xff1a;2、设置网络模型模块3、数据预处理模块4、定义损失loss5、定义优化器模块 本次使用的TensorFlow版本…

web自动化框架:selenium学习使用操作大全(Python版)

目录 一、浏览器驱动下载二、selenium-python安装&#xff08;打开网站、操作元素&#xff09;三、网页解析&#xff08;HTML、xpath&#xff09;四、selenium基本操作1、元素定位八种方法2、元素动态定位3、iframe切换4、填充表单_填充文本框5、填充表单_单选按钮6、填充表单_…

RT-Thread在STM32硬件I2C的踩坑记录

RT-Thread在STM32硬件I2C的踩坑记录 0.前言一、软硬件I2C区别二、RT Thread中的I2C驱动三、尝试适配硬件I2C四、i2c-bit-ops操作函数替换五、Attention Please!六、总结 参考文章&#xff1a; 1.将硬件I2C巧妙地将“嫁接”到RTT原生的模拟I2C驱动框架 2.基于STM32F4平台的硬件I…

java八股文面试[多线程]——Synchronized的底层实现原理

笔试&#xff1a;画出Synchronized 线程状态流转实现原理图 synchronized关键字解决的是多个线程之间访问资源的同步性&#xff0c;synchronized 翻译为中文的意思是同步&#xff0c;也称之为”同步锁“。 synchronized的作用是保证在同一时刻&#xff0c; 被修饰的代码块或方…

16.CSS菜单悬停特效

效果 源码 <!DOCTYPE html> <html> <head> <title>Creative Menu Item Hover Effects</title> <link rel="stylesheet" type="text/css" href="style.css"> </head> <body><section><…