C# 中讀取 Excel 檔案的 StreamReader 替代方案 - IronXL
許多C#開發人員在嘗試讀取Excel工作表文件時遇到一個常見的挑戰:他們所信賴的StreamReader在處理文字文件時運行良好,但在Excel文件上卻神秘地失敗了。 如果您嘗試使用StreamReader在C#中讀取Excel文件時出現亂碼或異常,您並不孤單。 本教程解釋了為什麼StreamReader不能直接處理Excel文件,並展示如何使用IronXL而不依賴Excel Interop的正確解決方案。
混淆常常出現在CSV文件可以被Excel打開且與StreamReader合作良好的情況中。 然而,真正的Excel文件(XLSX,XLS)需要截然不同的方法。 理解這一區別將節省您數小時的除錯時間,並引導您找到正確的工具。

為什麼StreamReader無法讀取Excel文件?
StreamReader專為純文字文件設計,逐行根據指定的編碼讀取字元資料。 儘管Excel文件的外觀像是電子表格,但實際上它們是複雜的二進位或ZIP壓縮的XML結構,StreamReader無法解釋這類文件。
static void Main(string[] args)
{
// This code will NOT work - demonstrates the problem
using (StreamReader reader = new StreamReader("ProductData.xlsx"))
{
string content = reader.ReadLine(); // read data
Console.WriteLine(content); // Outputs garbled binary data
}
}
static void Main(string[] args)
{
// This code will NOT work - demonstrates the problem
using (StreamReader reader = new StreamReader("ProductData.xlsx"))
{
string content = reader.ReadLine(); // read data
Console.WriteLine(content); // Outputs garbled binary data
}
}
Option Strict On
Imports System.IO
Module Program
Sub Main(args As String())
' This code will NOT work - demonstrates the problem
Using reader As New StreamReader("ProductData.xlsx")
Dim content As String = reader.ReadLine() ' read data
Console.WriteLine(content) ' Outputs garbled binary data
End Using
End Sub
End Module
當您運行此類程式程式碼片段時,您將會見到的不是您的表格資料,而是未知的二進位資料,例如"PK♥♦"或類似的系統字元。 這種情況發生是因為XLSX文件是包含多個XML文件的ZIP檔案,而XLS文件則使用專有的二進位格式。 StreamReader期望的是純文字,並嘗試將這些複雜的結構解釋為字元,導致無意義的輸出。
範例輸入

輸出

現代Excel文件(XLSX)包括多個組件:工作表、樣式、共享字串和關係,所有這些都被打包在一起。 這種複雜性需要能理解Excel文件結構的專用程式庫,這就引出了IronXL。
如何使用 IronXL 讀取 Excel 檔案?
IronXL為C#中讀取Excel文件提供了一個簡單的解決方案。 與StreamReader不同,IronXL了解Excel的內部結構,並提供方便的方法來存取您的資料。 該程式庫支持Windows、Linux、macOS和Docker容器,使其成為當前跨平台應用程式的理想選擇。

首先,通過NuGet包管理器安裝IronXL:
Install-Package IronXL.Excel

這是如何正確讀取Excel文件的方法:
using IronXL;
// Load the Excel file
WorkBook workbook = WorkBook.Load("sample.xlsx");
WorkSheet worksheet = workbook.DefaultWorkSheet;
// Read specific cell values
string cellValue = worksheet["A1"].StringValue;
Console.WriteLine($"Cell A1 contains: {cellValue}");
// Read a range of cells
foreach (var cell in worksheet["A1:C5"])
{
Console.WriteLine($"{cell.AddressString}: {cell.Text}");
}
using IronXL;
// Load the Excel file
WorkBook workbook = WorkBook.Load("sample.xlsx");
WorkSheet worksheet = workbook.DefaultWorkSheet;
// Read specific cell values
string cellValue = worksheet["A1"].StringValue;
Console.WriteLine($"Cell A1 contains: {cellValue}");
// Read a range of cells
foreach (var cell in worksheet["A1:C5"])
{
Console.WriteLine($"{cell.AddressString}: {cell.Text}");
}
Imports IronXL
' Load the Excel file
Dim workbook As WorkBook = WorkBook.Load("sample.xlsx")
Dim worksheet As WorkSheet = workbook.DefaultWorkSheet
' Read specific cell values
Dim cellValue As String = worksheet("A1").StringValue
Console.WriteLine($"Cell A1 contains: {cellValue}")
' Read a range of cells
For Each cell In worksheet("A1:C5")
Console.WriteLine($"{cell.AddressString}: {cell.Text}")
Next
此程式碼成功載入您的Excel文件,並提供對單元格值的清晰存取。 WorkBook.Load方法會自動檢測文件格式(XLSX,XLS,XLSM,CSV)並在內部處理所有複雜的解析。 您可以使用熟悉的Excel表示法(如"A1")存取單元格,或者使用範圍(如"A1:C5"),這使得對於任何熟悉Excel的人來說程式碼都是可理解的。
如何從記憶體流讀取 Excel?
實際應用程式經常需要從流而非磁碟檔案處理 Excel 檔案。 常見的場景包括處理網頁上傳、從資料庫中檢索文件或處理來自雲儲存的資料。 IronXL優雅地處理這些情況:
using IronXL;
using System.IO;
// Read Excel from a memory stream
byte[] fileBytes = File.ReadAllBytes("ProductData.xlsx");
using (MemoryStream stream = new MemoryStream(fileBytes))
{
WorkBook workbook = WorkBook.FromStream(stream);
WorkSheet worksheet = workbook.DefaultWorkSheet;
// Process the data
int rowCount = worksheet.RowCount;
Console.WriteLine($"The worksheet has {rowCount} rows");
// Read all data into a new DataTable, return dt
var dataTable = worksheet.ToDataTable(false);
// Return DataTable row count
Console.WriteLine($"Loaded {dataTable.Rows.Count} data rows");
}
using IronXL;
using System.IO;
// Read Excel from a memory stream
byte[] fileBytes = File.ReadAllBytes("ProductData.xlsx");
using (MemoryStream stream = new MemoryStream(fileBytes))
{
WorkBook workbook = WorkBook.FromStream(stream);
WorkSheet worksheet = workbook.DefaultWorkSheet;
// Process the data
int rowCount = worksheet.RowCount;
Console.WriteLine($"The worksheet has {rowCount} rows");
// Read all data into a new DataTable, return dt
var dataTable = worksheet.ToDataTable(false);
// Return DataTable row count
Console.WriteLine($"Loaded {dataTable.Rows.Count} data rows");
}
Imports IronXL
Imports System.IO
' Read Excel from a memory stream
Dim fileBytes As Byte() = File.ReadAllBytes("ProductData.xlsx")
Using stream As New MemoryStream(fileBytes)
Dim workbook As WorkBook = WorkBook.FromStream(stream)
Dim worksheet As WorkSheet = workbook.DefaultWorkSheet
' Process the data
Dim rowCount As Integer = worksheet.RowCount
Console.WriteLine($"The worksheet has {rowCount} rows")
' Read all data into a new DataTable, return dt
Dim dataTable = worksheet.ToDataTable(False)
' Return DataTable row count
Console.WriteLine($"Loaded {dataTable.Rows.Count} data rows")
End Using
FileStream還是網路流。 這種靈活性允許您在不先將文件保存到磁碟的情況下,從各種來源處理Excel文件。該範例還展示了將工作表資料轉換為資料表,這能與資料庫和資料綁定場景無縫整合。
輸出

何時使用object sender來讀取資料?
在此程式碼用於事件驅動編程(例如,在Windows Forms或ASP.NET中處理文件上傳按鈕)時,單一的方法簽名通常包括像EventArgs e這樣的參數。 這樣的上下文確保了Excel處理邏輯正確地與UI或服務事件結合。

如何在 Excel 和 CSV 之間轉換?
雖然StreamReader可以處理CSV文件,但通常需要在Excel和CSV格式之間進行轉換。 IronXL使得此轉換簡單易行:
using IronXL;
// Load an Excel file and save as CSV
WorkBook workbook = WorkBook.Load("data.xlsx");
workbook.SaveAsCsv("output.csv");
// Load a CSV file and save as Excel
WorkBook csvWorkbook = WorkBook.LoadCSV("input.csv");
csvWorkbook.SaveAs("output.xlsx");
// Export specific worksheet to CSV
WorkSheet worksheet = workbook.WorkSheets[0];
worksheet.SaveAsCsv("worksheet1.csv");
using IronXL;
// Load an Excel file and save as CSV
WorkBook workbook = WorkBook.Load("data.xlsx");
workbook.SaveAsCsv("output.csv");
// Load a CSV file and save as Excel
WorkBook csvWorkbook = WorkBook.LoadCSV("input.csv");
csvWorkbook.SaveAs("output.xlsx");
// Export specific worksheet to CSV
WorkSheet worksheet = workbook.WorkSheets[0];
worksheet.SaveAsCsv("worksheet1.csv");
Imports IronXL
' Load an Excel file and save as CSV
Dim workbook As WorkBook = WorkBook.Load("data.xlsx")
workbook.SaveAsCsv("output.csv")
' Load a CSV file and save as Excel
Dim csvWorkbook As WorkBook = WorkBook.LoadCSV("input.csv")
csvWorkbook.SaveAs("output.xlsx")
' Export specific worksheet to CSV
Dim worksheet As WorkSheet = workbook.WorkSheets(0)
worksheet.SaveAsCsv("worksheet1.csv")
這些轉換在改變文件格式的同時保留了您的資料。 在將Excel轉換為CSV時,IronXL預設展開第一個工作表,但您可以指定要導出的工作表。 從CSV轉換為Excel時,會建立一個格式正確的電子表格,能保存資料型別並啟用未來的格式和公式新增。
結論
StreamReader無法處理Excel文件源於純文字和Excel複雜文件結構之間的基本區別。 雖然StreamReader對於CSV和其他文字格式運行良好,但真正的Excel文件需要專門的程式庫(如IronXL)來理解其中的二進位和XML結構。
IronXL提供了一個優雅的解決方案,其直觀的API、全面的格式支持和無縫的流處理能力。 無論您是在開發網頁應用、桌面軟體還是雲服務,IronXL都可以在所有平台上可靠處理Excel文件。

準備好開始正確地處理 Excel 檔案了嗎? 下載IronXL的免費試用版,在您的C#應用程式中體驗無憂的Excel處理。 部署到生產環境時,請考慮IronXL授權選項,以更好地滿足您的專案需求。
常見問題
為什麼我不能在C#中使用StreamReader讀取Excel文件?
StreamReader是為讀取文字文件而設計的,不支援Excel文件的二進制格式,這會導致字元篡改或異常。
在C#中讀取Excel文件的推薦方法是什麼?
在C#中讀取Excel文件的推薦方法是使用IronXL,它可以在不需要Excel Interop的情況下直接讀取和操控Excel文件。
IronXL相比於StreamReader處理Excel文件有什麼優勢?
IronXL專門設計來處理Excel文件格式,允許準確的資料讀取和操控,支援公式、圖表和格式等多種功能。
我需要Excel Interop才能使用IronXL嗎?
不,IronXL是獨立於Excel Interop運行的,允許您在未安裝Excel的情況下處理Excel文件。
IronXL能處理不同的Excel文件格式嗎?
是的,IronXL支援多種Excel文件格式,包括.xls、.xlsx和.csv,提供了處理各類Excel文件的靈活性。
IronXL 適合處理大型 Excel 文件嗎?
是的,IronXL針對性能進行了優化,能夠有效地處理大型Excel文件,非常適合處理大量資料的應用。
IronXL與其他C# Excel操控程式庫相比如何?
IronXL提供了使用者友好的API,對Excel功能提供了全面的支援,且不需要安裝Excel,使其相比其他程式庫成為一個強而有力的選擇。




