• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C#教程 > C#读取Excel的三种方式以及比较分析

C#读取Excel的三种方式以及比较分析

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了c站,c语言,欲情 c max,奔驰c200,85度c等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

(1)OleDB方式

优点:将Excel直接当做数据源处理,通过SQL直接读取内容,读取速度较快。

缺点:读取数据方式不够灵活,无法直接读取某一个单元格,只有将整个Sheet页读取出来后(结果为Datatable)再在Datatable中根据行列数来获取指定的值。

当Excel数据量很大时。会非常占用内存,当内存不够时会抛出内存溢出的异常。

读取代码如下:

 public DataTable GetExcelTableByOleDB(string strExcelPath, string tableName)
 {
   try
   {
     DataTable dtExcel = new DataTable();
     //数据表
     DataSet ds = new DataSet();
     //获取文件扩展名
     string strExtension = System.IO.Path.GetExtension(strExcelPath);
     string strFileName = System.IO.Path.GetFileName(strExcelPath);
     //Excel的连接
     OleDbConnection objConn = null;
     switch (strExtension)
     {
       case ".xls":
         objConn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + strExcelPath + ";" + "Extended Properties=\"Excel 8.0;HDR=NO;IMEX=1;\"");
         break;
       case ".xlsx":
         objConn = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + strExcelPath + ";" + "Extended Properties=\"Excel 12.0;HDR=NO;IMEX=1;\"");
         break;
       default:
         objConn = null;
         break;
     }
     if (objConn == null)
     {
       return null;
     }
     objConn.Open();
     //获取Excel中所有Sheet表的信息
     //System.Data.DataTable schemaTable = objConn.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, null);
     //获取Excel的第一个Sheet表名
     //string tableName = schemaTable.Rows[0][2].ToString().Trim();
     string strSql = "select * from [" + tableName + "]";
     //获取Excel指定Sheet表中的信息
     OleDbCommand objCmd = new OleDbCommand(strSql, objConn);
     OleDbDataAdapter myData = new OleDbDataAdapter(strSql, objConn);
     myData.Fill(ds, tableName);//填充数据
     objConn.Close();
     //dtExcel即为excel文件中指定表中存储的信息
     dtExcel = ds.Tables[tableName];
     return dtExcel;
   }
   catch
   {
     return null;
   }
 }
</div>

下面说明一下连接字符串

HDR=Yes,这代表第一行是标题,不做为数据使用(但是我在实际使用中,如果第一行存在复杂数值,那么读取得到的Datatable列标题会自动设置为F1、F2等方式命名,与实际应用不符,所以当时是通过HDR=No方式将所有内容读取到Datatable中,然后手动将第一行设置成标题的);IMEX ( IMport EXport mode )设置
IMEX 有三种模式:
0 is Export mode
1 is Import mode
2 is Linked mode (full update capabilities)
我这里特别要说明的就是 IMEX 参数了,因为不同的模式代表著不同的读写行为:
当 IMEX=0 时为“汇出模式”,这个模式开启的 Excel 档案只能用来做“写入”用途。
当 IMEX=1 时为“汇入模式”,这个模式开启的 Excel 档案只能用来做“读取”用途。
当 IMEX=2 时为“链接模式”,这个模式开启的 Excel 档案可同时支援“读取”与“写入”用途。

---------------------------------

另外,读取Excel2007版本的文件时,版本应该从8.0改为12.0,同时驱动不能再用Jet,而应该用ACE。负责会造成“找不到可安装的 ISAM”的错误。

---------------------------------

在网上还发现采用这种方式存在取出的Sheet表的个数多于实际Excel表中的Sheet表个数的情况,其原因有二:

1. 取出的名称中,包括了XL命名管理器中的名称(参见XL2007的公式--命名管理器, 快捷键Crtl+F3);

2. 取出的名称中,包括了FilterDatabase后缀的, 这是XL用来记录Filter范围的。

对于第一点比较简单, 删除已有命名管理器中的内容即可;第二点处理起来比较麻烦, Filter删除后这些名称依然保留着,简单的做法是新增Sheet然后将原Sheet Copy进去。但实际情况并不能为每个Excel做以上检查。下面给出了过滤的方案。(此问题我们有验证过,大家自己验证一下吧)

 //objConn为读取Excel的链接,下面通过过滤来获取有效的Sheet页名称集合
  System.Data.DataTable schemaTable = objConn.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, null);
  List<string> lstSheetNames = new List<string>();
  for (int i = 0; i < schemaTable.Rows.Count; i++)
  {
    string strSheetName = (string)dtSheetName.Rows[i]["TABLE_NAME"];
    if (strSheetName.Contains("$") && !strSheetName.Replace("'", "").EndsWith("$"))
    {
      //过滤无效SheetName完毕....
      continue;
    }
    if (lstSheetNames != null && !lstSheetNames.Contains(strSheetName))
      lstSheetNames.Add(strSheetName);
  }
</div>

因为读取出来无效SheetName一般情况最后一个字符都不会是$。如果SheetName有一些特殊符号,读取出来的SheetName会自动加上单引号。比如在Excel中将SheetName编辑成MySheet(1),此时读取出来的SheetName就为:'MySheet(1)$',所以判断最后一个字符是不是$之前最好过滤一下单引号。

---------------------------------

(2)Com组件的方式(通过添加 Microsoft.Office.Interop.Excel引用实现)

优点:能够非常灵活的读取Excel中的数据,用户可以灵活的调用各种函数进行处理。

缺点:基于单元格的处理,读取速度较慢,对于数据量较大的文件最好不要使用此种方式读取。

需要添加相应的DLL引用,必须存在此引用才可使用,如果是Web站点部署在IIS上时,还需要服务器机子已安装了Excel,有时候还需要为配置IIS权限。

读取代码如下:

 private Stopwatch wath = new Stopwatch();
 /// <summary>
 /// 使用COM读取Excel
 /// </summary>
 /// <param name="excelFilePath">路径</param>
 /// <returns>DataTabel</returns>
 public System.Data.DataTable GetExcelData(string excelFilePath)
 {
   Excel.Application app = new Excel.Application();
   Excel.Sheets sheets;
   Excel.Workbook workbook = null;
   object oMissiong = System.Reflection.Missing.Value;
   System.Data.DataTable dt = new System.Data.DataTable();
   wath.Start();
   try
   {
     if (app == null)
     {
       return null;
     }
     workbook = app.Workbooks.Open(excelFilePath, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, 
       oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong);
     //将数据读入到DataTable中——Start  
     sheets = workbook.Worksheets;
     Excel.Worksheet worksheet = (Excel.Worksheet)sheets.get_Item(1);//读取第一张表
     if (worksheet == null)
       return null;
     string cellContent;
     int iRowCount = worksheet.UsedRange.Rows.Count;
     int iColCount = worksheet.UsedRange.Columns.Count;
     Excel.Range range;
     //负责列头Start
     DataColumn dc;
     int ColumnID = 1;
     range = (Excel.Range)worksheet.Cells[1, 1];
     while (range.Text.ToString().Trim() != "")
     {
       dc = new DataColumn();
       dc.DataType = System.Type.GetType("System.String");
       dc.ColumnName = range.Text.ToString().Trim();
       dt.Columns.Add(dc);
 
       range = (Excel.Range)worksheet.Cells[1, ++ColumnID];
     }
     //End
     for (int iRow = 2; iRow <= iRowCount; iRow++)
     {
       DataRow dr = dt.NewRow();
       for (int iCol = 1; iCol <= iColCount; iCol++)
       {
         range = (Excel.Range)worksheet.Cells[iRow, iCol];
         cellContent = (range.Value2 == null) ? "" : range.Text.ToString();
           dr[iCol - 1] = cellContent;
       }
       dt.Rows.Add(dr);
     }
     wath.Stop();
     TimeSpan ts = wath.Elapsed;
     //将数据读入到DataTable中——End
     return dt;
   }
   catch
   {
     return null;
   }
   finally
   {
     workbook.Close(false, oMissiong, oMissiong);
     System.Runtime.InteropServices.Marshal.ReleaseComObject(workbook);
     workbook = null;
     app.Workbooks.Close();
     app.Quit();
     System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
     app = null;
     GC.Collect();
     GC.WaitForPendingFinalizers();
   }
 }
 /// <summary>
 /// 使用COM,多线程读取Excel(1 主线程、4 副线程)
 /// </summary>
 /// <param name="excelFilePath">



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • C# 检索不区分大小写并高亮显示实例详解
  • C#实现Base64处理的加密解密,编码解码示例
  • C# SqlHelper应用开发学习
  • C#多线程经典示例(吃苹果)
  • C#使用Windows Service的简单教程(创建、安装、卸载、调试)
  • C# 6.0 的知识梳理
  • C#向PPT文档插入图片以及导出图片的实例
  • C#使用Jquery zTree实现树状结构显示 异步数据加载
  • C#清理非托管对象实例分析
  • C#双缓冲技术实例详解

相关文章

  • 2017-05-28C# 利用ICSharpCode.SharpZipLib实现在线压缩和解压缩
  • 2017-05-28C#日期时间格式化小结
  • 2017-08-14C#网页分页标签生成
  • 2017-05-28C#检测上传文件真正类型的方法
  • 2017-05-28C#中通过API实现的打印类 实例代码
  • 2017-05-28协定需要会话,但是绑定“BasicHttpBinding”不支持它或者因配置不正确而无法支持它
  • 2017-05-28C#实现老板键功能的代码
  • 2017-05-28C#创建二叉搜索树的方法
  • 2017-05-28C#中实现Fluent Interface的三种方法
  • 2017-05-28C#引用访问权限分析

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • C#采用HttpWebRequest实现保持会话上传文件到HTTP的方法
    • C#中析构函数、Dispose、Close方法的区别
    • 那些年,我还在学习C# 学习笔记
    • C#简单实现文件上传功能
    • c#文件助手类分享(读取文件内容 操作日志文件)
    • C# 匿名方法基础回顾
    • C#图像伪彩色处理方法
    • 浅析C#静态类,静态构造函数,静态变量
    • 基于c#图像灰度化、灰度反转、二值化的实现方法详解
    • C# KeyUp事件中MessageBox的回车(Enter)键回调问题解决方案

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有