用c#读取Excel的三种方法.docx

上传人:b****3 文档编号:4635798 上传时间:2022-12-07 格式:DOCX 页数:15 大小:40.07KB
下载 相关 举报
用c#读取Excel的三种方法.docx_第1页
第1页 / 共15页
用c#读取Excel的三种方法.docx_第2页
第2页 / 共15页
用c#读取Excel的三种方法.docx_第3页
第3页 / 共15页
用c#读取Excel的三种方法.docx_第4页
第4页 / 共15页
用c#读取Excel的三种方法.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

用c#读取Excel的三种方法.docx

《用c#读取Excel的三种方法.docx》由会员分享,可在线阅读,更多相关《用c#读取Excel的三种方法.docx(15页珍藏版)》请在冰豆网上搜索。

用c#读取Excel的三种方法.docx

用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:

ListlstSheetNames=newList();

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:

///DataTabel

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:

///DataTabel

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();

1

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1