SELECT * FROM [Sheet1$]
但當我使用較新的中文版 Excel 時,Excel 裡的 Sheet 名稱預設是 「工作表1」,如此我就得將上面的 SQL 語法改成
SELECT * FROM [工作表1$]
一旦開放讓使用者自行上傳 Excel 檔案以供讀取檔案內容時,我怎麼知道裡面的 Excel 內容是 Sheet1 還是 工作表1 呢?
遇到這兩難的情況時,可以試試 OleDbConnection 類別裡的 GetSchema() 方法,他可以回傳資料來源的結構描述資訊,其回傳的資料格式為 DataTable。接著就可以透過這 DataTable 來判斷使用者所上傳的 Excel 的 Sheet 名稱到底是叫「阿貓」還是「阿狗」了。我試著將這 DataTable 的內容整理如下,就可以很清楚的瞭解裡頭到底藏了些什麼內容。
透過上面的圖表,可以發現 GetSchema()所回傳的 DataTable 裡頭,有一個欄位 TABLE_NAME 。他主要是紀錄著 Excel 裡面每一個 Sheet 的名稱。如果我只需關心第一個 Sheet 的名稱,那只要取第一筆 TABLE_NAME 就可以正確得到我想要的資訊了。
試著完成讀取 Excel 內容的程式碼就如下所示:
protected void btnImport_Click(object sender, EventArgs e) { DataTable tablesInFile; string currentTable; string xlsFullName = Server.MapPath("Test.xlsx"); string OleConStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + xlsFullName + ";Extended Properties='Excel 12.0 Xml;HDR=No;IMEX=1'"; OleDbConnection OleCn = new OleDbConnection(OleConStr); OleDbCommand OleCmd = new OleDbCommand(); OleCmd.Connection = OleCn; try { OleCn.Open(); //透過 GetSchema 取得資料來源的結構描述資訊 tablesInFile = OleCn.GetSchema("Tables"); //只取第一筆 Sheet 名稱 DataRow tableInFile = tablesInFile.Rows[0]; currentTable = tableInFile["TABLE_NAME"].ToString(); //調整後的 SQL 語法 string strSQL = string.Format(@"SELECT * FROM [{0}]", currentTable); OleCmd.CommandText = strSQL; DataSet ds = new DataSet(); OleDbDataAdapter odda = new OleDbDataAdapter(strSQL, OleCn); odda.Fill(ds, currentTable); OleCn.Close(); odda.Dispose(); } catch(Exception ex) { } }
參考:
01:OleDbConnection.GetSchema 方法
02:以指令碼工作處理 Excel 檔案
沒有留言:
張貼留言