




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、C#讀取Excel的三種方法及比較(1)OleDB方式優(yōu)點(diǎn):將Excel直接當(dāng)做數(shù)據(jù)源處理,通過SQL直接讀取內(nèi)容,讀取速度較快。缺點(diǎn):讀取數(shù)據(jù)方式不夠靈活,無法直接讀取某一個(gè)單元格,只有將整個(gè)Sheet頁讀取出來后(結(jié)果為Datatable)再在Datatable中根據(jù)行列數(shù)來獲取指定的值。 當(dāng)Excel數(shù)據(jù)量很大時(shí)。會(huì)非常占用內(nèi)存,當(dāng)內(nèi)存不夠時(shí)會(huì)拋出內(nèi)存溢出的異常。讀取代碼如下: 1: public DataTable GetExcelTableByOleDB(strin
2、g strExcelPath, string tableName) 2: 3: try 4: 5: DataTable dtExcel = new DataTable(); 6: /數(shù)據(jù)表 7: DataSet ds = new DataSet(); 8: /獲取文件擴(kuò)展名 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的第一個(gè)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);/填充數(shù)據(jù) 39: objConn.Close(); 40: /dtExcel即為excel文件中指定表中存儲(chǔ)的信息 41: dtExcel =
7、 ds.TablestableName; 42: return dtExcel; 43: 44: catch 45: 46: return null; 47: 48: 下面說明一下連接字符串 HDR=Yes,這代表第一行是標(biāo)題,不做為數(shù)據(jù)使用(但是我在實(shí)際使用中,如果第一行存在復(fù)雜數(shù)值,那么讀取得到的Datatable列標(biāo)題會(huì)自動(dòng)設(shè)置為F1、F2等方式命名,與實(shí)際應(yīng)用不符,所以當(dāng)時(shí)是通過HDR=No方式將所有內(nèi)容讀取到Datatable中,然后手動(dòng)將第一行設(shè)置成標(biāo)題的);IMEX ( IMport EXport
8、 mode )設(shè)置 IMEX 有三種模式: 0 is Export mode 1 is Import mode 2 is Linked mode (full update capabilities) 我這里特別要說明的就是 IMEX 參數(shù)了,因?yàn)椴煌哪J酱碇煌淖x寫行為: 當(dāng) IMEX=0 時(shí)為“匯出模式”,這個(gè)模式開啟的 Excel 檔案只能用來做“寫入”用途。 當(dāng) IMEX=1 時(shí)為“匯入模式”,這個(gè)模式開啟的 Excel 檔案只能用來做“讀取”用途。 當(dāng) IMEX=2 時(shí)為“鏈接模式”,這個(gè)模式開啟的
9、Excel 檔案可同時(shí)支援“讀取”與“寫入”用途。-另外,讀取Excel2007版本的文件時(shí),版本應(yīng)該從8.0改為12.0,同時(shí)驅(qū)動(dòng)不能再用Jet,而應(yīng)該用ACE。負(fù)責(zé)會(huì)造成“找不到可安裝的 ISAM”的錯(cuò)誤。-在網(wǎng)上還發(fā)現(xiàn)采用這種方式存在取出的Sheet表的個(gè)數(shù)多于實(shí)際Excel表中的Sheet表個(gè)數(shù)的情況,其原因有二:1. 取出的名稱中,包括了XL命名管理器中的名稱(參見XL2007的公式-命名管理器, 快捷鍵Crtl+F3);2. 取出的名稱中,包括了FilterDatabase后綴的, 這是XL用來記錄Filter范圍的。對(duì)于第一點(diǎn)比較簡(jiǎn)單, 刪除已有命名管理器中的內(nèi)容即可;第二點(diǎn)處理
10、起來比較麻煩, Filter刪除后這些名稱依然保留著,簡(jiǎn)單的做法是新增Sheet然后將原Sheet Copy進(jìn)去。但實(shí)際情況并不能為每個(gè)Excel做以上檢查。下面給出了過濾的方案。(此問題我們有驗(yàn)證過,大家自己驗(yàn)證一下吧) 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: 因?yàn)樽x取出來無效SheetName一般情況最后一個(gè)字符都不會(huì)是$。如果SheetName有一些特殊符號(hào),讀取出來的SheetName會(huì)自動(dòng)加上單引號(hào)。比如在Excel中將SheetName編輯成MySheet(1),此時(shí)讀取出來的SheetName就為:'MySh
13、eet(1)$',所以判斷最后一個(gè)字符是不是$之前最好過濾一下單引號(hào)。-(2)Com組件的方式(通過添加 Microsoft.Office.Interop.Excel引用實(shí)現(xiàn))優(yōu)點(diǎn):能夠非常靈活的讀取Excel中的數(shù)據(jù),用戶可以靈活的調(diào)用各種函數(shù)進(jìn)行處理。缺點(diǎn):基于單元格的處理,讀取速度較慢,對(duì)于數(shù)據(jù)量較大的文件最好不要使用此種方式讀取。 需要添加相應(yīng)的DLL引用,必須存在此引用才可使用,如果是Web站點(diǎn)部署在IIS上時(shí),還需要服務(wù)器機(jī)子已安裝了Excel,有時(shí)候還需
14、要為配置IIS權(quán)限。讀取代碼如下: 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: /將數(shù)據(jù)讀入到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: /負(fù)責(zé)列頭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: /將數(shù)據(jù)讀入到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: /將數(shù)據(jù)讀入到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: /負(fù)責(zé)列頭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: /判斷列名是否重復(fù) 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: /數(shù)據(jù)大于500條,使用多
28、進(jìn)程進(jìn)行讀取數(shù)據(jù) 131: if (iRowCount - 1 > 500) 132: 133: /開始多線程讀取數(shù)據(jù) 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 毫秒,保證第一個(gè)讀取 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: /主線程讀取剩余數(shù)據(jù) 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: /將多個(gè)線程讀取出來的數(shù)據(jù)追加至 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: /將數(shù)據(jù)讀入到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(此方法未經(jīng)過測(cè)試)NPOI 是 POI 項(xiàng)目的 .NET 版本。POI是一個(gè)開源的Java讀寫Excel、WORD等微軟OLE2組件文檔的項(xiàng)目。使用 NPOI 你就可以在沒有安裝 Office 或者相應(yīng)環(huán)境的機(jī)器上對(duì) WORD/EXCEL 文檔進(jìn)行讀寫。優(yōu)點(diǎn):讀
39、取Excel速度較快,讀取方式操作靈活性缺點(diǎn):需要下載相應(yīng)的插件并添加到系統(tǒng)引用當(dāng)中。 1: / <summary> 2: / 將excel中的數(shù)據(jù)導(dǎo)入到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等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 預(yù)防傳染病主題班會(huì)課件
- 水肌酸產(chǎn)品項(xiàng)目規(guī)劃設(shè)計(jì)方案(參考模板)
- 鄉(xiāng)鎮(zhèn)機(jī)關(guān)管理制度
- 吳起采油廠人執(zhí)勤點(diǎn)工程頤園樣本
- 物業(yè)員工工作計(jì)劃
- 2025年微波等離子炬光譜儀項(xiàng)目合作計(jì)劃書
- 2025年藥品及醫(yī)療器械批發(fā)服務(wù)項(xiàng)目建議書
- 物業(yè)的服務(wù)規(guī)定規(guī)定合同(物業(yè)的服務(wù)公司的)
- 博物館解決方案方案
- 2025年試驗(yàn)機(jī)械相關(guān)檢測(cè)儀器合作協(xié)議書
- 2023年小學(xué)數(shù)學(xué)必背定義和公式
- 2023年四川省宜賓市全科醫(yī)學(xué)專業(yè)實(shí)踐技能測(cè)試卷(含答案)
- 電梯井道腳手架施工方案
- 興平市生活垃圾焚燒發(fā)電項(xiàng)目環(huán)評(píng)報(bào)告
- 初中數(shù)學(xué)浙教版九年級(jí)上冊(cè)第4章 相似三角形4.3 相似三角形 全國公開課一等獎(jiǎng)
- 主令電器(課用)課件
- DLT 5066-2010 水電站水力機(jī)械輔助設(shè)備系統(tǒng)設(shè)計(jì)技術(shù)規(guī)定
- 湘少版英語六年級(jí)下冊(cè)全冊(cè)教案
- 測(cè)繪生產(chǎn)困難類別細(xì)則及工日定額
- 湖南省長(zhǎng)郡中學(xué)“澄池”杯數(shù)學(xué)競(jìng)賽初賽試題(掃描版含答案)
- 消防系統(tǒng)施工總進(jìn)度計(jì)劃
評(píng)論
0/150
提交評(píng)論