首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

C# / ASP.NET 實作 Excel 匯入資料庫完整教學 (OleDb 方案)

     編輯:關於SqlServer

技術棧與適用場景

  • 環境: C# 2.0 / .NET Framework 2.0+、Microsoft Access (.mdb) 或 SQL Server
  • 核心元件: System.Data.OleDb、Microsoft Jet OLEDB 4.0 Provider
  • 適用場景: 中小型檔案匯入、離線資料同步、舊系統維護

核心流程三步驟

1. 讀取 Excel → DataTable

public static DataTable ExcelToDataTable(string filePath, string sheetName)
{
    // Excel 97-2003 (.xls) 連接字串
    string connStr = $@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={filePath};Extended Properties='Excel 8.0;HDR=YES;IMEX=1;'";
    
    // Excel 2007+ (.xlsx) 需改用 ACE Provider:
    // string connStr = $@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={filePath};Extended Properties='Excel 12.0 Xml;HDR=YES;IMEX=1;'";
    
    string query = $"SELECT * FROM [{sheetName}$]"; // 工作表名需加 $ 符號
    
    using (OleDbConnection conn = new OleDbConnection(connStr))
    using (OleDbDataAdapter adapter = new OleDbDataAdapter(query, conn))
    {
        DataTable dt = new DataTable();
        adapter.Fill(dt);
        return dt;
    }
}

關鍵參數說明:

  • HDR=YES:第一行為標題列;HDR=NO 則視為資料,欄位名自動產生 F1、F2...。
  • IMEX=1:混合模式,強制將混合型態欄位視為文字讀取,避免數值欄位前幾行為數字後面出現文字導致讀取為 NULL。

2. DataTable 逐筆寫入 Access / SQL Server

public static void DataTableToAccess(DataTable dt, string accessConnStr)
{
    string sql = "INSERT INTO tb_ExcelData (strColumn1, fColumn2) VALUES (@p1, @p2)";
    
    using (OleDbConnection conn = new OleDbConnection(accessConnStr))
    using (OleDbCommand cmd = new OleDbCommand(sql, conn))
    {
        // 參數化查詢防注入、處理型別轉換
        cmd.Parameters.Add("@p1", OleDbType.VarWChar, 50);
        cmd.Parameters.Add("@p2", OleDbType.Double);
        
        conn.Open();
        foreach (DataRow row in dt.Rows)
        {
            cmd.Parameters["@p1"].Value = row[0]?.ToString() ?? string.Empty;
            cmd.Parameters["@p2"].Value = Convert.ToDouble(row[1] ?? 0);
            cmd.ExecuteNonQuery();
        }
    }
}

3. 整合呼叫範例

public static void ImportExcelToDb(string excelPath, string sheetName, string targetConnStr)
{
    DataTable dt = ExcelToDataTable(excelPath, sheetName);
    DataTableToAccess(dt, targetConnStr); // 或改寫為 SqlConnection 寫入 SQL Server
}

進階優化與避坑指南

大量資料效能優化

  • 批次更新: 改用 OleDbDataAdapter.UpdateBatchSize 或 SqlBulkCopy (SQL Server 專用) 替換逐筆 ExecuteNonQuery,效能提升 10-100 倍。
  • 交易控制: 包裹在 TransactionScope 或 OleDbTransaction 中,失敗回滾保證資料一致性。

常見問題排查

錯誤現象原因解決方案
External table is not in the expected formatProvider 版本不匹配 (.xls 用 Jet, .xlsx 用 ACE)依副檔名切換 Provider,確認目標機器已安裝對應 Access Database Engine (32/64 位元需與應用程式一致)
數值欄位讀出為 NULL前 8 行 (預設掃描範圍) 為數字,後出現文字連接字串加 IMEX=1;或修改註冊表 TypeGuessRows=0 掃描全表
中文欄位名亂碼/錯誤OleDb 不支援中文欄位名稱當參數查詢時用別名 SELECT [中文欄位] AS Col1,或程式端用索引 row[0] 存取
伺服器部署失敗IIS 應用程式集區啟用 32 位元應用程式設定不匹配應用程式集區 → 進階設定 → 啟用 32 位元應用程式 = True (若安裝 32-bit ACE)

現代化替代方案推薦

新專案建議使用 ClosedXML、EPPlus (商業需授權) 或 NPOI 純 .NET 程式庫直接解析 .xlsx (OpenXML 格式),無需安裝 Office/ACE 驅動程式,支援 Linux/Docker 容器化部署,記憶體佔用更可控,語法更現代化:

// EPPlus 範例
using (var package = new ExcelPackage(new FileInfo("data.xlsx")))
{
    var ws = package.Workbook.Worksheets[0];
    foreach (var row in ws.Cells[2, 1, ws.Dimension.End.Row, ws.Dimension.End.Column].Rows)
    {
        var col1 = row[0].Text;
        var col2 = row[1].GetValue<double>();
        // 直接寫入 DB...
    }
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved