C# 中讀取 Excel 檔案的最佳方法 | IronXL 逐步指南
在C#中讀取Excel文件是.NET開發者常見的挑戰。 無論您是在建立資料匯入管道、報告工具還是批次處理系統,乾淨地解析電子表格資料非常重要。 IronXL是一個.NET程式庫,可以處理XLSX、XLS和CSV文件,而無需伺服器上安裝Microsoft Office或COM互操作。 本指南涵蓋了從安裝到進階查詢的完整工作流程,讓您可以為您的專案選擇適合的方法。
在C#中讀取Excel文件的最佳方法是什麼?
最好的方法是使用像IronXL這樣獨立於Office的專用程式庫。 傳統方法如Microsoft.Office.Interop.Excel適用於安裝了Excel的計算機,但在伺服器或容器環境中容易出錯,因為它們會在後台啟動COM進程。 OpenXML SDK是免費且伺服器安全的,但它暴露了一個低層級的XML模型,需要相當多的樣板程式碼來完成日常任務。
IronXL則位於這些極端之間。 API模仿開發者對電子表格的已有思維模式--工作簿包含工作表、工作表包含單元格,單元格持有型別化的值。 程式庫內部處理格式檢測、公式計算和編碼,因此您可以專注於商業邏輯,而不是解析細節。
| 方法 | 需要Office嗎? | 伺服器安全嗎? | API簡單度 | 格式支援 |
|---|---|---|---|---|
| COM互操作 | 是 | 否 | 低 | XLSX, XLS |
| OpenXML SDK | 否 | 是 | 低 | 僅限XLSX |
| IronXL | 否 | 是 | 高 | XLSX, XLS, CSV |
IronXL的Excel閱讀文件涵蓋了完整的API範圍。 目前,以下部分顯示了您在每個專案中將使用的核心模式。
如何在.NET專案中安裝IronXL?
使用NuGet套件管理器安裝僅需不到一分鐘。 在專案目錄中打開終端並運行:
dotnet add package IronXL.Excel
或者,使用Visual Studio套件管理器控制台:
Install-Package IronXL.Excel
安裝後,將using IronXL;指令新增到需要電子表格存取的任何文件中。 程式庫針對.NET 10、.NET 8、.NET 6、.NET Framework 4.6.2和.NET Standard 2.0,適合現有專案而不升級運行時。請參閱IronXL安裝指南,了解平台特定的注意事項和NuGet套件詳細資訊。
無需其他運行時組件、註冊表項或Office授權。 NuGet套件包含了程式庫所需的一切。
驗證安裝
新增套件後,構建專案一次以確認引用正確解析。 如果您看到.csproj目標框架為受支持的版本之一。 IronXL相容性矩陣列出了所有確認的運行時目標。
如何載入和讀取Excel工作簿?
載入工作簿只需一個方法呼叫。 WorkBook物件,表示記憶體中的整個文件。
using IronXL;
// Load any supported format -- XLSX, XLS, or CSV
WorkBook workbook = WorkBook.Load("financial_report.xlsx");
// Access the first worksheet by position
WorkSheet worksheet = workbook.WorkSheets[0];
// Or retrieve a named worksheet
WorkSheet expenses = workbook.GetWorkSheet("Expenses");
Console.WriteLine($"Sheets loaded: {workbook.WorkSheets.Count}");
Console.WriteLine($"Default sheet rows: {worksheet.RowCount}");
using IronXL;
// Load any supported format -- XLSX, XLS, or CSV
WorkBook workbook = WorkBook.Load("financial_report.xlsx");
// Access the first worksheet by position
WorkSheet worksheet = workbook.WorkSheets[0];
// Or retrieve a named worksheet
WorkSheet expenses = workbook.GetWorkSheet("Expenses");
Console.WriteLine($"Sheets loaded: {workbook.WorkSheets.Count}");
Console.WriteLine($"Default sheet rows: {worksheet.RowCount}");
Imports IronXL
' Load any supported format -- XLSX, XLS, or CSV
Dim workbook As WorkBook = WorkBook.Load("financial_report.xlsx")
' Access the first worksheet by position
Dim worksheet As WorkSheet = workbook.WorkSheets(0)
' Or retrieve a named worksheet
Dim expenses As WorkSheet = workbook.GetWorkSheet("Expenses")
Console.WriteLine($"Sheets loaded: {workbook.WorkSheets.Count}")
Console.WriteLine($"Default sheet rows: {worksheet.RowCount}")

WorkBook物件保持所有工作表資料可存取。 每個WorkSheets[0])存取對於單一工作表文件可靠; 當文件包含多個已知名稱的標籤時,按名稱存取更安全。
IronXL在您讀取單元格時自動計算公式。 如果單元格sheet["B10"].DecimalValue返回計算的總和,而不是公式字串。 有關工作簿載入選項的更多詳細資訊,請參閱載入電子表格操作指南。
處理多個工作表
當工作簿包含多個標籤時,您可以使用workbook.WorkSheets枚舉它們,依次處理每個標籤。 這對於按月、部門或地區在不同標籤上分割資料的文件非常有用。 WorkSheet.Name屬性為您提供了標籤標識的字串,您可以用於條件處理或記錄。
如何從工作表中讀取單元格值?
IronXL在每個單元格上提供了強型別屬性,讓您可以將值直接讀取到正確的.NET型別中,而無需手動解析。
using IronXL;
WorkBook workbook = WorkBook.Load("Products.xlsx");
WorkSheet sheet = workbook.DefaultWorkSheet;
// Address-based access with typed properties
string productName = sheet["A2"].StringValue;
int quantity = sheet["B2"].IntValue;
decimal price = sheet["C2"].DecimalValue;
bool inStock = sheet["D2"].BoolValue;
// Check for empty cells before processing
var statusCell = sheet["E2"];
if (statusCell.Value != null && statusCell.StringValue.Length > 0)
{
Console.WriteLine($"Status: {statusCell.StringValue}");
}
// Row/column index access (zero-based)
var firstDataCell = sheet.Rows[1].Columns[0];
Console.WriteLine($"Product: {productName}, Qty: {quantity}, Price: {price:C}");
using IronXL;
WorkBook workbook = WorkBook.Load("Products.xlsx");
WorkSheet sheet = workbook.DefaultWorkSheet;
// Address-based access with typed properties
string productName = sheet["A2"].StringValue;
int quantity = sheet["B2"].IntValue;
decimal price = sheet["C2"].DecimalValue;
bool inStock = sheet["D2"].BoolValue;
// Check for empty cells before processing
var statusCell = sheet["E2"];
if (statusCell.Value != null && statusCell.StringValue.Length > 0)
{
Console.WriteLine($"Status: {statusCell.StringValue}");
}
// Row/column index access (zero-based)
var firstDataCell = sheet.Rows[1].Columns[0];
Console.WriteLine($"Product: {productName}, Qty: {quantity}, Price: {price:C}");
Imports IronXL
Dim workbook As WorkBook = WorkBook.Load("Products.xlsx")
Dim sheet As WorkSheet = workbook.DefaultWorkSheet
' Address-based access with typed properties
Dim productName As String = sheet("A2").StringValue
Dim quantity As Integer = sheet("B2").IntValue
Dim price As Decimal = sheet("C2").DecimalValue
Dim inStock As Boolean = sheet("D2").BoolValue
' Check for empty cells before processing
Dim statusCell = sheet("E2")
If statusCell.Value IsNot Nothing AndAlso statusCell.StringValue.Length > 0 Then
Console.WriteLine($"Status: {statusCell.StringValue}")
End If
' Row/column index access (zero-based)
Dim firstDataCell = sheet.Rows(1).Columns(0)
Console.WriteLine($"Product: {productName}, Qty: {quantity}, Price: {price:C}")

sheet["A2"]語法使用標準的Excel符號。 列字母對大小寫不敏感,行號從1開始,與Excel標籤單元格的方式一致。 單元格值讀取文件顯示了其他型別存取器,包括用於日期格式化單元格的DateTimeValue。
當單元格包含作為文字儲存的數字(在匯出的電子表格中是一個常見的資料質量問題)時,0。 在將意外資料作為生產程式碼中的型別化值處理之前,請始終驗證。
處理日期和布林單元格
Excel中的日期單元格內部儲存為序列號。 IronXL暴露了DateTimeValue可以將它們轉換為.NET DateTime物件,而無需手動計算。 對於包含BoolValue將不比較字串而返回正確的布林值。 這些型別化存取器消除了在通過基於文字的解析器讀取電子表格時常見出現的資料型別錯誤。
如何遍歷行和單元格?
遍歷資料集需要範圍或行集合。 IronXL支持這兩種方法,您可以結合它們以匹配資料的形狀。
using IronXL;
WorkBook workbook = WorkBook.Load("financial_report.xlsx");
WorkSheet sheet = workbook.WorkSheets[0];
// Iterate a cell range -- skips header row
foreach (var cell in sheet["A2:D100"])
{
Console.WriteLine($"{cell.AddressString}: {cell.Text}");
}
// Row-by-row with column access
for (int rowIndex = 1; rowIndex < sheet.RowCount; rowIndex++)
{
var row = sheet.Rows[rowIndex];
var values = new System.Text.StringBuilder();
foreach (var cell in row)
{
if (cell.Value != null)
values.Append($"{cell.StringValue}\t");
}
Console.WriteLine(values.ToString().TrimEnd());
}
using IronXL;
WorkBook workbook = WorkBook.Load("financial_report.xlsx");
WorkSheet sheet = workbook.WorkSheets[0];
// Iterate a cell range -- skips header row
foreach (var cell in sheet["A2:D100"])
{
Console.WriteLine($"{cell.AddressString}: {cell.Text}");
}
// Row-by-row with column access
for (int rowIndex = 1; rowIndex < sheet.RowCount; rowIndex++)
{
var row = sheet.Rows[rowIndex];
var values = new System.Text.StringBuilder();
foreach (var cell in row)
{
if (cell.Value != null)
values.Append($"{cell.StringValue}\t");
}
Console.WriteLine(values.ToString().TrimEnd());
}
Imports IronXL
Imports System.Text
Dim workbook As WorkBook = WorkBook.Load("financial_report.xlsx")
Dim sheet As WorkSheet = workbook.WorkSheets(0)
' Iterate a cell range -- skips header row
For Each cell In sheet("A2:D100")
Console.WriteLine($"{cell.AddressString}: {cell.Text}")
Next
' Row-by-row with column access
For rowIndex As Integer = 1 To sheet.RowCount - 1
Dim row = sheet.Rows(rowIndex)
Dim values As New StringBuilder()
For Each cell In row
If cell.Value IsNot Nothing Then
values.Append($"{cell.StringValue}" & vbTab)
End If
Next
Console.WriteLine(values.ToString().TrimEnd())
Next

範圍字串"A2:D100"建立平坦的單元格集合。 範圍內的行按自上而下、從左到右的順序處理。 此模式適用於導出到DataTable或資料庫。
sheet.RowCount屬性反映了工作表中最後使用的行,因此當資料結束時,迴圈會自動終止。 遍歷Excel範圍指南涵蓋了包括按列優先遍歷的其他遍歷模式。
跳過標題行
大多數電子表格有一個用於描述列名的標頭行,而不是包含資料。 從行2開始範圍遍歷(例如,rowIndex = 1開始索引迴圈以跳過標題。 如果您使用ToDataTable(true),IronXL會自動處理標頭檢測並映射第一行的列名。
如何處理多個Excel格式?
IronXL自動從擴展名和文件頭中檢測文件格式。 API對XLSX、XLS和CSV文件是一致的,這意味着所有三種格式都可以使用相同的解析程式碼,無需條件邏輯。
using IronXL;
// Load different formats with identical API
WorkBook xlsxBook = WorkBook.Load("Modern.xlsx");
WorkBook xlsBook = WorkBook.Load("Legacy.xls");
WorkBook csvBook = WorkBook.Load("Export.csv");
// Access worksheets identically across formats
WorkSheet sheet1 = xlsxBook.DefaultWorkSheet;
WorkSheet sheet2 = xlsBook.DefaultWorkSheet;
WorkSheet sheet3 = csvBook.DefaultWorkSheet;
// Cross-format conversion -- save XLSX as CSV, or CSV as XLSX
xlsxBook.SaveAs("converted_output.csv");
csvBook.SaveAs("structured_output.xlsx");
Console.WriteLine($"XLSX rows: {sheet1.RowCount}");
Console.WriteLine($"XLS rows: {sheet2.RowCount}");
Console.WriteLine($"CSV rows: {sheet3.RowCount}");
using IronXL;
// Load different formats with identical API
WorkBook xlsxBook = WorkBook.Load("Modern.xlsx");
WorkBook xlsBook = WorkBook.Load("Legacy.xls");
WorkBook csvBook = WorkBook.Load("Export.csv");
// Access worksheets identically across formats
WorkSheet sheet1 = xlsxBook.DefaultWorkSheet;
WorkSheet sheet2 = xlsBook.DefaultWorkSheet;
WorkSheet sheet3 = csvBook.DefaultWorkSheet;
// Cross-format conversion -- save XLSX as CSV, or CSV as XLSX
xlsxBook.SaveAs("converted_output.csv");
csvBook.SaveAs("structured_output.xlsx");
Console.WriteLine($"XLSX rows: {sheet1.RowCount}");
Console.WriteLine($"XLS rows: {sheet2.RowCount}");
Console.WriteLine($"CSV rows: {sheet3.RowCount}");
Imports IronXL
' Load different formats with identical API
Dim xlsxBook As WorkBook = WorkBook.Load("Modern.xlsx")
Dim xlsBook As WorkBook = WorkBook.Load("Legacy.xls")
Dim csvBook As WorkBook = WorkBook.Load("Export.csv")
' Access worksheets identically across formats
Dim sheet1 As WorkSheet = xlsxBook.DefaultWorkSheet
Dim sheet2 As WorkSheet = xlsBook.DefaultWorkSheet
Dim sheet3 As WorkSheet = csvBook.DefaultWorkSheet
' Cross-format conversion -- save XLSX as CSV, or CSV as XLSX
xlsxBook.SaveAs("converted_output.csv")
csvBook.SaveAs("structured_output.xlsx")
Console.WriteLine($"XLSX rows: {sheet1.RowCount}")
Console.WriteLine($"XLS rows: {sheet2.RowCount}")
Console.WriteLine($"CSV rows: {sheet3.RowCount}")
對於CSV文件,IronXL遵循RFC 4180慣例,包括包含逗號的引號字段、引號值中的換行符和轉義的雙引號。 CSV到XLSX轉換指南涵蓋了非標準CSV導出的分隔符定制。
當您的應用程式必須接受來自外部系統的文件時,最好檢查文件的擴展名並在載入之前驗證內容。 如果文件損壞或格式不受支持,IronXL會拋出一個描述性異常,您可以捕獲並提供給使用者。
如何在Excel資料上運行高級查詢?
除了逐個單元讀取,IronXL還提供了聚合函式和LINQ相容性,可將工作表範圍轉換為可查詢集合。
using IronXL;
using System.Linq;
WorkBook workbook = WorkBook.Load("Financials.xlsx");
WorkSheet sheet = workbook.DefaultWorkSheet;
// Built-in aggregates -- no manual looping needed
decimal totalSales = sheet["B2:B50"].Sum();
decimal maxRevenue = sheet["C2:C50"].Max(c => c.DecimalValue);
decimal avgMargin = sheet["D2:D50"].Avg();
// LINQ filtering directly on a range
var highValueRows = sheet["C2:C50"]
.Where(c => c.DecimalValue > 1000)
.Select(c => new { c.AddressString, c.DecimalValue });
foreach (var row in highValueRows)
Console.WriteLine($"高 value at {row.AddressString}: {row.DecimalValue:C}");
// Write a calculated result back to the sheet
sheet["E2"].Value = totalSales;
workbook.SaveAs("Financials_Updated.xlsx");
Console.WriteLine($"Total: {totalSales:C}, Max: {maxRevenue:C}, Avg: {avgMargin:C}");
using IronXL;
using System.Linq;
WorkBook workbook = WorkBook.Load("Financials.xlsx");
WorkSheet sheet = workbook.DefaultWorkSheet;
// Built-in aggregates -- no manual looping needed
decimal totalSales = sheet["B2:B50"].Sum();
decimal maxRevenue = sheet["C2:C50"].Max(c => c.DecimalValue);
decimal avgMargin = sheet["D2:D50"].Avg();
// LINQ filtering directly on a range
var highValueRows = sheet["C2:C50"]
.Where(c => c.DecimalValue > 1000)
.Select(c => new { c.AddressString, c.DecimalValue });
foreach (var row in highValueRows)
Console.WriteLine($"高 value at {row.AddressString}: {row.DecimalValue:C}");
// Write a calculated result back to the sheet
sheet["E2"].Value = totalSales;
workbook.SaveAs("Financials_Updated.xlsx");
Console.WriteLine($"Total: {totalSales:C}, Max: {maxRevenue:C}, Avg: {avgMargin:C}");
Imports IronXL
Imports System.Linq
Dim workbook As WorkBook = WorkBook.Load("Financials.xlsx")
Dim sheet As WorkSheet = workbook.DefaultWorkSheet
' Built-in aggregates -- no manual looping needed
Dim totalSales As Decimal = sheet("B2:B50").Sum()
Dim maxRevenue As Decimal = sheet("C2:C50").Max(Function(c) c.DecimalValue)
Dim avgMargin As Decimal = sheet("D2:D50").Avg()
' LINQ filtering directly on a range
Dim highValueRows = sheet("C2:C50") _
.Where(Function(c) c.DecimalValue > 1000) _
.Select(Function(c) New With {Key .AddressString = c.AddressString, Key .DecimalValue = c.DecimalValue})
For Each row In highValueRows
Console.WriteLine($"高 value at {row.AddressString}: {row.DecimalValue:C}")
Next
' Write a calculated result back to the sheet
sheet("E2").Value = totalSales
workbook.SaveAs("Financials_Updated.xlsx")
Console.WriteLine($"Total: {totalSales:C}, Max: {maxRevenue:C}, Avg: {avgMargin:C}")

LINQ相容性在您需要在將其匯入資料庫之前過濾行或驗證列中的所有值是否達到閾值時非常有用。 程式庫在LINQ運行之前計算公式,因此聚合查詢總是在計算出的最終值上運行,而不是公式字串。
IronXL教程中的LINQ涵蓋了連接工作表、按列分組和將結果投影到強型別物件中的模式--這些模式可消除資料管道程式碼中的大量樣板。
如何將Excel資料匯出到DataTable?
許多.NET應用程式將電子表格資料載入到ADO.NET DataTable中以進一步處理或資料庫插入。 IronXL提供了一種直接轉換方法,去除了手動列映射的需求。
using IronXL;
using System.Data;
WorkBook workbook = WorkBook.Load("SalesData.xlsx");
WorkSheet sheet = workbook.DefaultWorkSheet;
// Convert worksheet to DataTable -- first row becomes column headers
DataTable dataTable = sheet.ToDataTable(true);
Console.WriteLine($"Columns: {dataTable.Columns.Count}");
Console.WriteLine($"Rows: {dataTable.Rows.Count}");
// Iterate the DataTable normally
foreach (DataRow row in dataTable.Rows)
{
Console.WriteLine($"{row["ProductName"]} -- {row["Quantity"]} -- {row["Price"]}");
}
using IronXL;
using System.Data;
WorkBook workbook = WorkBook.Load("SalesData.xlsx");
WorkSheet sheet = workbook.DefaultWorkSheet;
// Convert worksheet to DataTable -- first row becomes column headers
DataTable dataTable = sheet.ToDataTable(true);
Console.WriteLine($"Columns: {dataTable.Columns.Count}");
Console.WriteLine($"Rows: {dataTable.Rows.Count}");
// Iterate the DataTable normally
foreach (DataRow row in dataTable.Rows)
{
Console.WriteLine($"{row["ProductName"]} -- {row["Quantity"]} -- {row["Price"]}");
}
Imports IronXL
Imports System.Data
Dim workbook As WorkBook = WorkBook.Load("SalesData.xlsx")
Dim sheet As WorkSheet = workbook.DefaultWorkSheet
' Convert worksheet to DataTable -- first row becomes column headers
Dim dataTable As DataTable = sheet.ToDataTable(True)
Console.WriteLine($"Columns: {dataTable.Columns.Count}")
Console.WriteLine($"Rows: {dataTable.Rows.Count}")
' Iterate the DataTable normally
For Each row As DataRow In dataTable.Rows
Console.WriteLine($"{row("ProductName")} -- {row("Quantity")} -- {row("Price")}")
Next
將ToDataTable將第一行工作表作為列標頭處理。 結果DataTable使用與標題文字匹配的字串列名,這使得隨後的LINQ-to-DataSet查詢可讀。 DataTable匯出文件涵蓋了空值處理和型別推斷選項。
當下游程式碼已經期待一個SqlBulkCopy插入行到SQL Server時。 您可以載入XLSX文件,將其轉換為DataTable,然後批量插入,而無需寫任何列映射樣板。
| 操作 | API | 返回 |
|---|---|---|
| 載入文件 | WorkBook.Load(path) |
WorkBook |
| 按索引獲取工作表 | workbook.WorkSheets[0] |
WorkSheet |
| 按名稱獲取工作表 | workbook.GetWorkSheet("name") |
WorkSheet |
| 讀取字串單元格 | sheet["A1"].StringValue |
string |
| 讀取十進位單元格 | sheet["B1"].DecimalValue |
decimal |
| 遍歷範圍 | foreach cell in sheet["A2:D100"] |
IEnumerable<Cell> |
| 匯總範圍 | sheet["B2:B50"].Sum() |
decimal |
| 匯出到DataTable | sheet.ToDataTable(true) |
DataTable |
要查看完整的API列表,請參閱IronXL API參考。 該參考涵蓋了每個屬性和方法,包括參數描述和返回型別詳細資訊。
您的下一步是什麼?
一旦您擁有正確的程式庫,用C#讀取Excel文件就很簡單。 IronXL去除了Office依賴,簡化了API表面,並使用相同的程式碼路徑處理XLSX、XLS和CSV格式。 這裡涵蓋的模式 -- 載入工作簿,讀取型別化單元格值,遍歷範圍,運行匯總,並匯出到DataTable -- 覆蓋了大多數真實世界的電子表格閱讀需求。
要繼續建立在這些模式的基礎上:
- 閱讀IronXL入門文件以獲得專案設置指導和運行時需求。
- 探索操作指南以學習編寫、格式和圖表生成。
- 審閱Excel公式支持指南以了解IronXL自動計算的Excel函式。
- 檢查IronXL許可頁面以獲得生產部署選項。
- 瀏覽IronXL部落格中的範例,涵蓋了資料驗證、資料透視表匯出以及密碼保護文件處理。
對於評估IronXL與其他程式庫的團隊,IronXL與EPPlus比較和IronXL與NPOI比較涵蓋了性能基準和API差異。 這兩個比較中都包括了每個庫等效操作的程式碼範例。
如果您遇到來自遺留系統的異常電子表格結構,Microsoft自己的Excel文件格式規範是一個有用的參考。 ECMA-376標準定義了XLSX文件遵循的OOXML格式。
開始使用免費的IronXL試用許可在您自己的專案中測試完整API,然後再購買生產許可。
常見問題
用C#讀取Excel檔案的最佳方法是什麼?
使用像IronXL這樣的專用、獨立於Office的程式庫是用C#讀取Excel檔案的最佳方法。它處理XLSX、XLS和CSV格式,不需要Microsoft Excel或COM互通,使其適合於伺服器和容器環境。
您需要安裝Microsoft Office才能使用IronXL嗎?
不需要。IronXL是一個獨立的.NET程式庫,以NuGet包形式發佈。它不需要機器上有Microsoft Office、Excel或任何COM元件。
IronXL支持哪些Excel檔案格式?
IronXL讀取和寫入XLSX、XLS和CSV檔案。根據檔案擴展名和內容標頭,自動進行格式檢測。
如何在.NET專案中安裝IronXL?
在終端中運行 'dotnet add package IronXL.Excel' 或在 Visual Studio Package Manager Console 中運行 'Install-Package IronXL.Excel'。
IronXL可以將Excel資料匯出為DataTable嗎?
可以。WorkSheet.ToDataTable(true) 方法將任意工作表轉換為ADO.NET DataTable,當true傳入時,第一行用作列標題。
IronXL支持在Excel資料上進行LINQ查詢嗎?
可以。IronXL的單元格範圍實現了IEnumerable,因此可以直接在工作表範圍上使用LINQ方法,如Where、Select、Sum、Max和Avg。
IronXL如何處理Excel公式?
IronXL會自動評估公式,當您讀取單元格值時。讀取公式單元格的sheet["B10"].DecimalValue會返回計算結果,而非公式字串。
IronXL支持哪些.NET版本?
IronXL支持.NET 10、.NET 8、.NET 6、.NET Framework 4.6.2和.NET Standard 2.0。




