需在不開啟 Excel 應用程式的情況下,讀取 `.xls`/`.xlsx` 檔案的資料表名稱與欄位結構。本文示範使用 OleDbConnection.GetOleDbSchemaTable 方法,配合 OleDbSchemaGuid.Tables 與 Columns 列舉,快速取得中繼資料,同樣適用於 Access 等 OleDb 資料源。
.xls (Excel 97-2003)
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\path\file.xls;Extended Properties="Excel 8.0;HDR=YES;IMEX=1";
.xlsx (Excel 2007+)
Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\path\file.xlsx;Extended Properties="Excel 12.0 Xml;HDR=YES;IMEX=1";
關鍵參數:HDR=YES 第一列為標題,IMEX=1 混合型別欄位以文字讀取避免截斷。
using System;
using System.Data;
using System.Data.OleDb;
public static void PrintExcelSchema(string filePath)
{
string connStr = $@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={filePath};Extended Properties='Excel 12.0 Xml;HDR=YES;IMEX=1';";
using (var conn = new OleDbConnection(connStr))
{
conn.Open();
// 1. 取得所有資料表(工作表/命名範圍)
DataTable tables = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
foreach (DataRow tRow in tables.Rows)
{
string tableName = tRow["TABLE_NAME"].ToString(); // 例如 "Sheet1$", "MyRange"
Console.WriteLine($"資料表:{tableName}");
// 2. 取得該資料表欄位結構
// restrictions: null, null, tableName, null
DataTable columns = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, new object[] { null, null, tableName, null });
foreach (DataRow cRow in columns.Rows)
{
string colName = cRow["COLUMN_NAME"].ToString();
string dataType = cRow["DATA_TYPE"].ToString(); // OleDbType 代碼
int maxLen = Convert.ToInt32(cRow["CHARACTER_MAXIMUM_LENGTH"]);
bool isNullable = Convert.ToBoolean(cRow["IS_NULLABLE"]);
Console.WriteLine($" 欄位:{colName,-20} 型別:{dataType,-6} 長度:{maxLen,-4} 可空:{isNullable}");
}
}
}
}
資料表:Sheet1$
欄位:ID 型別:3 長度:255 可空:False
欄位:Name 型別:130 長度:255 可空:True
欄位:BirthDate 型別:7 長度:0 可空:True
資料表:Sheet2$
...
| 問題 | 原因 | 解決 |
|---|---|---|
| 找不到 Provider | 未安裝 Access Database Engine | 下載安裝 Microsoft Access Database Engine 2016 Redistributable (x64 版搭配 64 位元程式) |
| 工作表名稱帶 `$` 或 `'` | Excel 工作表慣例 | 查詢時直接使用 TABLE_NAME 回傳值,不要手動去符號 |
| 欄位型別顯示數字代碼 | OleDbType 列舉值 | 對照 OleDbType 列舉轉換為可讀名稱 |
| 混合型別欄位讀取錯誤 | 前幾列為數字,後來出現文字 | 加上 IMEX=1 強制文字模式 |
// 主鍵
DataTable pk = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Primary_Keys, new object[] { null, null, tableName });
// 索引
DataTable idx = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Indexes, new object[] { null, null, tableName });
GetOleDbSchemaTable 是標準 OleDb 介面,不依賴 Excel Interop,適合伺服器端無人值守程式、資料匯入驗證、動態建立資料庫結構等場景。記得釋放連線,並正確處理 32/64 位元 Provider 相容性。