亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

C#讀取Excel的三種方式以及比較分析

2020-01-24 01:23:42
字體:
來源:轉載
供稿:網友

(1)OleDB方式

優點:將Excel直接當做數據源處理,通過SQL直接讀取內容,讀取速度較快。

缺點:讀取數據方式不夠靈活,無法直接讀取某一個單元格,只有將整個Sheet頁讀取出來后(結果為Datatable)再在Datatable中根據行列數來獲取指定的值。

當Excel數據量很大時。會非常占用內存,當內存不夠時會拋出內存溢出的異常。

讀取代碼如下:

 public DataTable GetExcelTableByOleDB(string strExcelPath, string tableName) {   try   {     DataTable 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.Rows[0][2].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.Tables[tableName];     return dtExcel;   }   catch   {     return 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做以上檢查。下面給出了過濾的方案。(此問題我們有驗證過,大家自己驗證一下吧)

 //objConn為讀取Excel的鏈接,下面通過過濾來獲取有效的Sheet頁名稱集合  System.Data.DataTable schemaTable = objConn.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, null);  List<string> lstSheetNames = new List<string>();  for (int i = 0; i < schemaTable.Rows.Count; i++)  {    string strSheetName = (string)dtSheetName.Rows[i]["TABLE_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權限。

讀取代碼如下:

 private Stopwatch wath = new Stopwatch(); /// <summary> /// 使用COM讀取Excel /// </summary> /// <param name="excelFilePath">路徑</param> /// <returns>DataTabel</returns> public 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();   try   {     if (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;     //負責列頭Start     DataColumn dc;     int ColumnID = 1;     range = (Excel.Range)worksheet.Cells[1, 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.Cells[1, ++ColumnID];     }     //End     for (int iRow = 2; iRow <= iRowCount; iRow++)     {       DataRow dr = dt.NewRow();       for (int iCol = 1; iCol <= iColCount; iCol++)       {         range = (Excel.Range)worksheet.Cells[iRow, iCol];         cellContent = (range.Value2 == null) ? "" : range.Text.ToString();           dr[iCol - 1] = cellContent;       }       dt.Rows.Add(dr);     }     wath.Stop();     TimeSpan ts = wath.Elapsed;     //將數據讀入到DataTable中――End     return dt;   }   catch   {     return null;   }   finally   {     workbook.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();   } } /// <summary> /// 使用COM,多線程讀取Excel(1 主線程、4 副線程) /// </summary> /// <param name="excelFilePath">路徑</param> /// <returns>DataTabel</returns> public 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();   try   {     if (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;     //負責列頭Start     DataColumn dc;     int ColumnID = 1;     range = (Excel.Range)worksheet.Cells[1, 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 < ColumnID; i++)       {         if (dt.Columns[i - 1].ColumnName == strNewColumnName)           strNewColumnName = strNewColumnName + "_1";       }       dc.ColumnName = strNewColumnName;       dt.Columns.Add(dc);       range = (Excel.Range)worksheet.Cells[1, ++ColumnID];     }     //End     //數據大于500條,使用多進程進行讀取數據     if (iRowCount - 1 > 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 毫秒,保證第一個讀取 dt1       Thread.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.Cells[iRow, iCol];           cellContent = (range.Value2 == null) ? "" : range.Text.ToString();           dr[iCol - 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;     }     else     {       for (int iRow = 2; iRow <= iRowCount; iRow++)       {         DataRow dr = dt.NewRow();         for (int iCol = 1; iCol <= iColCount; iCol++)         {           range = (Excel.Range)worksheet.Cells[iRow, iCol];           cellContent = (range.Value2 == null) ? "" : range.Text.ToString();           dr[iCol - 1] = cellContent;         }         dt.Rows.Add(dr);       }     }     wath.Stop();     TimeSpan ts = wath.Elapsed;     //將數據讀入到DataTable中――End     return dt;   }   catch   {     return null;   }   finally   {     workbook.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速度較快,讀取方式操作靈活性

缺點:需要下載相應的插件并添加到系統引用當中。

 /// <summary> /// 將excel中的數據導入到DataTable中 /// </summary> /// <param name="sheetName">excel工作薄sheet的名稱</param> /// <param name="isFirstRowColumn">第一行是否是DataTable的列名</param> /// <returns>返回的DataTable</returns> public DataTable ExcelToDataTable(string sheetName, bool isFirstRowColumn) {   ISheet sheet = null;   DataTable data = new DataTable();   int startRow = 0;   try   {     fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);     if (fileName.IndexOf(".xlsx") > 0) // 2007版本       workbook = new XSSFWorkbook(fs);     else if (fileName.IndexOf(".xls") > 0) // 2003版本       workbook = new HSSFWorkbook(fs);     if (sheetName != null)     {       sheet = workbook.GetSheet(sheetName);     }     else     {       sheet = workbook.GetSheetAt(0);     }     if (sheet != null)     {       IRow firstRow = sheet.GetRow(0);       int cellCount = firstRow.LastCellNum; //一行最后一個cell的編號 即總的列數       if (isFirstRowColumn)       {         for (int i = firstRow.FirstCellNum; i < cellCount; ++i)         {           DataColumn column = new DataColumn(firstRow.GetCell(i).StringCellValue);           data.Columns.Add(column);         }         startRow = sheet.FirstRowNum + 1;       }       else       {         startRow = sheet.FirstRowNum;       }       //最后一列的標號       int rowCount = sheet.LastRowNum;       for (int i = startRow; i <= rowCount; ++i)       {         IRow row = sheet.GetRow(i);         if (row == null) continue; //沒有數據的行默認是null                         DataRow dataRow = data.NewRow();         for (int j = row.FirstCellNum; j < cellCount; ++j)         {           if (row.GetCell(j) != null) //同理,沒有數據的單元格都默認是null             dataRow[j] = row.GetCell(j).ToString();         }         data.Rows.Add(dataRow);       }     }     return data;   }   catch (Exception ex)   {     Console.WriteLine("Exception: " + ex.Message);     return null;   } }

下面是一些相關的文章,大家可以參考下

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
中文字幕亚洲无线码a| 狠狠躁夜夜躁久久躁别揉| 久久999免费视频| 日韩精品极品在线观看播放免费视频| 午夜剧场成人观在线视频免费观看| 亚洲精品视频中文字幕| 丝袜美腿亚洲一区二区| 国产主播喷水一区二区| 亚洲国产精品成人va在线观看| 高清欧美一区二区三区| 亚洲国产中文字幕在线观看| 狠狠干狠狠久久| 国产女人精品视频| 国产+成+人+亚洲欧洲| 国产成人免费91av在线| 国产精品一区二区女厕厕| 精品中文字幕在线2019| 亚洲欧美中文日韩在线v日本| 欧美精品在线免费播放| 91色在线视频| 国产成人久久精品| 久久久久99精品久久久久| 91免费欧美精品| 亚洲欧美综合精品久久成人| 日本精品在线视频| 亚洲人成网站999久久久综合| 欧美日韩电影在线观看| 亚洲xxxx3d| 一区二区亚洲欧洲国产日韩| 国产精品第100页| 91av国产在线| 全亚洲最色的网站在线观看| 欧美日韩国产va另类| 国产欧美精品在线播放| 日韩成人在线播放| 欧美激情一区二区三区在线视频观看| 一区二区三区四区精品| 在线视频精品一| 国产精品久久久久久久午夜| 成人综合国产精品| 理论片在线不卡免费观看| 高清一区二区三区日本久| 欧美一级淫片videoshd| 欧美电影在线播放| 亚洲色图在线观看| 色哟哟入口国产精品| 日韩美女主播视频| 97在线看免费观看视频在线观看| 亚洲精品国产成人| 亚洲精品国产综合区久久久久久久| 欧美肥老太性生活视频| 成人激情av在线| 国产在线日韩在线| 中文字幕在线成人| 久久精品国产久精国产思思| 亚洲黄色免费三级| 久久五月天综合| 久久夜精品香蕉| 国产成人精品免高潮在线观看| 亚洲最大的成人网| 91精品视频在线免费观看| 色综久久综合桃花网| 狠狠久久亚洲欧美专区| 欧美精品在线视频观看| 91精品综合视频| 91国在线精品国内播放| 综合av色偷偷网| 久久久久久久久综合| 欧洲中文字幕国产精品| 色偷偷偷综合中文字幕;dd| 欧美成人午夜激情在线| 欧美日韩中国免费专区在线看| 91久久国产综合久久91精品网站| 午夜精品久久久99热福利| 综合网日日天干夜夜久久| 国产成人97精品免费看片| 欧美丰满老妇厨房牲生活| 中文字幕一区二区三区电影| 精品丝袜一区二区三区| 欧美电影免费观看网站| 欧美激情伊人电影| 亚洲精品国产精品国产自| 最新91在线视频| 国产91精品久久久| 影音先锋欧美在线资源| 欧美精品在线播放| 午夜精品蜜臀一区二区三区免费| 狠狠色狠狠色综合日日小说| 久久久亚洲精选| 日韩网站免费观看高清| 最近日韩中文字幕中文| 色yeye香蕉凹凸一区二区av| 欧美视频一二三| 亚洲欧美一区二区三区在线| 狠狠爱在线视频一区| 国产欧美 在线欧美| 中文字幕亚洲综合久久| 日韩经典中文字幕| 欧美日韩中文字幕日韩欧美| 亚洲国产精品嫩草影院久久| 国产精品久久视频| 热re91久久精品国99热蜜臀| 亚洲精品国产福利| 美女扒开尿口让男人操亚洲视频网站| 午夜精品久久17c| 国产中文日韩欧美| 久久影视电视剧凤归四时歌| 57pao国产成人免费| 九九热精品视频在线播放| 8x海外华人永久免费日韩内陆视频| 欧美在线视频网| 在线观看视频99| 久久久久成人精品| 国产69精品久久久| 精品中文字幕在线2019| 欧美激情精品久久久久久久变态| 欧美视频一区二区三区…| 欧洲美女7788成人免费视频| 久久精品中文字幕一区| 欧美日韩免费观看中文| 一区二区三区四区在线观看视频| 日韩精品在线第一页| 国产精品久久久久久一区二区| 欧美电影在线观看网站| 欧美人与性动交a欧美精品| 成人免费观看网址| 国产精品99导航| 亚洲欧美日韩天堂一区二区| 国产精品h在线观看| 97国产在线观看| 国产精品99一区| 日韩激情视频在线| 欧美电影免费观看高清| 久久久女女女女999久久| 亚洲天堂色网站| 成人网在线免费看| 欧美性少妇18aaaa视频| 亚洲自拍高清视频网站| 日韩电影在线观看免费| 欧美日韩免费区域视频在线观看| 日韩中文字幕视频| 国产精品一区二区久久精品| 69av在线播放| 日韩成人在线视频观看| 欧美精品一区三区| 97精品欧美一区二区三区| 欧美精品在线免费| 九九精品视频在线观看| 欧美激情网友自拍| 亚洲精品少妇网址| 久久视频在线免费观看| 亚洲成人精品视频| 国产精彩精品视频| 久久久久久久亚洲精品| 欧美日韩国产激情| 日韩二区三区在线| 97精品视频在线播放| 欧美亚洲在线视频| 亚洲激情小视频| 久久久久久久久久久国产| 亚洲一区二区三区香蕉| 国产精品视频久| 国产精品主播视频| 日韩在线视频免费观看|