已阅读5页,还剩5页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
C#读取Excel的三种方式以及比较分析投稿:mdxy-dxy 字体:增加 减小 类型:转载 时间:2015-11-08 我要评论这篇文章主要介绍了C#读取Excel的三种方式以及比较分析,需要的朋友可以参考下(1)OleDB方式优点:将Excel直接当做数据源处理,通过SQL直接读取内容,读取速度较快。缺点:读取数据方式不够灵活,无法直接读取某一个单元格,只有将整个Sheet页读取出来后(结果为Datatable)再在Datatable中根据行列数来获取指定的值。当Excel数据量很大时。会非常占用内存,当内存不够时会抛出内存溢出的异常。读取代码如下:?123456789101112131415161718192021222324252627282930313233343536373839404142434445464748public DataTable GetExcelTableByOleDB(string strExcelPath, string tableName)tryDataTable 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.Rows02.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.TablestableName;return dtExcel;catchreturn null;下面说明一下连接字符串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做以上检查。下面给出了过滤的方案。(此问题我们有验证过,大家自己验证一下吧)?1234567891011121314/objConn为读取Excel的链接,下面通过过滤来获取有效的Sheet页名称集合System.Data.DataTable schemaTable = objConn.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, null);List lstSheetNames = new List();for (int i = 0; i schemaTable.Rows.Count; i+)string strSheetName = (string)dtSheetName.RowsiTABLE_NAME;if (strSheetName.Contains($) & !strSheetName.Replace(, ).EndsWith($)/过滤无效SheetName完毕.continue;if (lstSheetNames != null & !lstSheetNames.Contains(strSheetName)lstSheetNames.Add(strSheetName);因为读取出来无效SheetName一般情况最后一个字符都不会是$。如果SheetName有一些特殊符号,读取出来的SheetName会自动加上单引号。比如在Excel中将SheetName编辑成MySheet(1),此时读取出来的SheetName就为:MySheet(1)$,所以判断最后一个字符是不是$之前最好过滤一下单引号。-(2)Com组件的方式(通过添加 Microsoft.Office.Interop.Excel引用实现)优点:能够非常灵活的读取Excel中的数据,用户可以灵活的调用各种函数进行处理。缺点:基于单元格的处理,读取速度较慢,对于数据量较大的文件最好不要使用此种方式读取。需要添加相应的DLL引用,必须存在此引用才可使用,如果是Web站点部署在IIS上时,还需要服务器机子已安装了Excel,有时候还需要为配置IIS权限。读取代码如下:?123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229private Stopwatch wath = new Stopwatch();/ / 使用COM读取Excel/ / 路径/ DataTabelpublic 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();tryif (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;/负责列头StartDataColumn dc;int ColumnID = 1;range = (Excel.Range)worksheet.Cells1, 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.Cells1, +ColumnID;/Endfor (int iRow = 2; iRow = iRowCount; iRow+)DataRow dr = dt.NewRow();for (int iCol = 1; iCol = iColCount; iCol+)range = (Excel.Range)worksheet.CellsiRow, iCol;cellContent = (range.Value2 = null) ? : range.Text.ToString();driCol - 1 = cellContent;dt.Rows.Add(dr);wath.Stop();TimeSpan ts = wath.Elapsed;/将数据读入到DataTable中Endreturn dt;catchreturn null;finallyworkbook.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();/ / 使用COM,多线程读取Excel(1 主线程、4 副线程)/ / 路径/ DataTabelpublic System.Data.DataTable ThreadReadExcel(string excelFilePath)Excel.Application app = new Excel.Application();Excel.Sheets sheets = null;Excel.Workbook workbook = null;object oMissiong = System.Reflection.Missing.Value;System.Data.DataTable dt = new System.Data.DataTable();wath.Start();tryif (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;/负责列头StartDataColumn dc;int ColumnID = 1;range = (Excel.Range)worksheet.Cells1, 1;while (iColCount = ColumnID)dc = new DataColumn();dc.DataType = System.Type.GetType(System.String);string strNewColumnName = range.Text.ToString().Trim();if (strNewColumnName.Length = 0) strNewColumnName = _1;/判断列名是否重复for (int i = 1; i 500)/开始多线程读取数据/新建线程int b2 = (iRowCount - 1) / 10;DataTable dt1 = new DataTable(dt1);dt1 = dt.Clone();SheetOptions sheet1thread = new SheetOptions(worksheet, iColCount, 2, b2 + 1, dt1);Thread othread1 = new Thread(new ThreadStart(sheet1thread.SheetToDataTable);othread1.Start();/阻塞 1 毫秒,保证第一个读取 dt1Thread.Sleep(1);DataTable dt2 = new DataTable(dt2);dt2 = dt.Clone();SheetOptions sheet2thread = new SheetOptions(worksheet, iColCount, b2 + 2, b2 * 2 + 1, dt2);Thread othread2 = new Thread(new ThreadStart(sheet2thread.SheetToDataTable);othread2.Start();DataTable dt3 = new DataTable(dt3);dt3 = dt.Clone();SheetOptions sheet3thread = new SheetOptions(worksheet, iColCount, b2 * 2 + 2, b2 * 3 + 1, dt3);Thread othread3 = new Thread(new ThreadStart(sheet3thread.SheetToDataTable);othread3.Start();DataTable dt4 = new DataTable(dt4);dt4 = dt.Clone();SheetOptions sheet4thread = new SheetOptions(worksheet, iColCount, b2 * 3 + 2, b2 * 4 + 1, dt4);Thread othread4 = new Thread(new ThreadStart(sheet4thread.SheetToDataTable);othread4.Start();/主线程读取剩余数据for (int iRow = b2 * 4 + 2; iRow = iRowCount; iRow+)DataRow dr = dt.NewRow();for (int iCol = 1; iCol = iColCount; iCol+)range = (Excel.Range)worksheet.CellsiRow, iCol;cellContent = (range.Value2 = null) ? : range.Text.ToString();driCol - 1 = cellContent;dt.Rows.Add(dr);othread1.Join();othread2.Join();othread3.Join();othread4.Join();/将多个线程读取出来的数据追加至 dt1 后面foreach (DataRow dr in dt.Rows)dt1.Rows.Add(dr.ItemArray);dt.Clear();dt.Dispose();foreach (DataRow dr in dt2.Rows)dt1.Rows.Add(dr.ItemArray);dt2.Clear();dt2.Dispose();foreach (DataRow dr in dt3.Rows)dt1.Rows.Add(dr.ItemArray);dt3.Clear();dt3.Dispose();foreach (DataRow dr in dt4.Rows)dt1.Rows.Add(dr.ItemArray);dt4.Clear();dt4.Dispose();return dt1;elsefor (int iRow = 2; iRow = iRowCount; iRow+)DataRow dr = dt.NewRow();for (int iCol = 1; iCol = iColCount; iCol+)range = (Excel.Range)worksheet.CellsiRow, iCol;cellContent = (range.Value2 = null) ? : range.Text.ToString();driCol - 1 = cellContent;dt.Rows.Add(dr);wath.Stop();TimeSpan ts = wath.Elapsed;/将数据读入到DataTable中Endreturn dt;catchreturn null;finallyworkbook.Close(false, oMissiong, oMissiong);System.Runtime.InteropServices.Marshal.ReleaseComObject(workbook);System.Runtime.InteropServices.Marshal.ReleaseComObject(sheets);workbook = null;app.Workbooks.Close();app.Quit();System.Runtime.InteropServices.Marshal.ReleaseComObject(app);app = null;GC.Collect();GC.WaitForPendingFinalizers();(3)NPOI方式读取Excel(此方法未经过测试)NPOI 是 POI 项目的 .NET 版本。POI是一个开源的Java读写Excel、WORD等微软OLE2组件文档的项目。使用 NPOI 你就可以在没有安装 Office 或者相应环境的机器上对 WORD/EXCEL 文档进行读写。优点:读取Excel速度较快,读取方式操作灵活性缺点:需要下载相应的插件并添加到系统引用当中。?12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667/ / 将excel中的数据导入到DataTable中/ / excel工作薄sheet的名称/ 第一行是否是DataTable的列名/ 返回的DataTablepublic DataTable ExcelToDataTable(string sheetName, bool isFirstRowColumn)ISheet sheet = null;DataTable data = new DataTable();int s
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年市场营销专业认证试题集与答案详解
- 初中八年级地理《大漠·长河·绿洲-西北地区人地关系密钥》学练案
- 初中八年级地理上册《中国的疆域》单元整合复习教学设计
- 财务规划资产配置策略预案
- 八年级数学上册压轴题精讲-思维进阶与模型建构专题教案
- 2026年机动车信号系统维修技术考试题库
- 个人健康监测系统搭建指导书
- 八年级物理跨学科项目式导学案:噪声地图测绘与静音空间定制-苏科版八年级上册第1.3章项目化学习设计
- 2026年超声中级考试试题及答案
- 2026年超声基础、心脏血管系统试题(1)试卷及答案
- 2026年沪教版八年级下册历史期末测试卷(含答案可下载)
- 2026浙江杭州萧山区义蓬街道国有企业招聘4人笔试模拟试题及答案详解
- 【物业分享】XXX物业服务品质管理制度
- 2026年湖南省怀化市八年级地理生物会考考试题库(含答案)
- 2025年小学英语教师招聘考试专业知识试题及答案
- 2026年北京市丰台区初三下学期二模物理试卷和答案
- 2026年地铁车站设备智能运维与预测性维护
- 2021年安徽省中考地理真题(word解析版)
- 2022年医学专题-国家慢性病综合防控示范区建设指标体系
- 人教版美术七年级下册《广而告之》课件
- DB32-T 3706-2019 住宅装饰装修质量规范-(高清现行)
评论
0/150
提交评论