如何在 C# 中使用 `StreamReader` 讀取 Excel 文件
StreamReader 無法讀取 Excel 檔案,因為它是設計用於純文字,而 Excel 檔案是複雜的二進位或 ZIP 壓縮的 XML 結構。 請改用 IronXL 程式庫,它提供 WorkBook.Load() 以正確讀取 Excel 檔案,無需依賴 Excel Interop。
許多 C# 開發人員在嘗試 讀取 Excel 表單檔案 時遇到一個常見挑戰:他們可信賴的 StreamReader,在文字檔上運作良好,但在 Excel 文件上卻莫名其妙地失敗。 如果您曾試著在 C# 中使用 StreamReader 讀取 Excel 檔案 而看到亂碼或例外,您並不孤單。 本教程說明為什麼 StreamReader 無法直接處理 Excel 檔案,並展示了使用 IronXL 無需 Excel Interop 的正確解決方案。
常常會出現困惑,因為 CSV 檔案,Excel 能開啟,而且 StreamReader 運作良好。 然而,真實的 Excel 檔案 (XLSX, XLS) 需要根本不同的方法。 理解這一區別將節省您數小時的除錯時間,並引導您找到正確的工具。 對於容器環境,選擇正確的程式庫對於 簡化部署 和避免複雜依賴關係至關重要。

為什麼 StreamReader 無法讀取 Excel 檔案?
StreamReader 是為純文字檔而設計,使用指定的編碼逐行讀取字元資料。 Excel 檔案,儘管看起來像試算表,實際上是複雜的二進位或 ZIP 壓縮的 XML 結構,StreamReader 無法解釋。 這一根本差異使 StreamReader 不適用於生產環境中的 處理 Excel 活頁簿。
using System;
using System.IO;
class Program
{
static void Main(string[] args)
{
// This code will NOT work - demonstrates the problem
try
{
using (StreamReader reader = new StreamReader("ProductData.xlsx"))
{
string content = reader.ReadLine(); // read data
Console.WriteLine(content); // Outputs garbled binary data
}
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
}
using System;
using System.IO;
class Program
{
static void Main(string[] args)
{
// This code will NOT work - demonstrates the problem
try
{
using (StreamReader reader = new StreamReader("ProductData.xlsx"))
{
string content = reader.ReadLine(); // read data
Console.WriteLine(content); // Outputs garbled binary data
}
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
}
Imports System
Imports System.IO
Module Program
Sub Main(args As String())
' This code will NOT work - demonstrates the problem
Try
Using reader As New StreamReader("ProductData.xlsx")
Dim content As String = reader.ReadLine() ' read data
Console.WriteLine(content) ' Outputs garbled binary data
End Using
Catch ex As Exception
Console.WriteLine($"Error: {ex.Message}")
End Try
End Sub
End Module
當您執行此程式碼片段時,而不是看到您的 試算表資料,您將遇到二進位字元如 "PK♥♦" 或類似符號。 這是因為 XLSX 檔案 是包含多個 XML 檔的 ZIP 档案,而 XLS 檔案使用專有的二進位格式。 StreamReader 期望純文字並嘗試將這些複雜結構解釋為字元,結果輸出沒有意義。 對於 容器化應用程式,這些二進位資料也可能導致編碼問題和意外崩潰。
當 StreamReader 試圖讀取 Excel 檔案時會發生什麼?
現代 Excel 活頁簿 的內部結構由多個組件一起打包構成。 當 StreamReader 遇到這些檔案時,它無法解析 工作簿元資料 或導航檔案結構。 相反,它試圖將原始位元組讀為文字,導致損壞和資料遺失。 這在自動化部署管道 中尤其有問題,那裡檔案處理必須可靠。

為何輸出會顯示為亂碼?
亂碼輸出是因為 Excel 檔案包含二進位標頭、壓縮算法和 XML 命名空間,然後 StreamReader 將其解釋為文字字元。 這些 複雜檔案結構 包括格式訊息、公式、以及單元格引用,這些都沒有有意義的文字表示形式。 DevOps 團隊經常在嘗試於 Linux 容器 中處理 Excel 檔案時遇到此問題,因為編碼差異會加劇該問題。

現代 Excel 檔案 (XLSX) 包含多個組件:工作表、樣式、共享字串 和關係,全被打包在一起。 這種複雜性需要專門了解 Excel 檔案結構 的程式庫,這使我們使用到 IronXL。 像 Kubernetes 這樣的容器編排平台受益於可以處理這些複雜性而無需外部依賴的程式庫。
如何使用 IronXL 讀取 Excel 檔案?
IronXL 提供了用於在 C# 中讀取 Excel 檔案的簡單解決方案。 與 StreamReader 不同,IronXL 了解 Excel 的內部結構,並提供直觀的方法來存取您的資料。 該程式庫支援 Windows、Linux、macOS 和 Docker 容器,這使得它成為現代跨平台應用程式的理想選擇。 其輕量級特性和最小的依賴關係使其成為 容器化部署 的完美選擇。

如何在我的容器環境中安裝 IronXL?
首先,通過 NuGet 套件管理器安裝 IronXL。 該程式庫的 容器友好設計 確保了 Docker 和 Kubernetes 環境的平穩整合。 不需要額外的系統依賴或本機程式庫,簡化了您的 部署管道:
Install-Package IronXL.Excel
對於 Docker 部署,您也可以在 Dockerfile 中直接包括 IronXL:
# Add to your Dockerfile
RUN dotnet add package IronXL.Excel --version 2024.12.5

讀取 Excel 資料的基本程式碼模式是什麼?
以下是如何使用全面的錯誤處理正確讀取 Excel 檔案,適合生產環境:
using IronXL;
using System;
using System.Linq;
class ExcelReader
{
public static void ReadExcelData(string filePath)
{
try
{
// Load the Excel file
WorkBook workbook = WorkBook.Load(filePath);
WorkSheet worksheet = workbook.DefaultWorkSheet;
// Read specific cell values with null checking
var cellA1 = worksheet["A1"];
if (cellA1 != null)
{
string cellValue = cellA1.StringValue;
Console.WriteLine($"Cell A1 contains: {cellValue}");
}
// Read a range of cells with LINQ
var range = worksheet["A1:C5"];
var nonEmptyCells = range.Where(cell => !cell.IsEmpty);
foreach (var cell in nonEmptyCells)
{
Console.WriteLine($"{cell.AddressString}: {cell.Text}");
}
// Get row and column counts for validation
int rowCount = worksheet.RowCount;
int columnCount = worksheet.ColumnCount;
Console.WriteLine($"Worksheet dimensions: {rowCount} rows × {columnCount} columns");
}
catch (Exception ex)
{
Console.WriteLine($"Error reading Excel file: {ex.Message}");
// Log to your monitoring system
}
}
}
using IronXL;
using System;
using System.Linq;
class ExcelReader
{
public static void ReadExcelData(string filePath)
{
try
{
// Load the Excel file
WorkBook workbook = WorkBook.Load(filePath);
WorkSheet worksheet = workbook.DefaultWorkSheet;
// Read specific cell values with null checking
var cellA1 = worksheet["A1"];
if (cellA1 != null)
{
string cellValue = cellA1.StringValue;
Console.WriteLine($"Cell A1 contains: {cellValue}");
}
// Read a range of cells with LINQ
var range = worksheet["A1:C5"];
var nonEmptyCells = range.Where(cell => !cell.IsEmpty);
foreach (var cell in nonEmptyCells)
{
Console.WriteLine($"{cell.AddressString}: {cell.Text}");
}
// Get row and column counts for validation
int rowCount = worksheet.RowCount;
int columnCount = worksheet.ColumnCount;
Console.WriteLine($"Worksheet dimensions: {rowCount} rows × {columnCount} columns");
}
catch (Exception ex)
{
Console.WriteLine($"Error reading Excel file: {ex.Message}");
// Log to your monitoring system
}
}
}
Imports IronXL
Imports System
Imports System.Linq
Class ExcelReader
Public Shared Sub ReadExcelData(filePath As String)
Try
' Load the Excel file
Dim workbook As WorkBook = WorkBook.Load(filePath)
Dim worksheet As WorkSheet = workbook.DefaultWorkSheet
' Read specific cell values with null checking
Dim cellA1 = worksheet("A1")
If cellA1 IsNot Nothing Then
Dim cellValue As String = cellA1.StringValue
Console.WriteLine($"Cell A1 contains: {cellValue}")
End If
' Read a range of cells with LINQ
Dim range = worksheet("A1:C5")
Dim nonEmptyCells = range.Where(Function(cell) Not cell.IsEmpty)
For Each cell In nonEmptyCells
Console.WriteLine($"{cell.AddressString}: {cell.Text}")
Next
' Get row and column counts for validation
Dim rowCount As Integer = worksheet.RowCount
Dim columnCount As Integer = worksheet.ColumnCount
Console.WriteLine($"Worksheet dimensions: {rowCount} rows × {columnCount} columns")
Catch ex As Exception
Console.WriteLine($"Error reading Excel file: {ex.Message}")
' Log to your monitoring system
End Try
End Sub
End Class
此程式碼成功載入您的 Excel 檔案並提供對 單元格值 的乾淨存取。 WorkBook.Load 方法 自動檢測文件格式 (XLSX、XLS、XLSM、CSV),並在內部處理所有複雜解析。 您可以使用熟悉的 Excel 註記如 "A1" 或 範圍 像 "A1:C5" 存取單元格,這使得程式碼對於任何熟悉 Excel 的人來說都很直觀。 錯誤處理確保您的容器在格式不正確的文件上不會崩潰。
IronXL 支援哪些文件格式以進行容器化部署?
IronXL 支援所有主要的 Excel 格式,無需 Microsoft Office 或 Interop 組件,使其成為 容器化環境 的理想選擇。 支援的格式包括:
如何從記憶體流讀取 Excel?
實際應用程式經常需要從流而非磁碟檔案處理 Excel 檔案。 常見的情境包括處理網頁上傳、從資料庫檢索檔案或從雲端儲存處理資料。 IronXL 使用內建流支援優雅地處理這些情況:
using IronXL;
using System.IO;
using System.Data;
using System.Threading.Tasks;
public class StreamProcessor
{
// Async method for container health checks
public async Task<bool> ProcessExcelStreamAsync(byte[] fileBytes)
{
try
{
using (MemoryStream stream = new MemoryStream(fileBytes))
{
// Load from stream asynchronously
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 DataTable for database operations
var dataTable = worksheet.ToDataTable(true); // true = use first row as headers
// Validate data integrity
if (dataTable.Rows.Count == 0)
{
Console.WriteLine("Warning: No data rows found");
return false;
}
Console.WriteLine($"Loaded {dataTable.Rows.Count} data rows");
Console.WriteLine($"Columns: {string.Join(", ", dataTable.Columns.Cast<DataColumn>().Select(c => c.ColumnName))}");
// Example: Process data for container metrics
foreach (DataRow row in dataTable.Rows)
{
// Your processing logic here
await ProcessRowAsync(row);
}
return true;
}
}
catch (Exception ex)
{
Console.WriteLine($"Stream processing error: {ex.Message}");
return false;
}
}
private async Task ProcessRowAsync(DataRow row)
{
// Simulate async processing
await Task.Delay(10);
}
}
using IronXL;
using System.IO;
using System.Data;
using System.Threading.Tasks;
public class StreamProcessor
{
// Async method for container health checks
public async Task<bool> ProcessExcelStreamAsync(byte[] fileBytes)
{
try
{
using (MemoryStream stream = new MemoryStream(fileBytes))
{
// Load from stream asynchronously
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 DataTable for database operations
var dataTable = worksheet.ToDataTable(true); // true = use first row as headers
// Validate data integrity
if (dataTable.Rows.Count == 0)
{
Console.WriteLine("Warning: No data rows found");
return false;
}
Console.WriteLine($"Loaded {dataTable.Rows.Count} data rows");
Console.WriteLine($"Columns: {string.Join(", ", dataTable.Columns.Cast<DataColumn>().Select(c => c.ColumnName))}");
// Example: Process data for container metrics
foreach (DataRow row in dataTable.Rows)
{
// Your processing logic here
await ProcessRowAsync(row);
}
return true;
}
}
catch (Exception ex)
{
Console.WriteLine($"Stream processing error: {ex.Message}");
return false;
}
}
private async Task ProcessRowAsync(DataRow row)
{
// Simulate async processing
await Task.Delay(10);
}
}
Imports IronXL
Imports System.IO
Imports System.Data
Imports System.Threading.Tasks
Public Class StreamProcessor
' Async method for container health checks
Public Async Function ProcessExcelStreamAsync(fileBytes As Byte()) As Task(Of Boolean)
Try
Using stream As New MemoryStream(fileBytes)
' Load from stream asynchronously
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 DataTable for database operations
Dim dataTable = worksheet.ToDataTable(True) ' True = use first row as headers
' Validate data integrity
If dataTable.Rows.Count = 0 Then
Console.WriteLine("Warning: No data rows found")
Return False
End If
Console.WriteLine($"Loaded {dataTable.Rows.Count} data rows")
Console.WriteLine($"Columns: {String.Join(", ", dataTable.Columns.Cast(Of DataColumn)().Select(Function(c) c.ColumnName))}")
' Example: Process data for container metrics
For Each row As DataRow In dataTable.Rows
' Your processing logic here
Await ProcessRowAsync(row)
Next
Return True
End Using
Catch ex As Exception
Console.WriteLine($"Stream processing error: {ex.Message}")
Return False
End Try
End Function
Private Async Function ProcessRowAsync(row As DataRow) As Task
' Simulate async processing
Await Task.Delay(10)
End Function
End Class
WorkBook.FromStream 方法 可以接收任何型別的流,不論是 FileStream 或網路流。 這種靈活性允許您直接從各種來源處理 Excel 檔案,而無需先將它們儲存到磁碟。範例還展示了將工作表資料轉換為 DataTable,整合無縫銜接於資料庫和資料綁定情境。 顯示的非同步模式是針對容器健康檢查和就緒探針的理想選擇。
支援 Excel 處理的流型別有哪些?
IronXL 支援所有 .NET 流型別,使其適用於各種部署情境:
MemoryStream:記憶體內部處理,無磁碟 I/OFileStream:具有可配置緩衝區大小的直接檔案存取NetworkStream:從遠程來源處理檔案CryptoStream:適用於加密的 Excel 檔案- GZipStream:在容器化環境中的壓縮資料處理

我應何時在容器化應用程式中使用流處理?
流處理在以下情況中特別有價值:
- 微服務:處理檔案而無需持久化儲存
- Serverless functions: AWS Lambda or Azure Functions
- API 端點:直接檔案上傳處理
- 訊息佇列:從佇列中處理 Excel 附件

流處理如何影響容器資源使用?
IronXL 的流處理針對 容器環境 進行了最佳化,具有最小的記憶體開銷。 該程式庫使用有效的記憶體管理技術,防止記憶體洩漏並減少垃圾回收壓力。 對於 大型 Excel 檔案,IronXL 提供選項來通過配置設置控制記憶體使用,使其適合於資源受限的容器。
如何在 Excel 和 CSV 之間轉換?
雖然 StreamReader 能夠處理 CSV 檔案,但往往需要在 Excel 和 CSV 格式之間進行轉換。 IronXL 通過針對生產環境優化的內建方法使這種轉換變得簡單:
using IronXL;
using System;
using System.IO;
public class FormatConverter
{
public static void ConvertExcelFormats()
{
try
{
// Load an Excel file and save as CSV with options
WorkBook workbook = WorkBook.Load("data.xlsx");
// Save with UTF-8 encoding for international character support
workbook.SaveAsCsv("output.csv", ";"); // Use semicolon as delimiter
// Load a CSV file with custom settings
WorkBook csvWorkbook = WorkBook.LoadCSV("input.csv", ",", "UTF-8");
csvWorkbook.SaveAs("output.xlsx", FileFormat.XLSX);
// Export specific worksheet to CSV
if (workbook.WorkSheets.Count > 0)
{
WorkSheet worksheet = workbook.WorkSheets[0];
worksheet.SaveAsCsv("worksheet1.csv");
// Advanced: Export only specific range
var dataRange = worksheet["A1:D100"];
// Process range data before export
foreach (var cell in dataRange)
{
if (cell.IsNumeric)
{
// Apply formatting for CSV output
cell.FormatString = "0.00";
}
}
}
Console.WriteLine("Conversion completed successfully");
}
catch (Exception ex)
{
Console.WriteLine($"Conversion error: {ex.Message}");
throw; // Re-throw for container orchestrator handling
}
}
}
using IronXL;
using System;
using System.IO;
public class FormatConverter
{
public static void ConvertExcelFormats()
{
try
{
// Load an Excel file and save as CSV with options
WorkBook workbook = WorkBook.Load("data.xlsx");
// Save with UTF-8 encoding for international character support
workbook.SaveAsCsv("output.csv", ";"); // Use semicolon as delimiter
// Load a CSV file with custom settings
WorkBook csvWorkbook = WorkBook.LoadCSV("input.csv", ",", "UTF-8");
csvWorkbook.SaveAs("output.xlsx", FileFormat.XLSX);
// Export specific worksheet to CSV
if (workbook.WorkSheets.Count > 0)
{
WorkSheet worksheet = workbook.WorkSheets[0];
worksheet.SaveAsCsv("worksheet1.csv");
// Advanced: Export only specific range
var dataRange = worksheet["A1:D100"];
// Process range data before export
foreach (var cell in dataRange)
{
if (cell.IsNumeric)
{
// Apply formatting for CSV output
cell.FormatString = "0.00";
}
}
}
Console.WriteLine("Conversion completed successfully");
}
catch (Exception ex)
{
Console.WriteLine($"Conversion error: {ex.Message}");
throw; // Re-throw for container orchestrator handling
}
}
}
Imports IronXL
Imports System
Imports System.IO
Public Class FormatConverter
Public Shared Sub ConvertExcelFormats()
Try
' Load an Excel file and save as CSV with options
Dim workbook As WorkBook = WorkBook.Load("data.xlsx")
' Save with UTF-8 encoding for international character support
workbook.SaveAsCsv("output.csv", ";") ' Use semicolon as delimiter
' Load a CSV file with custom settings
Dim csvWorkbook As WorkBook = WorkBook.LoadCSV("input.csv", ",", "UTF-8")
csvWorkbook.SaveAs("output.xlsx", FileFormat.XLSX)
' Export specific worksheet to CSV
If workbook.WorkSheets.Count > 0 Then
Dim worksheet As WorkSheet = workbook.WorkSheets(0)
worksheet.SaveAsCsv("worksheet1.csv")
' Advanced: Export only specific range
Dim dataRange = worksheet("A1:D100")
' Process range data before export
For Each cell In dataRange
If cell.IsNumeric Then
' Apply formatting for CSV output
cell.FormatString = "0.00"
End If
Next
End If
Console.WriteLine("Conversion completed successfully")
Catch ex As Exception
Console.WriteLine($"Conversion error: {ex.Message}")
Throw ' Re-throw for container orchestrator handling
End Try
End Sub
End Class
這些轉換在改變文件格式的同時保留了您的資料。 當 Excel 轉換為 CSV 時,IronXL 會預設拉平第一個工作表,但您可以指定要導出的工作表。 從 CSV 轉換為 Excel 建立一個格式良好的試算表,保留資料型別,並啟用未來的格式化和公式新增。
為什麼 DevOps 團隊需要 Excel 到 CSV 的轉換?
DevOps 團隊經常需要將 Excel 轉換為 CSV 用於:
格式轉換的性能影響是什麼?
IronXL 的格式轉換針對 容器化環境 進行了優化,具有:
- 流式轉換:大型文件處理而無需完全載入到記憶體
- 並行處理:多核利用以加快轉換
- 最小磁碟 I/O:記憶體內處理減少儲存需求
- 資源限制:Kubernetes 部署 的配置記憶體上限
這些優化確保您的容器即使在處理大型 Excel 檔案時也能保持一致性能。 該程式庫的高效記憶體管理可防止資源受限環境中出現 OOM 錯誤。
結論
StreamReader 無法處理 Excel 檔案源於純文字與 Excel 複雜文件結構之間的根本差異。 雖然 StreamReader 在 CSV 和其他文字格式中運作完美,但真實的 Excel 檔案需要像 IronXL 這樣可以理解其中的二進位和 XML 結構的專門程式庫。 對於 DevOps 團隊管理 容器化應用程式,選擇正確的程式庫對於維持可靠的 部署管道 至關重要。
IronXL 提供了一個優雅的解決方案,其直觀的 API、全面的格式支援和無縫的流處理能力。 無論您在構建 網頁應用程式、桌面軟體還是雲端服務,IronXL 均能可靠地處理所有平臺上的 Excel 檔案。 其 容器友好設計、極少依賴,以及出色的性能特性使其成為現代 DevOps 工作流程的理想選擇。

準備好開始正確地處理 Excel 檔案了嗎? 下載 IronXL 的免費試用以在您的環境中探索其功能。 該程式庫包含全面文件、程式碼範例,以及專為容器化環境設計的部署指南。
常見問題
為什麼StreamReader不能在C#中讀取Excel文件?
StreamReader設計用來讀取文字文件,缺乏處理Excel文件二進制格式的能力,這導致亂碼或異常。
什麼是IronXL?
IronXL是一個C#程式庫,允許開發者閱讀、寫入和操作Excel文件,而不需要Excel Interop,提供更高效可靠的解決方案。
IronXL如何改善C#中的Excel文件讀取?
IronXL透過提供存取Excel資料的方法,無需複雜的Interop編碼或處理文件格式細節,簡化了Excel文件的讀取過程。
我可以使用IronXL無需安裝Excel來讀取Excel文件嗎?
是的,IronXL不需要您的系統上安裝Microsoft Excel,這使其成為獨立處理C#中Excel文件的解決方案。
使用IronXL比使用Excel Interop有哪些優勢?
IronXL速度更快,不需要安裝Excel,並且降低了與Excel Interop常見的版本相容性問題的風險。
IronXL 適合處理大型 Excel 文件嗎?
是的,IronXL針對性能進行了優化,能夠有效地處理大型Excel文件,非常適合處理大量資料的應用。
IronXL支持讀取.xls和.xlsx格式嗎?
IronXL支持.xls和.xlsx格式,允許開發者無縫工作於各種Excel文件型別。
如何在我的C#項目中開始使用IronXL?
您可以通過在Visual Studio中的NuGet套件管理器安裝IronXL,然後將其整合到您的C#項目中來讀取和處理Excel文件。
IronXL的常見使用情況有哪些?
IronXL的常見使用情況包括從Excel文件中提取資料、生成報告、資料操作以及自動化C#應用中的Excel相關任務。
IronXL可以用於Web應用程式中嗎?
是的,IronXL可以用於桌面和Web應用程式中,提供了如何在專案中實現Excel處理功能的靈活性。




