用c#读取Excel的三种方法.docx
- 文档编号:12271921
- 上传时间:2023-06-05
- 格式:DOCX
- 页数:18
- 大小:40.12KB
用c#读取Excel的三种方法.docx
《用c#读取Excel的三种方法.docx》由会员分享,可在线阅读,更多相关《用c#读取Excel的三种方法.docx(18页珍藏版)》请在冰点文库上搜索。
用c#读取Excel的三种方法
C#读取Excel的三种方法及比较
(1)OleDB方式
优点:
将Excel直接当做数据源处理,通过SQL直接读取内容,读取速度较快。
缺点:
读取数据方式不够灵活,无法直接读取某一个单元格,只有将整个Sheet页读取出来后(结果为Datatable)再在Datatable中根据行列数来获取指定的值。
当Excel数据量很大时。
会非常占用内存,当内存不够时会抛出内存溢出的异常。
读取代码如下:
1:
publicDataTableGetExcelTableByOleDB(stringstrExcelPath,stringtableName)
2:
{
3:
try
4:
{
5:
DataTabledtExcel=newDataTable();
6:
//数据表
7:
DataSetds=newDataSet();
8:
//获取文件扩展名
9:
stringstrExtension=System.IO.Path.GetExtension(strExcelPath);
10:
stringstrFileName=System.IO.Path.GetFileName(strExcelPath);
11:
//Excel的连接
12:
OleDbConnectionobjConn=null;
13:
switch(strExtension)
14:
{
15:
case".xls":
16:
objConn=newOleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;DataSource="+strExcelPath+";"+"ExtendedProperties=\"Excel8.0;HDR=NO;IMEX=1;\"");
17:
break;
18:
case".xlsx":
19:
objConn=newOleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;DataSource="+strExcelPath+";"+"ExtendedProperties=\"Excel12.0;HDR=NO;IMEX=1;\"");
20:
break;
21:
default:
22:
objConn=null;
23:
break;
24:
}
25:
if(objConn==null)
26:
{
27:
returnnull;
28:
}
29:
objConn.Open();
30:
//获取Excel中所有Sheet表的信息
31:
//System.Data.DataTableschemaTable=objConn.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables,null);
32:
//获取Excel的第一个Sheet表名
33:
//stringtableName=schemaTable.Rows[0][2].ToString().Trim();
34:
stringstrSql="select*from["+tableName+"]";
35:
//获取Excel指定Sheet表中的信息
36:
OleDbCommandobjCmd=newOleDbCommand(strSql,objConn);
37:
OleDbDataAdaptermyData=newOleDbDataAdapter(strSql,objConn);
38:
myData.Fill(ds,tableName);//填充数据
39:
objConn.Close();
40:
//dtExcel即为excel文件中指定表中存储的信息
41:
dtExcel=ds.Tables[tableName];
42:
returndtExcel;
43:
}
44:
catch
45:
{
46:
returnnull;
47:
}
48:
}
下面说明一下连接字符串
HDR=Yes,这代表第一行是标题,不做为数据使用(但是我在实际使用中,如果第一行存在复杂数值,那么读取得到的Datatable列标题会自动设置为F1、F2等方式命名,与实际应用不符,所以当时是通过HDR=No方式将所有内容读取到Datatable中,然后手动将第一行设置成标题的);IMEX(IMportEXportmode)设置
IMEX有三种模式:
0isExportmode
1isImportmode
2isLinkedmode(fullupdatecapabilities)
我这里特别要说明的就是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然后将原SheetCopy进去。
但实际情况并不能为每个Excel做以上检查。
下面给出了过滤的方案。
(此问题我们有验证过,大家自己验证一下吧)
1:
//objConn为读取Excel的链接,下面通过过滤来获取有效的Sheet页名称集合
2:
System.Data.DataTableschemaTable=objConn.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables,null);
3:
List
4:
for(inti=0;i 5: { 6: stringstrSheetName=(string)dtSheetName.Rows[i]["TABLE_NAME"]; 7: if(strSheetName.Contains("$")&&! strSheetName.Replace("'","").EndsWith("$")) 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就为: 'MySheet (1)$',所以判断最后一个字符是不是$之前最好过滤一下单引号。 --------------------------------- (2)Com组件的方式(通过添加Microsoft.Office.Interop.Excel引用实现) 优点: 能够非常灵活的读取Excel中的数据,用户可以灵活的调用各种函数进行处理。 缺点: 基于单元格的处理,读取速度较慢,对于数据量较大的文件最好不要使用此种方式读取。 需要添加相应的DLL引用,必须存在此引用才可使用,如果是Web站点部署在IIS上时,还需要服务器机子已安装了Excel,有时候还需要为配置IIS权限。 读取代码如下: 1: privateStopwatchwath=newStopwatch(); 2: /// 3: ///使用COM读取Excel 4: /// 5: /// 6: /// 7: publicSystem.Data.DataTableGetExcelData(stringexcelFilePath) 8: { 9: Excel.Applicationapp=newExcel.Application(); 10: Excel.Sheetssheets; 11: Excel.Workbookworkbook=null; 12: objectoMissiong=System.Reflection.Missing.Value; 13: System.Data.DataTabledt=newSystem.Data.DataTable(); 14: wath.Start(); 15: try 16: { 17: if(app==null) 18: { 19: returnnull; 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.Worksheetworksheet=(Excel.Worksheet)sheets.get_Item (1);//读取第一张表 26: if(worksheet==null) 27: returnnull; 28: stringcellContent; 29: intiRowCount=worksheet.UsedRange.Rows.Count; 30: intiColCount=worksheet.UsedRange.Columns.Count; 31: Excel.Rangerange; 32: //负责列头Start 33: DataColumndc; 34: intColumnID=1; 35: range=(Excel.Range)worksheet.Cells[1,1]; 36: while(range.Text.ToString().Trim()! ="") 37: { 38: dc=newDataColumn(); 39: dc.DataType=System.Type.GetType("System.String"); 40: dc.ColumnName=range.Text.ToString().Trim(); 41: dt.Columns.Add(dc); 42: 43: range=(Excel.Range)worksheet.Cells[1,++ColumnID]; 44: } 45: //End 46: for(intiRow=2;iRow<=iRowCount;iRow++) 47: { 48: DataRowdr=dt.NewRow(); 49: for(intiCol=1;iCol<=iColCount;iCol++) 50: { 51: range=(Excel.Range)worksheet.Cells[iRow,iCol]; 52: cellContent=(range.Value2==null)? "": range.Text.ToString(); 53: dr[iCol-1]=cellContent; 54: } 55: dt.Rows.Add(dr); 56: } 57: wath.Stop(); 58: TimeSpants=wath.Elapsed; 59: //将数据读入到DataTable中——End 60: returndt; 61: } 62: catch 63: { 64: returnnull; 65: } 66: finally 67: { 68: workbook.Close(false,oMissiong,oMissiong); 69: System.Runtime.InteropServices.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: /// 80: ///使用COM,多线程读取Excel(1主线程、4副线程) 81: /// 82: /// 83: /// 84: publicSystem.Data.DataTableThreadReadExcel(stringexcelFilePath) 85: { 86: Excel.Applicationapp=newExcel.Application(); 87: Excel.Sheetssheets=null; 88: Excel.Workbookworkbook=null; 89: objectoMissiong=System.Reflection.Missing.Value; 90: System.Data.DataTabledt=newSystem.Data.DataTable(); 91: wath.Start(); 92: try 93: { 94: if(app==null) 95: { 96: returnnull; 97: } 98: workbook=app.Workbooks.Open(excelFilePath,oMissiong,oMissiong,oMissiong,oMissiong,oMissiong,oMissiong, 99: oMissiong,oMissiong,oMissiong,oMissiong,oMissiong,oMissiong,oMissiong,oMissiong); 100: //将数据读入到DataTable中——Start 101: sheets=workbook.Worksheets; 102: Excel.Worksheetworksheet=(Excel.Worksheet)sheets.get_Item (1);//读取第一张表 103: if(worksheet==null) 104: returnnull; 105: stringcellContent; 106: intiRowCount=worksheet.UsedRange.Rows.Count; 107: intiColCount=worksheet.UsedRange.Columns.Count; 108: Excel.Rangerange; 109: //负责列头Start 110: DataColumndc; 111: intColumnID=1; 112: range=(Excel.Range)worksheet.Cells[1,1]; 113: while(iColCount>=ColumnID) 114: { 115: dc=newDataColumn(); 116: dc.DataType=System.Type.GetType("System.String"); 117: stringstrNewColumnName=range.Text.ToString().Trim(); 118: if(strNewColumnName.Length==0)strNewColumnName="_1"; 119: //判断列名是否重复 120: for(inti=1;i 121: { 122: if(dt.Columns[i-1].ColumnName==strNewColumnName) 123: strNewColumnName=strNewColumnName+"_1"; 124: } 125: dc.ColumnName=strNewColumnName; 126: dt.Columns.Add(dc); 127: range=(Excel.Range)worksheet.Cells[1,++ColumnID]; 128: } 129: //End 130: //数据大于500条,使用多进程进行读取数据 131: if(iRowCount-1>500) 132: { 133: //开始多线程读取数据 134: //新建线程 135: intb2=(iRowCount-1)/10; 136: DataTabledt1=newDataTable("dt1"); 137: dt1=dt.Clone(); 138: SheetOptionssheet1thread=newSheetOptions(worksheet,iColCount,2,b2+1,dt1); 139: Threadothread1=newThread(newThreadStart(sheet1thread.SheetToDataTable)); 140: othread1.Start(); 141: //阻塞1毫秒,保证第一个读取dt1 142: Thread.Sleep (1); 143: DataTabledt2=newDataTable("dt2"); 144: dt2=dt.Clone(); 145: SheetOptionssheet2thread=newSheetOptions(worksheet,iColCount,b2+2,b2*2+1,dt2); 146: Threadothread2=newThread(newThreadStart(sheet2thread.SheetToDataTable)); 147: othread2.Start(); 148: DataTabledt3=newDataTable("dt3"); 149: dt3=dt.Clone(); 150: SheetOptionssheet3thread=newSheetOptions(worksheet,iColCount,b2*2+2,b2*3+1,dt3); 151: Threadothread3=newThread(newThreadStart(sheet3thread.SheetToDataTable)); 152: othread3.Start(); 153: DataTabledt4=newDataTable("dt4"); 154: dt4=dt.Clone(); 155: SheetOptionssheet4thread=newSheetOptions(worksheet,iColCount,b2*3+2,b2*4+1,dt4); 156: Threadothread4=newThread(newThreadStart(sheet4thread.SheetToDataTable)); 157: othread4.Start(); 158: //主线程读取剩余数据 159: for(intiRow=b2*4+2;iRow<=iRowCount;iRow++) 160: { 161: DataRowdr=dt.NewRow(); 162: for(intiCol=1;iCol<=iColCount;iCol++) 163: { 164: range=(Excel.Range)worksheet.Cells[iRow,iCol]; 165: cellContent=(range.Value2==null)? "": range.Text.ToString(); 166: dr[iCol-1]=cellContent; 167: } 168: dt.Rows.Add(dr); 169: } 170: othread1.Join();
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- c# 读取 Excel 方法