如何在 C# 中讀取 Excel 檔案而不是使用 StreamReader
許多C#開發人員在處理Excel文件時遇到一個讓人沮喪的挑戰:處理文字文件可靠的StreamReader類,當面對Excel文件時卻完全無法運作。 如果您試圖通過C#中的StreamReader讀取Excel文件,卻只看到亂碼、二進制噪聲或意外異常,您不是唯一的一個。 本指南正確說明了為什麼StreamReader無法處理Excel文件,並向您展示如何正確解決此問題的方法,使用IronXL --一個專為.NET設計的Excel程式庫,且不需要安裝Excel。
混淆通常發生是因為CSV文件 -- Excel可以打開和保存 -- 在StreamReader下工作正常。 真正的Excel文件(XLSX、XLS、XLSM)需要根本不同的方法。 理解這一區別將為您節省數小時的除錯時間,並引導您找到合適的工具。

為什麼StreamReader無法讀取Excel文件?
StreamReader是一個基於文字的讀取器。 它使用指定的編碼(如UTF-8、ASCII等)逐行讀取字元資料,並不知道任何二進制結構或壓縮檔案。 官方.NET StreamReader文件確認這個類是專為字元編碼文字設計的。 Excel文件儘管看起來像簡單的試算表,實際上是複雜的二進制或ZIP壓縮的XML結構,StreamReader無法解析。
當您使用StreamReader打開XLSX文件時,您基本上是在嘗試將ZIP壓縮檔案作為純文字讀取。 結果是一串二進制噪聲,而不是您的試算表資料。
// This code will NOT work -- demonstrates the problem
using StreamReader reader = new StreamReader("ProductData.xlsx");
string content = reader.ReadLine();
Console.WriteLine(content); // Outputs garbled binary data like "PK♥♦"
// This code will NOT work -- demonstrates the problem
using StreamReader reader = new StreamReader("ProductData.xlsx");
string content = reader.ReadLine();
Console.WriteLine(content); // Outputs garbled binary data like "PK♥♦"
Imports System.IO
' This code will NOT work -- demonstrates the problem
Using reader As New StreamReader("ProductData.xlsx")
Dim content As String = reader.ReadLine()
Console.WriteLine(content) ' Outputs garbled binary data like "PK♥♦"
End Using
當您運行這個片段時,與其看到您的試算表行,不如看到如PK♥♦等二進制字元或類似噪音。這是因為:
- XLSX文件是包含多個XML文件的ZIP壓縮包:工作表、樣式、共享字串、關係。 Open XML SDK文件提供了這一結構的詳細解析。
- XLS文件使用專有的二進制格式(BIFF -- 二進制交換文件格式)
StreamReader將讀取的任何位元組應用字元編碼,對於這兩種格式產生毫無意義的輸出
範例輸入

使用StreamReader時的亂碼輸出

為什麼CSV可以而XLSX不行
CSV(逗號分隔值)是一種純文字格式。 每行是文字行,每列用逗號分隔。 StreamReader 讀取CSV文件時沒有問題,因為它們不包含二進制資料或壓縮檔案。 XLSX從根本上不同:它會將多個XML文件打包在帶有元資料、主題和樣式定義的ZIP容器中。 無法進行簡單的逐行讀取。
這一區別在選擇工具時尤為重要。 對於CSV文件,File.ReadAllLines是完全足夠的。 對於真正的Excel工作簿,您需要一個從結構層面理解格式的程式庫。
如何在.NET專案中安裝IronXL?
IronXL 是一個.NET程式庫,可以讀取、寫入和建立Excel文件而不需要安裝Microsoft Excel。 它支持XLSX、XLS、XLSM、CSV和TSV格式,並可在Windows、Linux、macOS和Docker容器上運行。
要安裝IronXL,可以使用NuGet包管理控制台或.NET CLI。 該包已在NuGet.org以上的IronXL發佈。
:ProductInstall
dotnet add package IronXL
:ProductInstall
dotnet add package IronXL
安裝後,將using IronXL;指令新增到您的文件中,您就可以開始處理Excel文件了。

如需詳細安裝步驟和NuGet配置選項,請參閱IronXL NuGet 安裝指南。 提供了一個免費試用授權,您可以在購買之前,在您的項目中評估IronXL。

您如何使用IronXL讀取Excel文件?
IronXL提供了一個直觀的API來用C#讀取Excel文件。 與StreamReader不同,IronXL理解Excel的內部結構,並提供對行、列和單元格值的清晰存取。 IronXL文件提供了所有支持操作的完整API參考。
這是如何使用IronXL在頂級語句中讀取Excel文件的方法:
using IronXL;
// Load the Excel file from disk
WorkBook workbook = WorkBook.Load("ProductData.xlsx");
WorkSheet worksheet = workbook.DefaultWorkSheet;
// Read a specific cell by address
string cellValue = worksheet["A1"].StringValue;
Console.WriteLine($"Cell A1 contains: {cellValue}");
// Iterate over a range of cells
foreach (var cell in worksheet["A1:C10"])
{
Console.WriteLine($"{cell.AddressString}: {cell.Text}");
}
// Read a numeric value
decimal price = worksheet["B2"].DecimalValue;
Console.WriteLine($"Price: {price:C}");
using IronXL;
// Load the Excel file from disk
WorkBook workbook = WorkBook.Load("ProductData.xlsx");
WorkSheet worksheet = workbook.DefaultWorkSheet;
// Read a specific cell by address
string cellValue = worksheet["A1"].StringValue;
Console.WriteLine($"Cell A1 contains: {cellValue}");
// Iterate over a range of cells
foreach (var cell in worksheet["A1:C10"])
{
Console.WriteLine($"{cell.AddressString}: {cell.Text}");
}
// Read a numeric value
decimal price = worksheet["B2"].DecimalValue;
Console.WriteLine($"Price: {price:C}");
Imports IronXL
' Load the Excel file from disk
Dim workbook As WorkBook = WorkBook.Load("ProductData.xlsx")
Dim worksheet As WorkSheet = workbook.DefaultWorkSheet
' Read a specific cell by address
Dim cellValue As String = worksheet("A1").StringValue
Console.WriteLine($"Cell A1 contains: {cellValue}")
' Iterate over a range of cells
For Each cell In worksheet("A1:C10")
Console.WriteLine($"{cell.AddressString}: {cell.Text}")
Next
' Read a numeric value
Dim price As Decimal = worksheet("B2").DecimalValue
Console.WriteLine($"Price: {price:C}")
WorkBook.Load 方法自動檢測文件格式(XLSX, XLS, XLSM, CSV)並處理所有複雜的解析。 您可以使用如"A1:C10"之類的範圍這樣的標準Excel表示法來存取單元格,這使得程式碼對於熟悉電子表格的人來說立即易讀。
存取多個工作表
許多工作簿包含多個工作表。 IronXL讓您可以打開並導航工作簿,並可枚舉完整工作表:
using IronXL;
WorkBook workbook = WorkBook.Load("MultiSheet.xlsx");
// List all worksheets
foreach (WorkSheet sheet in workbook.WorkSheets)
{
Console.WriteLine($"Sheet: {sheet.Name}, Rows: {sheet.RowCount}");
}
// Access a sheet by name
WorkSheet summary = workbook.GetWorkSheet("Summary");
string totalRevenue = summary["B20"].StringValue;
Console.WriteLine($"Total Revenue: {totalRevenue}");
// Access a sheet by index
WorkSheet firstSheet = workbook.WorkSheets[0];
int lastRow = firstSheet.RowCount;
Console.WriteLine($"Last row in first sheet: {lastRow}");
using IronXL;
WorkBook workbook = WorkBook.Load("MultiSheet.xlsx");
// List all worksheets
foreach (WorkSheet sheet in workbook.WorkSheets)
{
Console.WriteLine($"Sheet: {sheet.Name}, Rows: {sheet.RowCount}");
}
// Access a sheet by name
WorkSheet summary = workbook.GetWorkSheet("Summary");
string totalRevenue = summary["B20"].StringValue;
Console.WriteLine($"Total Revenue: {totalRevenue}");
// Access a sheet by index
WorkSheet firstSheet = workbook.WorkSheets[0];
int lastRow = firstSheet.RowCount;
Console.WriteLine($"Last row in first sheet: {lastRow}");
Imports IronXL
Dim workbook As WorkBook = WorkBook.Load("MultiSheet.xlsx")
' List all worksheets
For Each sheet As WorkSheet In workbook.WorkSheets
Console.WriteLine($"Sheet: {sheet.Name}, Rows: {sheet.RowCount}")
Next
' Access a sheet by name
Dim summary As WorkSheet = workbook.GetWorkSheet("Summary")
Dim totalRevenue As String = summary("B20").StringValue
Console.WriteLine($"Total Revenue: {totalRevenue}")
' Access a sheet by index
Dim firstSheet As WorkSheet = workbook.WorkSheets(0)
Dim lastRow As Integer = firstSheet.RowCount
Console.WriteLine($"Last row in first sheet: {lastRow}")
這樣的方法遠比任何嘗試使用StreamReader或字串操作解析Excel的努力要乾淨。
您如何從記憶體流中讀取Excel資料?
實際應用程式經常需要從流而非磁碟檔案處理 Excel 檔案。 常見的場景包括從網頁表單處理文件上傳、從資料庫BLOB列檢索工作簿或處理從雲儲存(Azure Blob Storage, AWS S3)中下載的文件。 IronXL通過WorkBook.FromStream處理這些場景:
using IronXL;
using System.IO;
// Simulate reading file bytes (e.g., from a database or web upload)
byte[] fileBytes = File.ReadAllBytes("ProductData.xlsx");
using MemoryStream stream = new MemoryStream(fileBytes);
WorkBook workbook = WorkBook.FromStream(stream);
WorkSheet worksheet = workbook.DefaultWorkSheet;
// Get row and column counts
Console.WriteLine($"Rows: {worksheet.RowCount}, Columns: {worksheet.ColumnCount}");
// Convert to DataTable for database or grid binding
var dataTable = worksheet.ToDataTable(useHeaderRow: true);
Console.WriteLine($"Loaded {dataTable.Rows.Count} data rows");
foreach (System.Data.DataRow row in dataTable.Rows)
{
string productName = row["ProductName"]?.ToString() ?? string.Empty;
string sku = row["SKU"]?.ToString() ?? string.Empty;
Console.WriteLine($"Product: {productName}, SKU: {sku}");
}
using IronXL;
using System.IO;
// Simulate reading file bytes (e.g., from a database or web upload)
byte[] fileBytes = File.ReadAllBytes("ProductData.xlsx");
using MemoryStream stream = new MemoryStream(fileBytes);
WorkBook workbook = WorkBook.FromStream(stream);
WorkSheet worksheet = workbook.DefaultWorkSheet;
// Get row and column counts
Console.WriteLine($"Rows: {worksheet.RowCount}, Columns: {worksheet.ColumnCount}");
// Convert to DataTable for database or grid binding
var dataTable = worksheet.ToDataTable(useHeaderRow: true);
Console.WriteLine($"Loaded {dataTable.Rows.Count} data rows");
foreach (System.Data.DataRow row in dataTable.Rows)
{
string productName = row["ProductName"]?.ToString() ?? string.Empty;
string sku = row["SKU"]?.ToString() ?? string.Empty;
Console.WriteLine($"Product: {productName}, SKU: {sku}");
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
Stream -- MemoryStream, FileStream或網路流。 這種靈活性意味著您不必編寫臨時文件到磁碟上以便讀取Excel資料。 轉換到SqlBulkCopy,資料綁定控件和報告框架整合。
流處理輸出

您何時使用事件驅動的Excel讀取?
在事件驅動的架構中 -- 例如,Windows Forms中的文件上傳按鈕或ASP.NET控制器動作 -- 方法簽名通常包括EventArgs e參數。 Excel處理邏輯仍然使用相同的IronXL API,但是從事件處理程式中而不是頂級語句中調用。 IronXL可以潔淨地整合到任何事件驅動或異步工作流程中,因為它對UI執行緒沒有依賴性。

如何在Excel和CSV格式之間轉換?
雖然StreamReader可以處理CSV文件,但是生產應用程式通常需要在Excel和CSV之間移動資料。IronXL使格式轉換變得簡單。 您可以將Excel資料導出到CSV,或者將CSV資料導入到工作簿中,只需幾行程式碼即可:
using IronXL;
// Load an Excel file and save as CSV
WorkBook workbook = WorkBook.Load("SalesData.xlsx");
workbook.SaveAsCsv("output.csv");
// Load a CSV file and save as Excel
WorkBook csvWorkbook = WorkBook.LoadCSV("legacy-report.csv");
csvWorkbook.SaveAs("converted.xlsx");
// Export a specific worksheet to CSV
WorkSheet worksheet = workbook.WorkSheets[0];
worksheet.SaveAsCsv("sheet1-export.csv");
using IronXL;
// Load an Excel file and save as CSV
WorkBook workbook = WorkBook.Load("SalesData.xlsx");
workbook.SaveAsCsv("output.csv");
// Load a CSV file and save as Excel
WorkBook csvWorkbook = WorkBook.LoadCSV("legacy-report.csv");
csvWorkbook.SaveAs("converted.xlsx");
// Export a specific worksheet to CSV
WorkSheet worksheet = workbook.WorkSheets[0];
worksheet.SaveAsCsv("sheet1-export.csv");
IRON VB CONVERTER ERROR developers@ironsoftware.com
這些轉換在改變容器格式的同時保留了您的資料。 當轉換Excel到CSV時,IronXL預設導出第一個工作表; 您可以指定您選擇的任意工作表。 將CSV轉換為Excel會建立正確緻構的工作簿,隨後您可以格式化,新增公式,並寫入額外資料。
支持格式有什麼不同?
| 文件格式 | StreamReader | IronXL | 註釋 |
|---|---|---|---|
| CSV (.csv) | 是 | 是 | 純文字; StreamReader完全可以用 |
| XLSX (.xlsx) | 否 | 是 | ZIP壓縮的XML; 需要程式庫 |
| XLS (.xls) | 否 | 是 | 二進制BIFF格式; 需要程式庫 |
| XLSM (.xlsm) | 否 | 是 | 啟用宏的工作簿 |
| TSV (.tsv) | 是 | 是 | Tab分隔的純文字 |
如何使用IronXL建立和格式化Excel文件?
讀取Excel資料只是工作流程的一部分。 許多應用程式還需要建立新Excel文件並應用格式。 IronXL支持單元格格式化,包括字體、顏色、邊框、數字格式和合併單元格:
using IronXL;
// Create a new workbook and worksheet
WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet sheet = workbook.CreateWorkSheet("Report");
// Write headers with formatting
sheet["A1"].Value = "Product";
sheet["B1"].Value = "Units Sold";
sheet["C1"].Value = "Revenue";
// Apply bold formatting to header row
sheet["A1:C1"].Style.Font.Bold = true;
sheet["A1:C1"].Style.SetBackgroundColor("#4472C4");
sheet["A1:C1"].Style.Font.Color = "#FFFFFF";
// Write data rows
string[] products = { "Widget A", "Widget B", "Widget C" };
int[] units = { 120, 85, 210 };
decimal[] revenues = { 2400.00m, 1700.00m, 4200.00m };
for (int i = 0; i < products.Length; i++)
{
sheet[$"A{i + 2}"].Value = products[i];
sheet[$"B{i + 2}"].Value = units[i];
sheet[$"C{i + 2}"].Value = revenues[i];
sheet[$"C{i + 2}"].FormatString = "$#,##0.00";
}
// Save the workbook
workbook.SaveAs("FormattedReport.xlsx");
Console.WriteLine("Report created successfully.");
using IronXL;
// Create a new workbook and worksheet
WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet sheet = workbook.CreateWorkSheet("Report");
// Write headers with formatting
sheet["A1"].Value = "Product";
sheet["B1"].Value = "Units Sold";
sheet["C1"].Value = "Revenue";
// Apply bold formatting to header row
sheet["A1:C1"].Style.Font.Bold = true;
sheet["A1:C1"].Style.SetBackgroundColor("#4472C4");
sheet["A1:C1"].Style.Font.Color = "#FFFFFF";
// Write data rows
string[] products = { "Widget A", "Widget B", "Widget C" };
int[] units = { 120, 85, 210 };
decimal[] revenues = { 2400.00m, 1700.00m, 4200.00m };
for (int i = 0; i < products.Length; i++)
{
sheet[$"A{i + 2}"].Value = products[i];
sheet[$"B{i + 2}"].Value = units[i];
sheet[$"C{i + 2}"].Value = revenues[i];
sheet[$"C{i + 2}"].FormatString = "$#,##0.00";
}
// Save the workbook
workbook.SaveAs("FormattedReport.xlsx");
Console.WriteLine("Report created successfully.");
Imports IronXL
' Create a new workbook and worksheet
Dim workbook As WorkBook = WorkBook.Create(ExcelFileFormat.XLSX)
Dim sheet As WorkSheet = workbook.CreateWorkSheet("Report")
' Write headers with formatting
sheet("A1").Value = "Product"
sheet("B1").Value = "Units Sold"
sheet("C1").Value = "Revenue"
' Apply bold formatting to header row
sheet("A1:C1").Style.Font.Bold = True
sheet("A1:C1").Style.SetBackgroundColor("#4472C4")
sheet("A1:C1").Style.Font.Color = "#FFFFFF"
' Write data rows
Dim products As String() = {"Widget A", "Widget B", "Widget C"}
Dim units As Integer() = {120, 85, 210}
Dim revenues As Decimal() = {2400.0D, 1700.0D, 4200.0D}
For i As Integer = 0 To products.Length - 1
sheet($"A{i + 2}").Value = products(i)
sheet($"B{i + 2}").Value = units(i)
sheet($"C{i + 2}").Value = revenues(i)
sheet($"C{i + 2}").FormatString = "$#,##0.00"
Next
' Save the workbook
workbook.SaveAs("FormattedReport.xlsx")
Console.WriteLine("Report created successfully.")
既能讀取現有工作簿又能建立新格式文件的能力使IronXL成為.NET應用程式的完整Excel解決方案。 查看完整的IronXL功能頁面,了解支持操作的詳細分析。
將資料導出到其他格式
IronXL還支持將工作簿資料導出到DataSet 物件,這在將多個工作表載入到記憶體中進行跨表計算或資料庫批量插入操作時尤為有用。 DataTable。

如何在生產環境中授權和部署IronXL?
IronXL在開發和測試中是免費的。 對於生產應用程式,需要授權。 您可以在產品頁面上探索IronXL 授權選項,這涵蓋了根據部署要求的開發者、團隊和組織級別。
購買後,請在任何IronXL調用之前在程式碼中應用您的授權金鑰:
IronXL.License.LicenseKey = "YOUR-LICENSE-KEY-HERE";
IronXL.License.LicenseKey = "YOUR-LICENSE-KEY-HERE";
Imports IronXL
IronXL.License.LicenseKey = "YOUR-LICENSE-KEY-HERE"
或者,將IRONXL_LICENSE_KEY環境變數設置在您的部署環境中,IronXL將自動檢索它。 這是在容器部署(Docker, Kubernetes)和雲端環境中首選的方法,在這些環境中,不可以硬編碼金鑰。
出於評估目的,提供免費試用授權,提供全部功能,讓您可以在承諾購買之前驗證IronXL是否符合您的特定工作負載。 試用不需要信用卡,並立即激活。
與Microsoft.Office.Interop.Excel等替代方案相比,IronXL在部署方面有幾個優勢:
- 伺服器上不需要安裝Microsoft Excel
- 相容Linux和Docker -- 這對雲原生應用程式至關重要
- 無需COM物件生命周期管理或公寓執行緒問題
- 在伺服器上下文中具有更快的啟動和更低的記憶體使用
- 在所有受支持的平台上性能一致
這些特性使IronXL成為任何需要在生產中處理Excel文件的.NET應用程式的實際選擇,無論是內部部署還是雲端。
常見問題
為什麼StreamReader不能直接處理Excel文件?
StreamReader設計用來讀取文字文件,無法解析Excel文件中使用的二進制或複雜結構化資料格式。這一局限性導致在直接用StreamReader嘗試讀取Excel文件時會出現字元亂碼或異常。
C#中讀取Excel文件的推薦解決方案是什麼?
推薦的解決方案是使用IronXL,一個強大的程式庫,使您無需依賴Excel Interop即可在C#中讀取、編輯和建立Excel文件。IronXL能夠高效處理Excel文件的複雜結構。
IronXL相較於Excel Interop有何優勢?
IronXL與Excel Interop相比有幾個優勢,包括更好的性能,不依賴於伺服器或客戶機上安裝Excel,更容易部署,並能在網路和雲環境中工作。
IronXL能處理.xls和.xlsx文件格式嗎?
是的,IronXL能處理.xls和.xlsx兩種Excel文件格式,為開發者處理不同型別的Excel文件提供靈活性。
IronXL可以用於Web應用程式中嗎?
是的,IronXL設計用於各種應用程式型別,包括網路應用程式,得益於其輕量特性及與.NET Core和.NET Framework的相容性。
IronXL需要安裝Microsoft Excel嗎?
不,IronXL不需要在伺服器或客戶機上安裝Microsoft Excel,因此非常適合於伺服器端應用程式和雲環境。
IronXL的典型使用案例有哪些?
IronXL的典型使用案例包括從Excel文件中提取和分析資料,生成報告,自動化Excel文件建立和修改,將Excel資料整合到其他應用程式中。




