用c读取excel的三种方法_第1页
用c读取excel的三种方法_第2页
用c读取excel的三种方法_第3页
用c读取excel的三种方法_第4页
用c读取excel的三种方法_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、C#读取Excel的三种方法及比较(1)OleDB方式优点:将Excel直接当做数据源处理,通过SQL直接读取内容,读取速度较快。缺点:读取数据方式不够灵活,无法直接读取某一个单元格,只有将整个Sheet页读取出来后(结果为Datatable)再在Datatable中根据行列数来获取指定的值。           当Excel数据量很大时。会非常占用内存,当内存不够时会抛出内存溢出的异常。读取代码如下: 1: public DataTable GetExcelTableByOleDB(strin

2、g strExcelPath, string tableName) 2: 3: try 4: 5: DataTable dtExcel = new DataTable(); 6: /数据表 7: DataSet ds = new DataSet(); 8: /获取文件扩展名 9: string strExtension = System.IO.Path.GetExtension(strExcelPath); 10: string strFileName = System.IO.Path.GetFileName(strExcelPath); 11: /Excel的连接 12: OleDbConn

3、ection objConn = null; 13: switch (strExtension) 14: 15: case ".xls": 16: objConn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + strExcelPath + "" + "Extended Properties="Excel 8.0;HDR=NO;IMEX=1;""); 17: break; 18: case "

4、;.xlsx": 19: objConn = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + strExcelPath + "" + "Extended Properties="Excel 12.0;HDR=NO;IMEX=1;""); 20: break; 21: default: 22: objConn = null; 23: break; 24: 25: if (objConn = null) 26: 27

5、: return null; 28: 29: objConn.Open(); 30: /获取Excel中所有Sheet表的信息 31: /System.Data.DataTable schemaTable = objConn.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, null); 32: /获取Excel的第一个Sheet表名 33: /string tableName = schemaTable.Rows02.ToString().Trim(); 34: string strSql = "select

6、 * from " + tableName + "" 35: /获取Excel指定Sheet表中的信息 36: OleDbCommand objCmd = new OleDbCommand(strSql, objConn); 37: OleDbDataAdapter myData = new OleDbDataAdapter(strSql, objConn); 38: myData.Fill(ds, tableName);/填充数据 39: objConn.Close(); 40: /dtExcel即为excel文件中指定表中存储的信息 41: dtExcel =

7、 ds.TablestableName; 42: return dtExcel; 43: 44: catch 45: 46: return null; 47: 48: 下面说明一下连接字符串        HDR=Yes,这代表第一行是标题,不做为数据使用(但是我在实际使用中,如果第一行存在复杂数值,那么读取得到的Datatable列标题会自动设置为F1、F2等方式命名,与实际应用不符,所以当时是通过HDR=No方式将所有内容读取到Datatable中,然后手动将第一行设置成标题的);IMEX ( IMport EXport

8、 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 时为“链接模式”,这个模式开启的

9、Excel 档案可同时支援“读取”与“写入”用途。-另外,读取Excel2007版本的文件时,版本应该从8.0改为12.0,同时驱动不能再用Jet,而应该用ACE。负责会造成“找不到可安装的 ISAM”的错误。-在网上还发现采用这种方式存在取出的Sheet表的个数多于实际Excel表中的Sheet表个数的情况,其原因有二:1. 取出的名称中,包括了XL命名管理器中的名称(参见XL2007的公式-命名管理器, 快捷键Crtl+F3);2. 取出的名称中,包括了FilterDatabase后缀的, 这是XL用来记录Filter范围的。对于第一点比较简单, 删除已有命名管理器中的内容即可;第二点处理

10、起来比较麻烦, Filter删除后这些名称依然保留着,简单的做法是新增Sheet然后将原Sheet Copy进去。但实际情况并不能为每个Excel做以上检查。下面给出了过滤的方案。(此问题我们有验证过,大家自己验证一下吧) 1: /objConn为读取Excel的链接,下面通过过滤来获取有效的Sheet页名称集合 2: System.Data.DataTable schemaTable = objConn.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, null); 3: List<string> lstS

11、heetNames = new List<string>(); 4: for (int i = 0; i < schemaTable.Rows.Count; i+) 5: 6: string strSheetName = (string)dtSheetName.Rowsi"TABLE_NAME" 7: if (strSheetName.Contains("$") && !strSheetName.Replace("'", "").EndsWith("$"

12、) 8: 9: /过滤无效SheetName完毕. 10: continue; 11: 12: if (lstSheetNames != null && !lstSheetNames.Contains(strSheetName) 13: lstSheetNames.Add(strSheetName); 14: 因为读取出来无效SheetName一般情况最后一个字符都不会是$。如果SheetName有一些特殊符号,读取出来的SheetName会自动加上单引号。比如在Excel中将SheetName编辑成MySheet(1),此时读取出来的SheetName就为:'MySh

13、eet(1)$',所以判断最后一个字符是不是$之前最好过滤一下单引号。-(2)Com组件的方式(通过添加 Microsoft.Office.Interop.Excel引用实现)优点:能够非常灵活的读取Excel中的数据,用户可以灵活的调用各种函数进行处理。缺点:基于单元格的处理,读取速度较慢,对于数据量较大的文件最好不要使用此种方式读取。           需要添加相应的DLL引用,必须存在此引用才可使用,如果是Web站点部署在IIS上时,还需要服务器机子已安装了Excel,有时候还需

14、要为配置IIS权限。读取代码如下: 1: private Stopwatch wath = new Stopwatch(); 2: / <summary> 3: / 使用COM读取Excel 4: / </summary> 5: / <param name="excelFilePath">路径</param> 6: / <returns>DataTabel</returns> 7: public System.Data.DataTable GetExcelData(string excelFilePat

15、h) 8: 9: Excel.Application app = new Excel.Application(); 10: Excel.Sheets sheets; 11: Excel.Workbook workbook = null; 12: object oMissiong = System.Reflection.Missing.Value; 13: System.Data.DataTable dt = new System.Data.DataTable(); 14: wath.Start(); 15: try 16: 17: if (app = null) 18: 19: return

16、null; 20: 21: workbook = app.Workbooks.Open(excelFilePath, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, 22: oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong); 23: /将数据读入到DataTable中Start 24: sheets = workbook.Worksheets; 25: Excel.Worksheet w

17、orksheet = (Excel.Worksheet)sheets.get_Item(1);/读取第一张表 26: if (worksheet = null) 27: return null; 28: string cellContent; 29: int iRowCount = worksheet.UsedRange.Rows.Count; 30: int iColCount = worksheet.UsedRange.Columns.Count; 31: Excel.Range range; 32: /负责列头Start 33: DataColumn dc; 34: int Column

18、ID = 1; 35: range = (Excel.Range)worksheet.Cells1, 1; 36: while (range.Text.ToString().Trim() != "") 37: 38: dc = new DataColumn(); 39: dc.DataType = System.Type.GetType("System.String"); 40: dc.ColumnName = range.Text.ToString().Trim(); 41: dt.Columns.Add(dc); 42: 43: range = (E

19、xcel.Range)worksheet.Cells1, +ColumnID; 44: 45: /End 46: for (int iRow = 2; iRow <= iRowCount; iRow+) 47: 48: DataRow dr = dt.NewRow(); 49: for (int iCol = 1; iCol <= iColCount; iCol+) 50: 51: range = (Excel.Range)worksheet.CellsiRow, iCol; 52: cellContent = (range.Value2 = null) ? ""

20、; : range.Text.ToString(); 53: driCol - 1 = cellContent; 54: 55: dt.Rows.Add(dr); 56: 57: wath.Stop(); 58: TimeSpan ts = wath.Elapsed; 59: /将数据读入到DataTable中End 60: return dt; 61: 62: catch 63: 64: return null; 65: 66: finally 67: 68: workbook.Close(false, oMissiong, oMissiong); 69: System.Runtime.In

21、teropServices.Marshal.ReleaseComObject(workbook); 70: workbook = null; 71: app.Workbooks.Close(); 72: app.Quit(); 73: System.Runtime.InteropServices.Marshal.ReleaseComObject(app); 74: app = null; 75: GC.Collect(); 76: GC.WaitForPendingFinalizers(); 77: 78: 79: / <summary> 80: / 使用COM,多线程读取Exce

22、l(1 主线程、4 副线程) 81: / </summary> 82: / <param name="excelFilePath">路径</param> 83: / <returns>DataTabel</returns> 84: public System.Data.DataTable ThreadReadExcel(string excelFilePath) 85: 86: Excel.Application app = new Excel.Application(); 87: Excel.Sheets she

23、ets = null; 88: Excel.Workbook workbook = null; 89: object oMissiong = System.Reflection.Missing.Value; 90: System.Data.DataTable dt = new System.Data.DataTable(); 91: wath.Start(); 92: try 93: 94: if (app = null) 95: 96: return null; 97: 98: workbook = app.Workbooks.Open(excelFilePath, oMissiong, o

24、Missiong, oMissiong, oMissiong, oMissiong, oMissiong, 99: oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong); 100: /将数据读入到DataTable中Start 101: sheets = workbook.Worksheets; 102: Excel.Worksheet worksheet = (Excel.Worksheet)sheets.get_Item(1);/读取第一张表 103: if (work

25、sheet = null) 104: return null; 105: string cellContent; 106: int iRowCount = worksheet.UsedRange.Rows.Count; 107: int iColCount = worksheet.UsedRange.Columns.Count; 108: Excel.Range range; 109: /负责列头Start 110: DataColumn dc; 111: int ColumnID = 1; 112: range = (Excel.Range)worksheet.Cells1, 1; 113:

26、 while (iColCount >= ColumnID) 114: 115: dc = new DataColumn(); 116: dc.DataType = System.Type.GetType("System.String"); 117: string strNewColumnName = range.Text.ToString().Trim(); 118: if (strNewColumnName.Length = 0) strNewColumnName = "_1" 119: /判断列名是否重复 120: for (int i =

27、1; i < ColumnID; i+) 121: 122: if (dt.Columnsi - 1.ColumnName = strNewColumnName) 123: strNewColumnName = strNewColumnName + "_1" 124: 125: dc.ColumnName = strNewColumnName; 126: dt.Columns.Add(dc); 127: range = (Excel.Range)worksheet.Cells1, +ColumnID; 128: 129: /End 130: /数据大于500条,使用多

28、进程进行读取数据 131: if (iRowCount - 1 > 500) 132: 133: /开始多线程读取数据 134: /新建线程 135: int b2 = (iRowCount - 1) / 10; 136: DataTable dt1 = new DataTable("dt1"); 137: dt1 = dt.Clone(); 138: SheetOptions sheet1thread = new SheetOptions(worksheet, iColCount, 2, b2 + 1, dt1); 139: Thread othread1 = ne

29、w Thread(new ThreadStart(sheet1thread.SheetToDataTable); 140: othread1.Start(); 141: /阻塞 1 毫秒,保证第一个读取 dt1 142: Thread.Sleep(1); 143: DataTable dt2 = new DataTable("dt2"); 144: dt2 = dt.Clone(); 145: SheetOptions sheet2thread = new SheetOptions(worksheet, iColCount, b2 + 2, b2 * 2 + 1, dt2)

30、; 146: Thread othread2 = new Thread(new ThreadStart(sheet2thread.SheetToDataTable); 147: othread2.Start(); 148: DataTable dt3 = new DataTable("dt3"); 149: dt3 = dt.Clone(); 150: SheetOptions sheet3thread = new SheetOptions(worksheet, iColCount, b2 * 2 + 2, b2 * 3 + 1, dt3); 151: Thread oth

31、read3 = new Thread(new ThreadStart(sheet3thread.SheetToDataTable); 152: othread3.Start(); 153: DataTable dt4 = new DataTable("dt4"); 154: dt4 = dt.Clone(); 155: SheetOptions sheet4thread = new SheetOptions(worksheet, iColCount, b2 * 3 + 2, b2 * 4 + 1, dt4); 156: Thread othread4 = new Threa

32、d(new ThreadStart(sheet4thread.SheetToDataTable); 157: othread4.Start(); 158: /主线程读取剩余数据 159: for (int iRow = b2 * 4 + 2; iRow <= iRowCount; iRow+) 160: 161: DataRow dr = dt.NewRow(); 162: for (int iCol = 1; iCol <= iColCount; iCol+) 163: 164: range = (Excel.Range)worksheet.CellsiRow, iCol; 16

33、5: cellContent = (range.Value2 = null) ? "" : range.Text.ToString(); 166: driCol - 1 = cellContent; 167: 168: dt.Rows.Add(dr); 169: 170: othread1.Join(); 171: othread2.Join(); 172: othread3.Join(); 173: othread4.Join(); 174: /将多个线程读取出来的数据追加至 dt1 后面 175: foreach (DataRow dr in dt.Rows) 176:

34、 dt1.Rows.Add(dr.ItemArray); 177: dt.Clear(); 178: dt.Dispose(); 179: foreach (DataRow dr in dt2.Rows) 180: dt1.Rows.Add(dr.ItemArray); 181: dt2.Clear(); 182: dt2.Dispose(); 183: foreach (DataRow dr in dt3.Rows) 184: dt1.Rows.Add(dr.ItemArray); 185: dt3.Clear(); 186: dt3.Dispose(); 187: foreach (Dat

35、aRow dr in dt4.Rows) 188: dt1.Rows.Add(dr.ItemArray); 189: dt4.Clear(); 190: dt4.Dispose(); 191: return dt1; 192: 193: else 194: 195: for (int iRow = 2; iRow <= iRowCount; iRow+) 196: 197: DataRow dr = dt.NewRow(); 198: for (int iCol = 1; iCol <= iColCount; iCol+) 199: 200: range = (Excel.Rang

36、e)worksheet.CellsiRow, iCol; 201: cellContent = (range.Value2 = null) ? "" : range.Text.ToString(); 202: driCol - 1 = cellContent; 203: 204: dt.Rows.Add(dr); 205: 206: 207: wath.Stop(); 208: TimeSpan ts = wath.Elapsed; 209: /将数据读入到DataTable中End 210: return dt; 211: 212: catch 213: 214: ret

37、urn null; 215: 216: finally 217: 218: workbook.Close(false, oMissiong, oMissiong); 219: System.Runtime.InteropServices.Marshal.ReleaseComObject(workbook); 220: System.Runtime.InteropServices.Marshal.ReleaseComObject(sheets); 221: workbook = null; 222: app.Workbooks.Close(); 223: app.Quit(); 224: Sys

38、tem.Runtime.InteropServices.Marshal.ReleaseComObject(app); 225: app = null; 226: GC.Collect(); 227: GC.WaitForPendingFinalizers(); 228: 229: -(3)NPOI方式读取Excel(此方法未经过测试)NPOI 是 POI 项目的 .NET 版本。POI是一个开源的Java读写Excel、WORD等微软OLE2组件文档的项目。使用 NPOI 你就可以在没有安装 Office 或者相应环境的机器上对 WORD/EXCEL 文档进行读写。优点:读

39、取Excel速度较快,读取方式操作灵活性缺点:需要下载相应的插件并添加到系统引用当中。 1: / <summary> 2: / 将excel中的数据导入到DataTable中 3: / </summary> 4: / <param name="sheetName">excel工作薄sheet的名称</param> 5: / <param name="isFirstRowColumn">第一行是否是DataTable的列名</param> 6: / <returns>返回的DataTable</returns> 7: public DataTable ExcelToDataTable(string sheetName, bool isFirstRowColumn) 8: 9: ISheet sheet = null; 10: DataTable data = new DataTable(); 11: int startRow = 0; 12: try 13: 14: fs = new FileStream(fileName, FileMode.Open,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论