采用 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 最全最稳定的方式的更多相关文章

  1. C# 读取Excel日期格式

    读取Excel日期数据,一种方式是在EXCEL中把你的日期列的格式设置一下,设成"文本"型. 如果单元格格式设置为date,则在后台读出的数值是一个数值,如2008-08-08读出 ...

  2. 无法读取Excel中的数据单元格。有数据,但是读出来全是空值

    C#读取Excel,取值为空的解决办法! C#读取Excel遇到无法读取的解决方法是什么呢?这样在C#读取Excel的过程中有很多问题,那么本文就向你介绍如何解决C#读取Excel遇到无法读取的解决方 ...

  3. 使用Aspose.Cells读取Excel

      最新更新请访问: http://denghejun.github.io Aspose.Cells读取Excel非常方便,以下是一个简单的实现读取和导出Excel的操作类: 以下是Aspose.Ce ...

  4. .Net读取Excel文件时丢失数据的问题 (转载)

    相信很多人都试过通过OleDB读取Excel文件,这种方法效率十分高,只是有一点会让人十分头痛,就是当一列中既有混合型数据,又有纯数据时,往往容易丢失数据. 百度过后,改连接字符串 “HDR=YES; ...

  5. OLDB读取excel的数据类型不匹配的解决方案(ZT)

    1 引言  在应用程序的设计中,经常需要读取Excel数据或将Excel数据导入转换到其他数据载体中,例如将Excel数据通过应用程序导入SQL Sever等数据库中以备使用.笔者在开发“汽车产业链A ...

  6. R语言读取excel文件的3种方法

    R读取excel文件中数据的方法: 电脑有一个excel文件,原始的文件路径是:E:\R workshop\mydata\biom excel数据为5乘2阶矩阵,元素为                ...

  7. Java Struts2读取Excel 2003/2007/2010例子

    Java读写Excel的包是Apache POI(项目地址:http://poi.apache.org/),因此需要先获取POI的jar包,本实验使用的是POI 3.9稳定版. Apache POI ...

  8. (转)ASP.NET(C#) 读取EXCEL ——另加解决日期问题

    使用OLEDB可以对excel文件进行读取,我们只要把该excel文件作为数据源即可. 一 在D盘创建excel文件test.xls: 二 将工作表Sheet1的内容读取到DataSet string ...

  9. ASP.NET(C#) 读取EXCEL ——另加解决日期问题

    转载:http://www.cnblogs.com/diony/archive/2011/09/08/2171133.html 使用OLEDB可以对excel文件进行读取,我们只要把该excel文件作 ...

随机推荐

  1. MyCP.java蓝墨云班课

    题目要求: 编写MyCP.java 实现类似Linux下cp XXX1 XXX2的功能,要求MyCP支持两个参数: java MyCP -tx XXX1.txt XXX2.bin 用来把文本文件(内容 ...

  2. Neutron:访问外网

    instance 如何与外部网络通信?   这里的外部网络是指的租户网络以外的网络.  租户网络是由 Neutron 创建和维护的网络. 外部网络不由 Neutron 创建. 如果是私有云,外部网络通 ...

  3. Python类和对象

    目录 类与对象 其他方法 继承 经典类和新式类 派生 组合 接口.归一化设计与抽象类 继承实现的原理 子类中调用父类的方法 指名道姓 super()方法 多态与多态性 封装 单下划线开头 双下划线开头 ...

  4. Graph图总结

    将COMP20003中关于Graph的内容进行总结,内容来自COMP20003,中文术语并不准确,以英文为准. Graph G = {V, E} 顶Vertices V: can contain in ...

  5. pytorch识别CIFAR10:训练ResNet-34(准确率80%)

    版权声明:本文为博主原创文章,欢迎转载,并请注明出处.联系方式:460356155@qq.com CNN的层数越多,能够提取到的特征越丰富,但是简单地增加卷积层数,训练时会导致梯度弥散或梯度爆炸. 何 ...

  6. USB虚拟串口通信

    https://blog.csdn.net/errorhai/article/details/85333914

  7. Sass 笔记

    Sass 笔记 1. 安装,依赖Ruby sass依赖Ruby, 所以Windows要先安装Ruby, Mac自带无需安装 $ gem install sass 2. 两种文件格式 sass scss ...

  8. css的寬高約束

    https://blog.csdn.net/qq_26780317/article/details/80736514

  9. CF 543C Remembering Strings

    https://cn.vjudge.net/problem/CodeForces-543C 题目 You have multiset of n strings of the same length, ...

  10. codeforces960G. Bandit Blues

    题目链接:codeforces960G 来看看三倍经验:hdu4372 luogu4609 某蒟蒻的关于第一类斯特林数的一点理解QAQ:https://www.cnblogs.com/zhou2003 ...