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文件作 ...
随机推荐
- RMQ 问题 ST 算法(模板)
解决区间查询最大值最小值的问题 用 $O(N * logN)$ 的复杂度预处理 查询的时候只要 $O(1)$ 的时间 这个算法是 real 小清新了 有一个长度为 N 的数组进行 M 次查询 可 ...
- Laravel数据库迁移
Laravel的数据迁移功能很好用,并且可以带来一系列好处.通过几条简单的 artisan 命令,就可以顺利上手,没有复杂的地方 注意:该系列命令对数据库非常危险,请准备一个单独的数据库作为配套练习, ...
- DS博客作业01--日期抽象数据类型设计与实现
1.思维导图及学习体会 1.1第一章绪论知识点思维导图 1.2 学习体会 这次博客园和大作业是我在编程学习中的有意义的进步,第一次尝试使用vs,并且通过同学的一些网站的推荐,和热心同学的帮忙,简单学会 ...
- [LOJ3084][GXOI/GZOI2019]宝牌一大堆——DP
题目链接: [GXOI/GZOI2019]宝牌一大堆 求最大值容易想到$DP$,但如果将$7$种和牌都考虑进来的话,$DP$状态不好设,我们将比较特殊的七小对和国士无双单独求,其他的进行$DP$. 观 ...
- python的排序方式
""" 冒泡排序: 冒泡排序的思想: 每次比较两个相邻的元素, 如果他们的顺序错误就把他们交换位置 比如有五个数: 12, 35, 99, 18, 76, 从大到小排序, ...
- Xilinx FPGA引脚txt文件导入excel中
需求 为了把xilinx FPGA的官方引脚文件txt转成excel文件(实际官网中有对应的csv文件就是excel文件了...) xilinx FPGA引脚地址:https://china.xili ...
- Python 练习——计算1-2+3-4...+99
# 求1-99的所有数的和 count = 1 s = 0 while count < 100: s += count count += 1 print(s) 当都为正数时,即1+2+3+... ...
- windows下提权基础
拿到webshell很多时候代表渗透的开始,下面带来windows提权基础 环境:虚拟机 win7系统 首先:查看权限whoami 我们知道windows的高权限应该是administrator和sy ...
- Python学习day17 迭代器&生成器
迭代器&生成器 1. 迭代器 1.1 迭代器 迭代:迭代是重复反馈过程的活动,其目的通常是为了逼近所需目标或结果.每一次对过程的重复称为一次"迭代" 迭代器:帮助对某种对象 ...
- loj6074 子序列
题目链接 思路 首先考虑暴力\(dp\) 用\(f[i][j]\)表示前\(i\)个字符,以\(j\)这个字符结尾的本质不同的字符串个数. 然后就有如下的转移 \(if(s_i==j)\) \[f_{ ...