C#NPOI操作Excel,实现Excel数据导入导出(支持多个sheet)
首先在项目中引用NPOI,通过管理NuGet程序包,搜索NPOI,选择版本2.3.0(支持.NET Framework 4.0)根据自己项目选择适当版本。
1.NpoiExcelHelper.cs Npoi操作Excel类

using System.Data;
using System.IO;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using NPOI.HSSF.UserModel; /// <summary>
/// Npoi操作Excel类
/// </summary>
public static class NpoiExcelHelper
{
/// <summary>
/// 根据Excel文件类型返回IWorkbook
/// </summary>
/// <param name="fileName">文件路径/文件名称(含后缀名)</param>
/// <param name="rowNum">Excel行数</param>
/// <param name="colNum">Excel列数</param>
/// <param name="isFirstRowColumn">第一行是否是标题</param>
/// <returns></returns>
public static IWorkbook GetWorkbook(string fileName, out int rowNum, out int colNum, bool isFirstRowColumn = true)
{
bool isXlsx = Path.GetExtension(fileName).Equals(".xlsx");
if (isXlsx)
{
if (isFirstRowColumn)
{
rowNum = 1048575;
}
else
{
rowNum = 1048576;
}
colNum = 16384;
}
else
{
if (isFirstRowColumn)
{
rowNum = 65535;
}
else
{
rowNum = 65536;
}
colNum = 256;
} if (File.Exists(fileName))
{ using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
if (isXlsx)
{
return new XSSFWorkbook(fs);
}
else
{
return new HSSFWorkbook(fs);
}
}
}
else
{
if (isXlsx)
{
return new XSSFWorkbook();
}
else
{
return new HSSFWorkbook();
}
}
} /// <summary>
/// 将DataTable中的数据导入到excel中(第一行是标题)
/// 支持根据Excel数据自动分页(多个Sheet)
/// </summary>
/// <param name="dt">DataTable</param>
/// <param name="fileName">文件路径/文件名称(含后缀名)</param>
/// <param name="columnFieldText">字段对应中文 顺序需要跟Excel中数据顺序一致</param>
/// <param name="sheetName">Excel中Sheet名称(多个sheet时 名字后面自动加上数字序号)</param>
/// <returns></returns>
public static byte[] DataTableToExcel(DataTable dt, string fileName, string[,] columnFieldText = null, string sheetName = null)
{
int rowNum = 0;
int colNum = 0;
IWorkbook workbook = GetWorkbook(fileName, out rowNum, out colNum); var recordNum = dt.Rows.Count;
int totalPage = recordNum % rowNum == 0 ? recordNum / rowNum : recordNum / rowNum + 1; for (var p = 0; p < totalPage; p++)
{
if (string.IsNullOrEmpty(sheetName))
{
sheetName = dt.TableName;
} if (totalPage > 1)
{
if (string.IsNullOrEmpty(sheetName))
{
sheetName = "Sheet";
} sheetName = sheetName + (p + 1).ToString();
}
else
{
if (string.IsNullOrEmpty(sheetName))
{
sheetName = "Sheet1";
}
} ISheet sheet = workbook.CreateSheet(sheetName);//创建工作表 #region 标题
IRow row = sheet.CreateRow(0);//在工作表中添加一行
if (columnFieldText != null)
{
var dataColumn = columnFieldText.GetLength(0);
if (dataColumn <= colNum)
{
for (int m = 0; m < dataColumn; m++)
{
ICell cell = row.CreateCell(m);//在行中添加一列
cell.SetCellValue(columnFieldText[m, 1]);//设置列的内容
}
}
else
{
//数据列数超过了Excel的列数
}
}
else
{
var dataColumn = dt.Columns.Count;
if (dataColumn <= colNum)
{
for (int i = 0; i < dataColumn; i++)
{
ICell cell = row.CreateCell(i);//在行中添加一列
cell.SetCellValue(dt.Columns[i].ColumnName);//设置列的内容
}
}
else
{
//数据列数超过了Excel的列数
}
}
#endregion
#region 填充数据 int startIndex = p * rowNum;
int endindex = (p + 1) * rowNum - 1;
if (endindex >= recordNum)
{
endindex = recordNum - 1;
} for (int i = startIndex; i <= endindex; i++)//遍历DataTable行
{
DataRow dataRow = dt.Rows[i]; row = sheet.CreateRow(i - startIndex + 1);//在工作表中添加一行 if (columnFieldText != null)
{
var dataColumn = columnFieldText.GetLength(0);
if (dataColumn <= colNum)
{
for (int m = 0; m < dataColumn; m++)
{
ICell cell = row.CreateCell(m);//在行中添加一列
cell.SetCellValue(dataRow[columnFieldText[m, 0]].ToString());//设置列的内容
}
}
else
{
//数据列数超过了Excel的列数
}
}
else
{
var dataColumn = dt.Columns.Count;
if (dataColumn <= colNum)
{
for (int j = 0; j < dt.Columns.Count; j++)//遍历DataTable列
{
ICell cell = row.CreateCell(j);//在行中添加一列
cell.SetCellValue(dataRow[j].ToString());//设置列的内容
}
}
else
{
//数据列数超过了Excel的列数
}
}
}
#endregion
}
#region 输出Excel
using (MemoryStream stream = new MemoryStream())
{
workbook.Write(stream);
return stream.ToArray();
}
#endregion
} /// <summary>
/// 将excel中的数据导入到DataTable中(第一行是标题)
/// 支持多个sheet数据导入(建议多个sheet的数据格式保持一致,将没有数据的sheet删除)
/// </summary>
/// <param name="fileName">文件路径(含文件名称后缀名)</param>
/// <param name="columnFieldText">字段对应中文 顺序需要跟Excel中数据顺序一致</param>
/// <param name="sheetName">指定Excel中Sheet名称 如果为null时,读取所有sheet中的数据</param>
/// <returns>返回的DataTable</returns>
public static DataTable ExcelToDataTable(string fileName, string[,] columnFieldText = null, string sheetName = null)
{
DataTable data = new DataTable();
int rowNum = 0;
int colNum = 0;
IWorkbook workbook = GetWorkbook(fileName, out rowNum, out colNum); for (int e = 0; e < workbook.NumberOfSheets; e++)
{
ISheet sheet = workbook.GetSheetAt(e);
if (sheet != null)
{
var currentSheetIndex = 0;
if (!string.IsNullOrEmpty(sheetName))
{
if (sheet.SheetName == sheetName)
{
currentSheetIndex = e;
}
} IRow firstRow = sheet.GetRow(0);
if (firstRow != null)
{
int cellCount = firstRow.LastCellNum; //一行最后一个cell的编号 即总的列数 var dataColumn = columnFieldText != null ? columnFieldText.GetLength(0) : cellCount;
int startRow = sheet.FirstRowNum;
if (dataColumn <= colNum)
{
if (e == currentSheetIndex)
{
for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
{
ICell cell = firstRow.GetCell(i);
if (cell != null)
{
string cellValue = cell.StringCellValue;
if (cellValue != null)
{
DataColumn column = new DataColumn((columnFieldText != null ? columnFieldText[i, 0] : cellValue));
data.Columns.Add(column);
}
}
}
} startRow = sheet.FirstRowNum + 1; //最后一列的标号
int rowCount = sheet.LastRowNum;
for (int i = startRow; i <= rowCount; ++i)
{
IRow row = sheet.GetRow(i);
if (row == null) continue; //没有数据的行默认是null DataRow dataRow = data.NewRow();
for (int j = row.FirstCellNum; j < cellCount; ++j)
{
if (row.GetCell(j) != null) //同理,没有数据的单元格都默认是null
dataRow[j] = row.GetCell(j).ToString();
}
data.Rows.Add(dataRow);
}
}
else
{
//数据列数超过了Excel的列数
}
} if (!string.IsNullOrEmpty(sheetName))
{
if (sheet.SheetName == sheetName)
{
break;
}
}
}
}
return data;
}
}
2.WEB项目的调用方法:
(1)数据导出到Excel中(支持根据DataTable数据及Excel自动分成多个Sheet)
调用方法:
int record = 500;
DataTable data = CreateDataTable(record); string fileName = "客户明细_" + DateTime.Now.ToString("MMddhhmmss") + ".xls";
string sheetName = "客户明细"; string[,] columnFieldText = new[,]{
{ "ID", "编号" },
{ "Name", "姓名" },
{ "CreateTime", "创建时间" }
}; //string[,] columnFieldText = null; var buf = NpoiExcelHelper.DataTableToExcel(data, fileName, columnFieldText, sheetName); Response.Buffer = true;
Response.Clear();
Response.ClearHeaders();
Response.ClearContent();
Response.Charset = "UTF8";
Response.ContentEncoding = Encoding.UTF8;
Response.ContentType = "application/vnd.ms-excel";
string browser = Request.Browser.Browser;
if (browser.Contains("InternetExplorer"))
Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(fileName, Encoding.UTF8));
else
Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName); Response.AddHeader("Content-Length", buf.Length.ToString()); Response.Flush();
Response.BinaryWrite(buf);
/// <summary>
/// 创建DataTable对象
/// </summary>
public DataTable CreateDataTable(int record)
{
//创建DataTable
DataTable dt = new DataTable("NewDt"); //创建自增长的ID列
DataColumn dc = dt.Columns.Add("ID", Type.GetType("System.Int32"));
dc.AutoIncrement = true; //自动增加
dc.AutoIncrementSeed = 1; //起始为1
dc.AutoIncrementStep = 1; //步长为1
dc.AllowDBNull = false; //非空 //创建其它列表
dt.Columns.Add(new DataColumn("Name", Type.GetType("System.String")));
dt.Columns.Add(new DataColumn("CreateTime", Type.GetType("System.DateTime"))); DataRow dr;
for (int i = 0; i < record; i++)
{
dr = dt.NewRow();
dr["Name"] = "名字" + i.ToString();
dr["CreateTime"] = DateTime.Now;
dt.Rows.Add(dr);
}
return dt;
}
(2)Excel中数据导入DataTable中(支持指定Sheet名称 / 多个数据格式一致的Shee)
string fileName = "客户明细_0213023109.xls";
string sheetName = "客户明细1"; string[,] columnFieldText = new[,]{
{ "ID", "编号" },
{ "Name", "姓名" },
{ "CreateTime", "创建时间" }
}; //string[,] columnFieldText = null; var dt = NpoiExcelHelper.ExcelToDataTable(Server.MapPath(fileName), columnFieldText, sheetName);
以上基本实现WEB通过NPOI操作Excel数据导入导出的功能。其他可自行研究。
C#NPOI操作Excel,实现Excel数据导入导出(支持多个sheet)的更多相关文章
- 1、数据库与excel表格的数据导入导出
1.居民用户界面中,excel数据导入导出: 2.其他5张表数据显示到本角色主页的container容器中.
- java中 Excel表实现数据导入导出
需要引入依赖: <!-- https://mvnrepository.com/artifact/org.apache.poi/poi --> <dependency> < ...
- SQL SERVER 与ACCESS、EXCEL的数据导入导出转换
* 说明:复制表(只复制结构,源表名:a 新表名:b) select * into b from a where 1<>1 * 说明:拷贝表(拷贝数据,源表名:a 目标表名:b) ...
- 使用openpyxl模块将Excel中的数据导入数据库
这里将不介绍openpyxl模块的详细操作. 主要就是记录一个使用openpyxl模块将Excel表格的数据导入数据库中的实例. from openpyxl import load_workbook ...
- SQL SERVER 和ACCESS、EXCEL的数据导入导出
SQL SERVER 与ACCESS.EXCEL之间的数据转换SQL SERVER 和ACCESS的数据导入导出[日期:2007-05-06] 来源:Linux公社 作者:Linux 熟 悉 ...
- ThinkPHP使用PHPExcel实现Excel数据导入导出完整实例
这篇文章主要介绍了ThinkPHP使用PHPExcel实现Excel数据导入导出,非常实用的功能,需要的朋友可以参考下 本文所述实例是使用在Thinkphp的开发框架上,要是使用在其他框架也是同样的方 ...
- jsp+servlet上传excel并将数据导入到数据库表的实现方法
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...
- 使用Python将Excel中的数据导入到MySQL
使用Python将Excel中的数据导入到MySQL 工具 Python 2.7 xlrd MySQLdb 安装 Python 对于不同的系统安装方式不同,Windows平台有exe安装包,Ubunt ...
- 图解如何 将Excel里的数据导入到sql server数据库中
项目中,经常会碰到如何将Excel里的数据导入到sql server中的问题. 下面,图解如何实现导入Excel中的数据到sql server 2008 R2: Excel截图如下: 查询pub数据库 ...
- ssm框架之将数据库的数据导入导出为excel文件
在这里首先我要将自己遇到的各种问题,以及需求记录下来,做一个备忘,便于以后查看: 需求:主要实现两个功能,将oracle数据库里的数据导出为excel,同时需要将excel表格的数据导入到数据库 环境 ...
随机推荐
- 图文详解在VMware Workstation 16 PRO虚拟机上安装Ubuntu 22.04.5 linux系统
一.下载Ubuntu linux系统镜像 机构 下载地址 官网地址 https://cn.ubuntu.com/download 南京大学 https://mirrors.nju.edu.cn/ubu ...
- [排序算法] 2路插入排序 (C++)
前言 本文章是建立在 插入排序 的基础上写的,如果还有不懂 插入排序 的童鞋先停下脚步,可以先看看这里~ 直接/折半插入排序 2路插入排序解释 在 插入排序 中,当待插入元素需要插入的位置位于当前有序 ...
- [最短路径问题]Dijkstra算法(含还原具体路径)
前言 在本篇文章中,我将介绍 Dijkstra 算法解决 单源最短路径问题 ,同时还包含了具体路径的还原.以下是我自己的全部学习过程与思考,参考书籍为 <数据结构>(C++语言版) 邓俊辉 ...
- 关于sublime-build的配置详解
前言 sublime-build 可以做很多自定义的构建命令,然后用其执行代码,十分方便! 开始 这里我就简单的用python 的配置来详细说明各个配置项目的作用 { "shell_cmd& ...
- MIT6.828 Lab 1: C, Assembly, Tools, and Bootstrapping
前置准备 实现机器为VMWare的虚拟机,操作系统为 Debian-11(无桌面版本),内核版本为 5.10.0,指令集为 AMD64(i7 9700K),编译器为 GCC-10 QEMU 虚拟化支持 ...
- springcloudgateway学习
API网关 大型项目开发过程中,往往都是由各个不同的微服务组成的,服务可能分布在不同地区不同机房,那用户如何知道访问某服务的时候该服务的实际地址呢,这时候就需要API网关了 API 网关就像服务的门面 ...
- 【实战】Hadoop安装01-伪分布式-Pseudo
Hadoop安装-伪分布式-Pseudo 〇.所需资料 一.前置环境安装 1.包含内容 (1)安装 虚拟机安装.系统安装 (2)配置 ip.host.主机名配置 关闭防火墙及selinux SSH免密 ...
- Spring Boot回顾
一.概述 1.Spring的优缺点 优点 无需开发ELB,通过IOC和AOP,就可以使用POJO(简单的Java对象)实现ELB的功能 缺点: 依赖管理导入Maven耗时耗力 注解繁琐 2.Sprin ...
- Go 每日一库之 go-carbon,优雅的golang日期时间处理库
Carbon 是一个轻量级.语义化.对开发者友好的 golang 时间处理库,支持链式调用. Carbon 已被 awesome-go 收录, 如果您觉得不错,请给个 star 吧. github.c ...
- 新项目决定用 JDK 17了
大家好,我是风筝,公众号「古时的风筝」,专注于 Java技术 及周边生态. 文章会收录在 JavaNewBee 中,更有 Java 后端知识图谱,从小白到大牛要走的路都在里面. 最近在调研 JDK 1 ...