今天學習的是從FTP上下載Excel文件,DataTable接收數據之后,在DataTable中通過篩選,刪減修改之后把數據插入到DB相應表中。
優點:讀取方式簡單、讀取速度快
缺點:除了讀取過程不太靈活之外,這種讀取方式還有個弊端就是,當Excel數據量很大時。會非常占用內存,當內存不夠時會拋出內存溢出的異常。
命名空間:using System.Data.OleDb;
另注:
參數:HDR=NO/YES
OleDb讀入一個Excel工作表(Sheet)的數據后,工作表的第一行會變成標題,第二行起,逐行變為DataTable的一個數據行(Row)
以下是代碼:
//根據excle的路徑把第一個sheel中的內容放入datatable public static DataTable ReadExcelToTable(string path)//excel存放的路徑 { try { //連接字符串 string connstring = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties='Excel 8.0;HDR=NO;IMEX=1';"; // Office 07及以上版本 不能出現多余的空格 而且分號注意 //string connstring = Provider=Microsoft.JET.OLEDB.4.0;Data Source=" + path + ";Extended Properties='Excel 8.0;HDR=NO;IMEX=1';"; //Office 07以下版本 using (OleDbConnection conn = new OleDbConnection(connstring)) { conn.Open(); DataTable sheetsName = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "Table" }); //得到所有sheet的名字 string firstSheetName = sheetsName.Rows[0][2].ToString(); //得到第一個sheet的名字 string sql = string.Format("SELECT * FROM [{0}]", firstSheetName); //查詢字符串
//string sql = string.Format("SELECT * FROM [{0}] WHERE [日期] is not null", firstSheetName); //查詢字符串
OleDbDataAdapter ada = new OleDbDataAdapter(sql, connstring); DataSet set = new DataSet(); ada.Fill(set); return set.Tables[0]; } } catch (Exception) { return null; } }
項目中還可以結合流文件(fileStream)的操作,檢查每一行數據,數據類型等,一行一行的插入到DB的表,使用DataTable的目的就是為了檢查excel的行列數(主要是列數)是否符合要求,比如今天的測試中,
網友有個說法:string sqlExcel = ("select * from [計划上sheet$A3:D8]"); sheet$后面是范圍A3到D8的 如果行不確定 要取到后面行 就把D8改成D
后來看到的,所以還沒測試,
以上這個問題我也在想,是不是excel里面sheet的活動界面的問題,select * from [sheetName]選取了所有的列數,所以導致可能DaTaTable導致空列,建議在DaTaTable進行刪改,或者用datagrid修改,隨后保存修改到DATATABLE中。
對於其他的excel讀取方式,參見博客地址:http://www.cnblogs.com/icyJ/p/ReadExcel.html
另外對於參數connstring字符串的標准,
1)HDR表示要把第一行作為數據還是作為列名,作為數據用HDR=no,作為列名用HDR=yes;
使用 Excel 工作簿時,默認情況下,區域中的第一行是標題行(或字段名稱)。如果第一個區域不包含標題,您可以在連接字符串的擴展屬性中指定 HDR=NO。如果您在連接字符串中指定 HDR=NO,Jet OLE DB 提供程序將自動為您命名字段(不管excel中的列叫什么名字,F1 表示第一個字段,F2 表示第二個字段,依此類推,select F1,F2 from [sheet1$]);
2)IMEX=1將所有讀入數據看作字符,其他值(0、2)請查閱相關幫助文檔;
3)如果出現“找不到可安裝的isam”錯誤,一般是連接字符串錯誤
string connstring = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties='Excel 8.0;HDR=NO;IMEX=1';";
HDR表示要把第一行作為數據還是作為列名,作為數據用HDR=no,作為列名用HDR=yes;
string connstring = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties='Excel 8.0;HDR=YES;IMEX=1';";
接着繼續:
這里出現的問題是:
很容易造成讀入很多的空行到datatable中,比如下面的excel,我們基本上看不出到底有多少實際的行數:
string sql = string.Format("SELECT * FROM [{0}]", firstSheetName); //查詢字符串
string sql = string.Format("SELECT * FROM [{0}] WHERE [日期] is not null", firstSheetName); //查詢字符串,字段名注意一定要和excel中標題名一致,有空格哦~
note:這時HDR參數必須是YES,否則會報異常
參考:http://www.devba.com/index.php/archives/4024.html
Excel讀取存在空白的原因:表格有兩個后台屬性,分別是已使用的最大行數和已使用的最大列數。這個 adapter可能是按這兩個屬性來的,沒法改。讀取代碼部分如圖所示,圖示為主要解析Excel到DataTable.經過仔細監視代碼我們會發現在 da.Fill(dt)時,把空白行填充到DataTable了。總體來講這個是有微軟提供的方法和規則,那么是沒辦法改的。
解決辦法有以下幾個:
1、在讀取的時候SQL語句上進行過濾:Select * From SheetName where col1 is not null and col2 is not null 在讀取的過程時,對空白行進行非空顧慮,建議過濾非空時,根據業務,把不可為空的Excel中的列作為col1和col2;當然可以先刪除空白行后再進行 讀取;總之先把空白行在讀取到Excel前除掉;
2、在讀取Excel到DataTable后再過濾掉空白行;DataTable空白行處理空白行方法應該很多的;但是在進行業務校驗的時候一定需要先刪除空白行!