首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> 關於ASP.NET

讀取 Excel 混合型別欄位出現 Null 解決方案:IMEX=1 與 TypeGuessRows 完整說明

     編輯:關於ASP.NET

使用 `Microsoft.Jet.OLEDB.4.0` / `Microsoft.ACE.OLEDB.12.0` 讀取 Excel 時,欄位前幾列為數字、後續混入文字會導致文字讀為 `null`。根因:OLEDB 驅動程式預設掃描前 8 列 (`TypeGuessRows=8`) 推斷型別,數字佔多數則整欄視為數值型,不符合者捨棄為 `DBNull`。

雙重解決方案 (必須同時奏效)

1. 連接字串加入 `IMEX=1` (關鍵)


string connStr = @"Provider=Microsoft.ACE.OLEDB.12.0; 
    Data Source=" + filePath + @";
    Extended Properties='Excel 12.0 Xml;HDR=YES;IMEX=1;'";
  • HDR=YES:第一列為標題
  • IMEX=1:強制混合型欄位視為文字 (Import Mixed Types),解決型別衝突導致資料遺失
  • IMEX 參數值:`0`=匯出模式、`1`=匯入混合模式、`2`=匯入嚴格模式

2. 登錄檔修改 `TypeGuessRows = 0` (掃描全欄)

路徑 (視 Office 位元數與版本):

  • 32 位元 Office / 64 位元系統 WoW64:
    `HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Office\16.0\Access Connectivity Engine\Engines\Excel\TypeGuessRows`
  • 64 位元 Office:
    `HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\16.0\Access Connectivity Engine\Engines\Excel\TypeGuessRows`
  • 舊版 Jet 4.0:
    `HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Excel\TypeGuessRows`

將值從 `8` 改為 `0` (掃描所有列決定型別) 或較大數值 (如 `1000`)。

原理深度解析

  1. 驅動程式讀取前 N 列 (N = TypeGuessRows)
  2. 統計每欄型別出現次數:數值、文字、日期、布林、錯誤
  3. 佔多數者成為該欄「決定型別」
  4. 後續列資料若不符合決定型別 → 回傳 `DBNull.Value`

範例:前 8 列 5 個數字 + 3 個文字 → 決定型別 = 數值 → 第 9 列文字變 `null`

驗證步驟

  1. 修改登錄檔 `TypeGuessRows=0`
  2. 連接字串加 `IMEX=1; HDR=YES`
  3. 重啟 IIS / 應用程式集區 (登錄檔變更需進程重啟生效)
  4. 測試讀取混合型別欄位,確認文字不再為 `null`

進階:ACE OLEDB 12.0/16.0 相容 .xlsx (必要)

Jet 4.0 **不支援 .xlsx**,必須使用 ACE:


// .xlsx (Excel 2007+)
Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties='Excel 12.0 Xml;HDR=YES;IMEX=1;'

// .xls (Excel 97-2003)
Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties='Excel 8.0;HDR=YES;IMEX=1;'

生產環境部署需安裝 **Microsoft Access Database Engine 2016 Redistributable** (含 ACE 16.0),並設定應用程式集區「啟用 32 位元應用程式 = True」(若用 32 位元 ACE)。

現代替代方案:免驅動、跨平台、強型別

ClosedXML 讀取混合型別範例 (無型別推斷問題)


using ClosedXML.Excel;

var workbook = new XLWorkbook(filePath);
var worksheet = workbook.Worksheet(1);
var rows = worksheet.RowsUsed().Skip(1); // 跳過標題

foreach (var row in rows)
{
    // 直接取得字串,自動處理數字/日期/文字轉換
    string colA = row.Cell(1).GetString(); 
    string colB = row.Cell(2).GetString();
    // 或取得型別化值
    var val = row.Cell(1).Value; // XLCellValue (可隱式轉換)
}

總結

**OLEDB 方案必做兩件事**:連接字串 `IMEX=1` + 登錄檔 `TypeGuessRows=0`。新專案**強烈建議改用 ClosedXML/NPOI/EPPlus**,徹底擺脫驅動程式相依、位元數衝突、登錄檔修改、權限問題,並獲得更豐富的 API 與型別安全。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
庫優點適用場景
EPPlus (商業授權)功能最完整、效能佳、支援公式/圖表/樣式企業級報表、複雜匯出
ClosedXML (MIT)API 直覺、支援 .xlsx、免費一般匯入匯出
NPOI (Apache)支援 .xls/.xlsx、跨平台、免費Linux/容器環境、舊格式相容
ExcelDataReader唯讀、串流、記憶體效率高大檔案匯入、ETL