C# 读取 Excel 最全最稳定的方式
采用 NPOI 和 Epplus 方式读取Excel,因为之前测试NPOI的时候发现对于 .xlsx 格式的文件读取不是很友好,所以才结合了两个。
废话少说,直接上代码:
public static class ExcelReader
{
/// <summary>
/// Excel表格列标识
/// </summary>
public enum ExcelColumns
{
Column_1 = ,
Column_2 = ,
Column_3 = ,
Column_4 = ,
Column_5 = ,
Column_6 = ,
Column_7 = ,
Column_8 = ,
Column_9 = ,
Column_10 = ,
Column_11 = ,
Column_12 = ,
Column_13 = ,
Column_14 = ,
Column_15 = ,
Column_16 = ,
Column_17 = ,
Column_18 = ,
Column_19 = ,
Column_20 = ,
Column_21 = ,
Column_22 = ,
Column_23 = ,
Column_24 = ,
Column_25 = ,
Column_26 = ,
Column_27 = ,
Column_28 = ,
Column_29 = ,
Column_30 = ,
Column_31 = ,
Column_32 = ,
Column_33 = ,
Column_34 = ,
Column_35 = ,
Column_36 = ,
Column_37 = ,
Column_38 = ,
Column_39 = ,
Column_40 = ,
Column_41 = ,
Column_42 = ,
Column_43 = ,
Column_44 = ,
Column_45 = ,
Column_46 = ,
Column_47 = ,
Column_48 = ,
Column_49 = ,
Column_50 = ,
Column_51 = ,
Column_52 = ,
Column_53 = ,
Column_54 = ,
Column_55 = ,
Column_56 = ,
Column_57 = ,
Column_58 = ,
Column_59 = ,
Column_60 = ,
Column_61 = ,
Column_62 = ,
Column_63 = ,
Column_64 = ,
Column_65 = ,
Column_66 = ,
Column_67 = ,
Column_68 = ,
Column_69 = ,
Column_70 = ,
Column_71 = ,
Column_72 = ,
Column_73 = ,
Column_74 = ,
Column_75 = ,
Column_76 = ,
Column_77 = ,
Column_78 = ,
Column_79 = ,
Column_80 = ,
Column_81 = ,
Column_82 = ,
Column_83 = ,
Column_84 = ,
Column_85 = ,
Column_86 = ,
Column_87 = ,
Column_88 = ,
Column_89 = ,
Column_90 = ,
Column_91 = ,
Column_92 = ,
Column_93 = ,
Column_94 = ,
Column_95 = ,
Column_96 = ,
Column_97 = ,
Column_98 = ,
Column_99 = ,
Column_100 = ,
Sys_NewGuid,
Sys_DateTime,
Sys_Empty
}
Excel表格列标识
/// <summary>
/// 表格列数据类型
/// </summary>
public enum DataTableColumnType
{
//Sys_String = "System.String";
//Sys_Int32 = "System.Int32";
//Sys_Decimal = "System.Decimal";
//Sys_DateTime = "System.DateTime";
//Sys_Long = "System.Int64";
//Sys_Bool = "System.Boolean"; Sys_String,
Sys_Int32,
Sys_Decimal,
Sys_DateTime,
Sys_Long,
Sys_Bool
} /// <summary>
/// 获取表格列数据类型
/// </summary>
/// <param name="dataTableColumnType"></param>
/// <returns></returns>
private static string GetDataTableColumnType(DataTableColumnType dataTableColumnType)
{
string columnType = string.Empty;
switch (dataTableColumnType)
{
case DataTableColumnType.Sys_String:
columnType = "System.String";
break;
case DataTableColumnType.Sys_Int32:
columnType = "System.Int32";
break;
case DataTableColumnType.Sys_Decimal:
columnType = "System.Decimal";
break;
case DataTableColumnType.Sys_DateTime:
columnType = "System.DateTime";
break;
case DataTableColumnType.Sys_Long:
columnType = "System.Int64";
break;
case DataTableColumnType.Sys_Bool:
columnType = "System.Boolean";
break;
default:
break;
}
return columnType;
}
表格列数据类型
/// <summary>
/// 读取Excel文件,返回DataTable
/// </summary>
/// <param name="filePath">文件路径</param>
/// <param name="sheetIndex">sheet页下标,从1开始</param>
/// <param name="startRow">开始行</param>
/// <param name="tableName">对应数据库的表名</param>
/// <param name="dtColumns">DataTable列定义</param>
/// <param name="dtExcelMap">DataTable和Excel的映射关系</param>
/// <returns></returns>
public static DataTable GetExcelContent(string filePath, int sheetIndex, int startRow, string tableName,
Dictionary<string, DataTableColumnType> dtColumns, Dictionary<string, ExcelColumns> dtExcelMap)
{
//声明表格控件,初始化表格列
DataTable tblDatas = new DataTable(tableName);
foreach (var item in dtColumns)
tblDatas.Columns.Add(item.Key, Type.GetType(GetDataTableColumnType(item.Value))); FileStream fs = null;
ExcelPackage package = null;
try
{
// 2007版本 epplus 读取
if (filePath.IndexOf(".xlsx") > )
{
#region 2007
fs = new FileStream(filePath, FileMode.Open);
using (package = new ExcelPackage(fs))
{
ExcelWorksheet sheet = package.Workbook.Worksheets[]; for (int i = startRow; i <= sheet.Dimension.End.Row; i++)
{
//定义获取列值的委托
Func<ExcelColumns, object> func = delegate (ExcelColumns excelColumns)
{
return sheet.GetValue(i, (int)excelColumns);//读取第i行第excelColumns列数据
};
//获取与表格列对应的 行值 集合
object[] arrValue = GetDataTableRow(tblDatas, dtExcelMap, func);
//添加到表格中
tblDatas.Rows.Add(arrValue);
}
} #endregion
}
// 2003版本
else if (filePath.IndexOf(".xls") > )
{
#region 2003 using (fs = File.OpenRead(filePath))
{
IWorkbook workbook = new HSSFWorkbook(fs); if (workbook != null)
{
//读取第一个sheet,当然也可以循环读取每个sheet
ISheet sheet = workbook.GetSheetAt(sheetIndex - );
if (sheet != null)
{
int rowCount = sheet.LastRowNum;//总行数
for (int i = startRow - ; rowCount > && i <= rowCount; ++i)
{
//定义获取列值的委托
Func<ExcelColumns, object> func = delegate (ExcelColumns excelColumns)
{
IRow row = sheet.GetRow(i);
return row.GetCell((int)excelColumns - );//读取第i行第excelColumns列数据
};
//获取与表格列对应的 行值 集合
object[] arrValue = GetDataTableRow(tblDatas, dtExcelMap, func);
//添加到表格中
tblDatas.Rows.Add(arrValue);
}
}
}
} #endregion
} return tblDatas;
}
catch (Exception ex)
{
return null;
}
finally
{
if (package != null)
{
package.Dispose();
}
if (fs != null)
{
fs.Close();
}
}
}
读取Excel文件,返回DataTable
/// <summary>
/// 获取表格行数据
/// </summary>
/// <param name="tblDatas"></param>
/// <param name="dtExcelMap"></param>
/// <param name="getExcelCellValue"></param>
/// <returns></returns>
private static object[] GetDataTableRow(DataTable tblDatas, Dictionary<string, ExcelColumns> dtExcelMap,
Func<ExcelColumns, object> getExcelCellValue)
{
int arrIndex = ;
object[] arrValue = new object[tblDatas.Columns.Count];
//循环表格所有列
foreach (DataColumn item in tblDatas.Columns)
{
//根据表格列和值枚举映射关系,由列得到值枚举
ExcelColumns excelColumns = dtExcelMap[item.ColumnName];
//判断值枚举是否为Guid
if (excelColumns == ExcelColumns.Sys_NewGuid)
arrValue[arrIndex] = Guid.NewGuid();
//判断值枚举是否为DateTime
else if (excelColumns == ExcelColumns.Sys_DateTime)
arrValue[arrIndex] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
//根据值枚举下标,获取对应列的值
else
arrValue[arrIndex] = getExcelCellValue(excelColumns); arrIndex++;
} return arrValue;
}
获取表格行数据
}
代码总体上没有达到完全体,还有非常多的优化空间,先Mark一下,赶下项目进度,后期进行优化了再更新。
具体使用方式如下:
string filePath = "文件完整的路径";
int sheetIndex = ;//将要读取的Sheet页,从1开始
int startRow = ;//开始读取的数据行,不包含表头,从1开始
string tableName = "对应数据库的名称,方便后续插入到数据库中";
//表格的列定义,想要输出多少列,就定义多少列
Dictionary<string, ExcelReader.DataTableColumnType> dtCols = new Dictionary<string, ExcelReader.DataTableColumnType>();
dtCols.Add("列名", ExcelReader.DataTableColumnType.Sys_DateTime);
//表格列 和 Excel表格列 的对应关系,必须和“表格的列定义”数量一致,且列名相同
//表格列 可以对应非 Excel表格列 的内容,目前仅支持 Guid 和 DataTime
Dictionary<string, ExcelReader.ExcelColumns> colsMap = new Dictionary<string, ExcelReader.ExcelColumns>();
colsMap.Add("列名", ExcelReader.ExcelColumns.Column_1); //开始调用,获取表格
DataTable data = ExcelReader.GetExcelContent(filePath, sheetIndex, startRow, tableName, dtCols, colsMap);
以上。
C# 读取 Excel 最全最稳定的方式的更多相关文章
- C# 读取Excel日期格式
读取Excel日期数据,一种方式是在EXCEL中把你的日期列的格式设置一下,设成"文本"型. 如果单元格格式设置为date,则在后台读出的数值是一个数值,如2008-08-08读出 ...
- 无法读取Excel中的数据单元格。有数据,但是读出来全是空值
C#读取Excel,取值为空的解决办法! C#读取Excel遇到无法读取的解决方法是什么呢?这样在C#读取Excel的过程中有很多问题,那么本文就向你介绍如何解决C#读取Excel遇到无法读取的解决方 ...
- 使用Aspose.Cells读取Excel
最新更新请访问: http://denghejun.github.io Aspose.Cells读取Excel非常方便,以下是一个简单的实现读取和导出Excel的操作类: 以下是Aspose.Ce ...
- .Net读取Excel文件时丢失数据的问题 (转载)
相信很多人都试过通过OleDB读取Excel文件,这种方法效率十分高,只是有一点会让人十分头痛,就是当一列中既有混合型数据,又有纯数据时,往往容易丢失数据. 百度过后,改连接字符串 “HDR=YES; ...
- OLDB读取excel的数据类型不匹配的解决方案(ZT)
1 引言 在应用程序的设计中,经常需要读取Excel数据或将Excel数据导入转换到其他数据载体中,例如将Excel数据通过应用程序导入SQL Sever等数据库中以备使用.笔者在开发“汽车产业链A ...
- R语言读取excel文件的3种方法
R读取excel文件中数据的方法: 电脑有一个excel文件,原始的文件路径是:E:\R workshop\mydata\biom excel数据为5乘2阶矩阵,元素为 ...
- Java Struts2读取Excel 2003/2007/2010例子
Java读写Excel的包是Apache POI(项目地址:http://poi.apache.org/),因此需要先获取POI的jar包,本实验使用的是POI 3.9稳定版. Apache POI ...
- (转)ASP.NET(C#) 读取EXCEL ——另加解决日期问题
使用OLEDB可以对excel文件进行读取,我们只要把该excel文件作为数据源即可. 一 在D盘创建excel文件test.xls: 二 将工作表Sheet1的内容读取到DataSet string ...
- ASP.NET(C#) 读取EXCEL ——另加解决日期问题
转载:http://www.cnblogs.com/diony/archive/2011/09/08/2171133.html 使用OLEDB可以对excel文件进行读取,我们只要把该excel文件作 ...
随机推荐
- linux下安装多个Tomcat
编辑环境变量:vi /etc/profile 加入以下代码 ##########first tomcat########### CATALINA_BASE=/usr/local/src/tomcat ...
- 禁止Cnario Player启动后自动开始播放
Cnario Player安装激活后, 默认开机后自动启动, 启动加载内容完成后进入10秒倒计时, 10秒后即开始播放关机前播放的内容. 如果不想让其自动开始播放, 可按照如下办法设置其不自动播放. ...
- Charles抓包工具使用
Charles抓包工具使用和进行接口数据模拟 打开软件,选择Tools >> Map Local >> 勾选enable >> add >> ...
- 失去焦点布局在ios12-微信6.7.0版本以上不回滚的解决方案
微信页面input获取焦点,布局上移,失去焦点布局在ios12-微信6.7.0版本以上不回滚的解决方案: setTimeout(function(){ let scrollHeight = docum ...
- 认识 CXF(WebService框架)
Apache CXF = Celtix + Xfire 支持多种协议: 1)SOAP1.1,1.2 2)HTTP 3)CORBA(Common Object Request Broker Archit ...
- Struts2+Spring+Hibernate3整合
这几天正在复习三大框架的知识,特意把写出来,如有错误,希望大家多指教! 代码地址:https://git.coding.net/puchenglin/SSHDemo.git 1. 引入jar包 Str ...
- 使用cURL尝试ElasticSearch
测试环境:debian 9官网提供了 deb,rpm,源码下载 官方下载地址:https://www.elastic.co/downloads/elasticsearch 通过源码安装会遇到一些小问题 ...
- JavaScript与C# Windows应用程序交互方法
一.建立网页 <html> <head> <meta http-equiv="Content-Language" content=&quo ...
- 【CSA49F】【XSY3317】card 博弈论 DP
题目大意 不会博弈论的 yww 在和博弈论大师 yxq 玩一个游戏. 有 \(n\) 种卡牌,第 \(i\) 种卡牌有 \(b_i\) 张. yww 会先把所有 \(B=\sum_{i=1}^nb_i ...
- 夜神模拟器调试web APP
前言:之前工作之余的时间自己做了一个web APP,但是都是在浏览器上调试的,这次想看看在手机上啥效果,所以下载了一个夜神模拟器 一.下载夜神模拟器 https://www.yeshen.com/ 二 ...