如何在未安裝 Excel 的情況下使用 C# 讀取 OpenOffice Excel 文件
在C#中讀取和處理OpenDocument Spreadsheet (ODS)和Excel檔案相當簡單,只要您使用正確的程式庫。 使用 IronXL,您可以將任何XLS、XLSX、ODS或CSV檔案載入到WorkBook物件中,只需調用一個方法——不需要安裝Microsoft Excel,不需要COM註冊,也不會有Interop相關問題。 本指南將引導您完成每個步驟:安裝套件、載入檔案、提取有型別的儲存格值、處理命名的工作表、處理合併儲存格,以及部署到Linux或容器化環境。
如何在.NET專案中安裝IronXL?
NuGet套件管理器安裝
通過NuGet套件管理器將IronXL新增到您的專案中。 在Visual Studio中打開Package Manager Console並運行:
Install-Package IronXL.Excel
IronXL針對.NET 8、.NET 9、.NET 10、.NET Framework 4.6.2+和.NET Standard 2.0,因此不論是現代或是舊版程式碼基礎都可以適用。安裝套件後,請在任何處理電子錶格的檔案頂部新增using IronXL;指令,然後您即可準備載入您的第一本工作簿。
對於Azure Functions、Docker容器或Linux託管的API,不需要額外的運行時配置。 該程式庫內部綑綁了其所需的一切,不會調用Excel的自動化元件。
如何在C#中載入OpenOffice或Excel檔案?
IronXL透過WorkBook.Load方法對ODS、XLS、XLSX和CSV檔案進行相同處理。 您可以傳遞一個絕對或相對的文件路徑,然後程式庫會從文件頭檢測格式——而不只是檔案擴展名。 這意味著,即使檔案從.xlsx也能正確讀取。
using IronXL;
// Load an OpenDocument Spreadsheet (.ods) produced by LibreOffice Calc or OpenOffice
WorkBook workbook = WorkBook.Load("quarterly_report.ods");
// Access the first worksheet by index
WorkSheet sheet = workbook.WorkSheets[0];
// Read a cell value
string companyName = sheet["A1"].StringValue;
int recordCount = sheet["B1"].IntValue;
Console.WriteLine($"Company : {companyName}");
Console.WriteLine($"Records : {recordCount}");
using IronXL;
// Load an OpenDocument Spreadsheet (.ods) produced by LibreOffice Calc or OpenOffice
WorkBook workbook = WorkBook.Load("quarterly_report.ods");
// Access the first worksheet by index
WorkSheet sheet = workbook.WorkSheets[0];
// Read a cell value
string companyName = sheet["A1"].StringValue;
int recordCount = sheet["B1"].IntValue;
Console.WriteLine($"Company : {companyName}");
Console.WriteLine($"Records : {recordCount}");
Imports IronXL
' Load an OpenDocument Spreadsheet (.ods) produced by LibreOffice Calc or OpenOffice
Dim workbook As WorkBook = WorkBook.Load("quarterly_report.ods")
' Access the first worksheet by index
Dim sheet As WorkSheet = workbook.WorkSheets(0)
' Read a cell value
Dim companyName As String = sheet("A1").StringValue
Dim recordCount As Integer = sheet("B1").IntValue
Console.WriteLine($"Company : {companyName}")
Console.WriteLine($"Records : {recordCount}")
對於XLSX和XLS檔案也是一樣的調用,只需更改路徑。 WorkBook.Load不論來源格式如何,都會返回相同的強型別物件,因此無論檔案來自Microsoft Excel、LibreOffice還是任何其他ODF符合應用程式,您其餘的程式碼都能保持一樣。
您如何讀取工作表中的每一行和每一個儲存格?
遍歷行集合
遍歷所有行和儲存格是最常見的Excel處理任務——無論您是在驗證導入資料、轉換記錄,還是供報告管道使用。IronXL在每個WorkSheet集合:
using IronXL;
WorkBook workbook = WorkBook.Load("customers.xlsx");
WorkSheet worksheet = workbook.WorkSheets[0];
Console.WriteLine($"Total rows : {worksheet.RowCount}");
Console.WriteLine($"Total columns : {worksheet.ColumnCount}");
Console.WriteLine();
foreach (var row in worksheet.Rows)
{
foreach (var cell in row)
{
if (!cell.IsEmpty)
Console.Write($"{cell.StringValue,-20}");
}
Console.WriteLine();
}
using IronXL;
WorkBook workbook = WorkBook.Load("customers.xlsx");
WorkSheet worksheet = workbook.WorkSheets[0];
Console.WriteLine($"Total rows : {worksheet.RowCount}");
Console.WriteLine($"Total columns : {worksheet.ColumnCount}");
Console.WriteLine();
foreach (var row in worksheet.Rows)
{
foreach (var cell in row)
{
if (!cell.IsEmpty)
Console.Write($"{cell.StringValue,-20}");
}
Console.WriteLine();
}
Imports IronXL
Dim workbook As WorkBook = WorkBook.Load("customers.xlsx")
Dim worksheet As WorkSheet = workbook.WorkSheets(0)
Console.WriteLine($"Total rows : {worksheet.RowCount}")
Console.WriteLine($"Total columns : {worksheet.ColumnCount}")
Console.WriteLine()
For Each row In worksheet.Rows
For Each cell In row
If Not cell.IsEmpty Then
Console.Write($"{cell.StringValue,-20}")
End If
Next
Console.WriteLine()
Next
ColumnCount屬性只返回已填充的範圍——不包括空的尾行和列。 在讀取前檢查cell.IsEmpty可阻止在稀疏表上的不必要處理。
對於大型檔案,考慮使用基於範圍的存取(worksheet["A1:D500"])而不是整張表迭代。 這限制了載入記憶體的儲存格並在您僅需資料子集時加速了處理。
您如何從儲存格中提取有型別的值?
型別屬性存取器
現實世界的電子錶格中的儲存格包含字串、整數、十進位數、布林值和日期。 IronXL公開了專用的型別屬性,因此您永遠不需要手動解析原始字串:
using IronXL;
WorkBook workbook = WorkBook.Load("inventory.xlsx");
WorkSheet sheet = workbook.GetWorkSheet("Products");
// Typed accessors handle conversion automatically
string productName = sheet["A2"].StringValue;
int quantity = sheet["B2"].IntValue;
decimal unitPrice = sheet["C2"].DecimalValue;
bool inStock = sheet["D2"].BoolValue;
DateTime? lastAudit = sheet["E2"].DateTimeValue;
Console.WriteLine($"Product : {productName}");
Console.WriteLine($"Qty : {quantity}");
Console.WriteLine($"Price : {unitPrice:C}");
Console.WriteLine($"In Stock : {inStock}");
Console.WriteLine($"Audited : {lastAudit?.ToString("d") ?? "Never"}");
using IronXL;
WorkBook workbook = WorkBook.Load("inventory.xlsx");
WorkSheet sheet = workbook.GetWorkSheet("Products");
// Typed accessors handle conversion automatically
string productName = sheet["A2"].StringValue;
int quantity = sheet["B2"].IntValue;
decimal unitPrice = sheet["C2"].DecimalValue;
bool inStock = sheet["D2"].BoolValue;
DateTime? lastAudit = sheet["E2"].DateTimeValue;
Console.WriteLine($"Product : {productName}");
Console.WriteLine($"Qty : {quantity}");
Console.WriteLine($"Price : {unitPrice:C}");
Console.WriteLine($"In Stock : {inStock}");
Console.WriteLine($"Audited : {lastAudit?.ToString("d") ?? "Never"}");
Imports IronXL
Dim workbook As WorkBook = WorkBook.Load("inventory.xlsx")
Dim sheet As WorkSheet = workbook.GetWorkSheet("Products")
' Typed accessors handle conversion automatically
Dim productName As String = sheet("A2").StringValue
Dim quantity As Integer = sheet("B2").IntValue
Dim unitPrice As Decimal = sheet("C2").DecimalValue
Dim inStock As Boolean = sheet("D2").BoolValue
Dim lastAudit As DateTime? = sheet("E2").DateTimeValue
Console.WriteLine($"Product : {productName}")
Console.WriteLine($"Qty : {quantity}")
Console.WriteLine($"Price : {unitPrice:C}")
Console.WriteLine($"In Stock : {inStock}")
Console.WriteLine($"Audited : {If(lastAudit?.ToString("d"), "Never")}")
當儲存格包含公式時,IronXL對其進行計算並通過相同的型別屬性返回計算結果。 您不需要調用單獨的計算方法。 對於可能是空值或包含不相容型別的儲存格,程式庫會返回該型別的預設值而不拋出異常,從而簡化了輸入驗證邏輯。
| 屬性 | .NET型別 | 空時返回 | 註釋 |
|---|---|---|---|
StringValue |
string |
空字串 | 總是安全的;將任何儲存格轉換為文字 |
IntValue |
int |
0 |
截斷十進位數 |
DecimalValue |
decimal |
0m |
保留財務資料的精度 |
DoubleValue |
double |
0.0 |
用於科學或統計值 |
BoolValue |
bool |
false |
讀取Excel中的TRUE/FALSE儲存格 |
DateTimeValue |
DateTime? |
null |
可空——使用前檢查 |
如何處理多個命名的工作表?
按名稱、索引或迭代存取
企業電子錶格通常包含多個命名的頁籤——每個月一個、每個區域一個或每條產品線一個。IronXL提供多種方法來存取它們:
using IronXL;
WorkBook workbook = WorkBook.Load("annual_sales.xlsx");
// Option 1: access by name (throws if the sheet does not exist)
WorkSheet januarySheet = workbook.GetWorkSheet("January");
// Option 2: iterate all sheets in the workbook
foreach (WorkSheet ws in workbook.WorkSheets)
{
Console.WriteLine($"Sheet: {ws.Name} | Rows: {ws.RowCount}");
// Read the header row from each sheet
string header = ws["A1"].StringValue;
Console.WriteLine($" Header: {header}");
}
// Option 3: access by zero-based index
WorkSheet lastSheet = workbook.WorkSheets[workbook.WorkSheets.Count - 1];
Console.WriteLine($"Last sheet: {lastSheet.Name}");
using IronXL;
WorkBook workbook = WorkBook.Load("annual_sales.xlsx");
// Option 1: access by name (throws if the sheet does not exist)
WorkSheet januarySheet = workbook.GetWorkSheet("January");
// Option 2: iterate all sheets in the workbook
foreach (WorkSheet ws in workbook.WorkSheets)
{
Console.WriteLine($"Sheet: {ws.Name} | Rows: {ws.RowCount}");
// Read the header row from each sheet
string header = ws["A1"].StringValue;
Console.WriteLine($" Header: {header}");
}
// Option 3: access by zero-based index
WorkSheet lastSheet = workbook.WorkSheets[workbook.WorkSheets.Count - 1];
Console.WriteLine($"Last sheet: {lastSheet.Name}");
Imports IronXL
Dim workbook As WorkBook = WorkBook.Load("annual_sales.xlsx")
' Option 1: access by name (throws if the sheet does not exist)
Dim januarySheet As WorkSheet = workbook.GetWorkSheet("January")
' Option 2: iterate all sheets in the workbook
For Each ws As WorkSheet In workbook.WorkSheets
Console.WriteLine($"Sheet: {ws.Name} | Rows: {ws.RowCount}")
' Read the header row from each sheet
Dim header As String = ws("A1").StringValue
Console.WriteLine($" Header: {header}")
Next
' Option 3: access by zero-based index
Dim lastSheet As WorkSheet = workbook.WorkSheets(workbook.WorkSheets.Count - 1)
Console.WriteLine($"Last sheet: {lastSheet.Name}")
當頁籤名稱在設計時已知時,GetWorkSheet是最明確的選擇。 對於動態處理——頁籤名稱來自使用者輸入或配置時,迭代WorkSheets集合能防止硬編碼假設,並妥善處理頁籤數量不一的工作簿。
如何處理合併儲存格及格式化區域?
報告和儀表板通常使用合併儲存格來做標題、分組標籤和摘要行。 IronXL從合併區域的左上儲存格中讀取值,正如Excel顯示的那樣:
using IronXL;
WorkBook workbook = WorkBook.Load("report_with_merges.xlsx");
WorkSheet sheet = workbook.DefaultWorkSheet;
// The merged region A1:D1 stores its value in cell A1
string reportTitle = sheet["A1"].StringValue;
Console.WriteLine($"Report title : {reportTitle}");
// Read cell formatting metadata
var titleCell = sheet["A1"];
Console.WriteLine($"Bold : {titleCell.Style.Font.Bold}");
Console.WriteLine($"Font size : {titleCell.Style.Font.Height}");
// Scan an entire column for non-empty section headers
foreach (var cell in sheet["A1:A100"])
{
if (!cell.IsEmpty && cell.Style.Font.Bold)
Console.WriteLine($"Section header at {cell.AddressString}: {cell.StringValue}");
}
using IronXL;
WorkBook workbook = WorkBook.Load("report_with_merges.xlsx");
WorkSheet sheet = workbook.DefaultWorkSheet;
// The merged region A1:D1 stores its value in cell A1
string reportTitle = sheet["A1"].StringValue;
Console.WriteLine($"Report title : {reportTitle}");
// Read cell formatting metadata
var titleCell = sheet["A1"];
Console.WriteLine($"Bold : {titleCell.Style.Font.Bold}");
Console.WriteLine($"Font size : {titleCell.Style.Font.Height}");
// Scan an entire column for non-empty section headers
foreach (var cell in sheet["A1:A100"])
{
if (!cell.IsEmpty && cell.Style.Font.Bold)
Console.WriteLine($"Section header at {cell.AddressString}: {cell.StringValue}");
}
Imports IronXL
Dim workbook As WorkBook = WorkBook.Load("report_with_merges.xlsx")
Dim sheet As WorkSheet = workbook.DefaultWorkSheet
' The merged region A1:D1 stores its value in cell A1
Dim reportTitle As String = sheet("A1").StringValue
Console.WriteLine($"Report title : {reportTitle}")
' Read cell formatting metadata
Dim titleCell = sheet("A1")
Console.WriteLine($"Bold : {titleCell.Style.Font.Bold}")
Console.WriteLine($"Font size : {titleCell.Style.Font.Height}")
' Scan an entire column for non-empty section headers
For Each cell In sheet("A1:A100")
If Not cell.IsEmpty AndAlso cell.Style.Font.Bold Then
Console.WriteLine($"Section header at {cell.AddressString}: {cell.StringValue}")
End If
Next
Style屬性樹反映出OOXML SpreadsheetML規範的結構,因此如果您曾使用Open XML SDK,屬性名稱會感覺熟悉。 然而,IronXL將所有的複雜性包裝在一個乾淨的API中,您不需要進行任何XML操作。
如何使用相同的API導入CSV檔案?
由資料庫匯出、CRM系統和舊版應用程式生成的CSV檔案可以利用相同的WorkBook.Load調用讀取。 IronXL從檔案內容中推斷分隔符:
using IronXL;
// Load a comma-separated values file -- same method, same API
WorkBook csvWorkbook = WorkBook.Load("export.csv");
WorkSheet csvSheet = csvWorkbook.DefaultWorkSheet;
Console.WriteLine($"CSV rows loaded: {csvSheet.RowCount}");
// Process rows exactly like any other worksheet
foreach (var row in csvSheet.Rows)
{
string id = row[0].StringValue;
string name = row[1].StringValue;
Console.WriteLine($"{id,-10} {name}");
}
using IronXL;
// Load a comma-separated values file -- same method, same API
WorkBook csvWorkbook = WorkBook.Load("export.csv");
WorkSheet csvSheet = csvWorkbook.DefaultWorkSheet;
Console.WriteLine($"CSV rows loaded: {csvSheet.RowCount}");
// Process rows exactly like any other worksheet
foreach (var row in csvSheet.Rows)
{
string id = row[0].StringValue;
string name = row[1].StringValue;
Console.WriteLine($"{id,-10} {name}");
}
Imports IronXL
' Load a comma-separated values file -- same method, same API
Dim csvWorkbook As WorkBook = WorkBook.Load("export.csv")
Dim csvSheet As WorkSheet = csvWorkbook.DefaultWorkSheet
Console.WriteLine($"CSV rows loaded: {csvSheet.RowCount}")
' Process rows exactly like any other worksheet
For Each row In csvSheet.Rows
Dim id As String = row(0).StringValue
Dim name As String = row(1).StringValue
Console.WriteLine($"{id,-10} {name}")
Next
載入後,您可以使用csvWorkbook.SaveAs("output.xlsx")將資料保存為XLSX。 這是一種常見的CSV到Excel轉換管道模式——接收CSV檔案,使用計算欄或格式進行豐富化,並將格式化的XLSX報告返回給使用者。
對於製表符分隔文件或使用者自定義分隔符,請使用WorkBook.LoadCSV("file.tsv", fileFormat: ExcelFileFormat.TSV)明確指定格式。
| 格式 | 擴展名 | 生成者 | 註釋 |
|---|---|---|---|
| XLSX | .xlsx |
Excel 2007+,LibreOffice | 預設現代格式;基於XML |
| XLS | .xls |
Excel 97--2003 | 二進位格式;完全讀寫支持 |
| ODS | .ods |
LibreOffice,OpenOffice | OpenDocument Spreadsheet標準 |
| CSV | .csv |
任何應用程式 | 分隔符自動檢測;沒有格式 |
| TSV | .tsv |
資料庫匯出 | 製表符分隔;顯式指定格式 |
IronXL與Microsoft.Office.Interop.Excel相比如何?
Interop、Open XML SDK和IronXL並排比較
最常見的IronXL替代品是用於.NET的Microsoft.Office.Interop.Excel。 了解利弊有助於您為專案選擇合適的工具。
Microsoft Interop包裹了Excel COM物件模型。 這意味著Excel必須安裝在每臺運行您的程式碼的機器上——包括網頁伺服器、構建代理和雲端VM。 COM物件生命週期管理是手動的:您必須顯式地釋放每個Workbook物件,否則Excel進程會在背景中積累並消耗記憶體,直到伺服器重啟。 許可證也是一個考慮因素:Office終端使用者許可協議在許多情況下禁止伺服器端自動化。
IronXL避免了所有這些限制。 它是純管理程式庫,無需COM依賴。 WorkBook物件是標準.NET類; 垃圾收集器處理清理。您可以在開發者筆記本電腦、Azure App Service、Docker容器,或在運行Linux的樹莓派上運行相同的程式碼。
來自Microsoft的Open XML SDK是另一個選擇。它提供對OOXML文件格式的直接存取,而無需Excel,但它操作在非常低的層次上——您需直接操控XML元素。 讀取單個儲存格值需要導航共享字串表、儲存格引用和樣式索引。 IronXL將所有這些整合成本指南中所示的單行sheet["A1"].StringValue調用。
如何將Excel處理部署到Linux和Docker?
伺服器部署中IronXL的獨立性益顯得尤為有價值。 您在Windows上編寫的程式碼,無需更改即可在Ubuntu、Alpine Linux或macOS上運行。 對於容器化部署,您的Dockerfile不需要特殊配置:
# Standard .NET runtime image -- no Office packages needed
FROM mcr.microsoft.com/dotnet/runtime:10.0
WORKDIR /app
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "ExcelProcessor.dll"]
# Standard .NET runtime image -- no Office packages needed
FROM mcr.microsoft.com/dotnet/runtime:10.0
WORKDIR /app
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "ExcelProcessor.dll"]
對於Azure Functions和AWS Lambda,IronXL在托管運行時中工作,而不需任何額外配置。 冷啟動開銷最小,因為沒有COM初始化步驟。
執行緒安全是內建的:多個執行緒可以同時打開不同的WorkBook實例,而無需協調。 如果您需要並行處理數千個文件——例如在背景工作中處理使用者上傳的電子錶格——您可以跨Task.WhenAll,而無需擔心損壞風險。
記憶體使用保持預測性,因為IronXL僅將請求的工作表載入記憶體,而不是在初始化時將整個工作簿載入。 對於非常大的檔案,這一區別尤為重要:一本有十個50MB的工作表的工作簿並不需要500MB的RAM來讀取單個工作表。 IronXL性能文件涵蓋了其他處理高容量文件處理場景的策略。
您接下來的步驟是什麼?
驗證IronXL在您的專案中最迅速的方法是安裝NuGet套件,並在您的環境中的真實檔案上運行本指南中的範例。 一份免費試用授權解鎖所有功能,當您準備進入生產階段時無需更改程式碼。
探索補充檔案讀取的相關IronXL功能:
- 用C#寫入和建立Excel檔案——以程式方式生成報告和資料導出
- 格式化儲存格、行和列——在程式碼中應用顏色、字型和邊框
- 在C#中處理Excel公式——讀和寫公式儲存格
- 在.NET中將Excel轉換為PDF——從電子錶格資料生成PDF報告
- IronXL API文件——所有類和方法的完整參考
- IronXL授權和定價——對於單個開發者和企業團隊的選項
- IronXL NuGet頁面——所有專案型別的安裝說明
- IronXL教程——常見使用案例的分步指南
- 將IronXL與EPPlus比較——並行功能和授權比較
- IronXL產品首頁——功能概述和入門資源
關於授權、跨平台支持或特定檔案格式的要求問題,IronXL支持團隊可以通過即時聊天和電子郵件提供幫助。
常見問題
我如何在未安裝Excel的情況下在C#中讀取Open Office Excel文件?
您可以使用IronXL程式庫在不需要在伺服器上安裝Excel的情況下,在C#中讀取Open Office Excel文件。它允許您通過單一的WorkBook.Load方法調用來高效載入XLS、XLSX、ODS和CSV文件。
使用IronXL可以處理哪些型別的Excel文件?
IronXL支持處理各種Excel文件格式,包括XLS、XLSX、ODS(OpenDocument電子表格)和CSV文件,使其能應對不同電子表格應用程式的需求,包括LibreOffice和OpenOffice。
為何開發人員應該使用IronXL而非Microsoft Interop來讀取Excel文件?
IronXL提供了一種更簡單和更高效的Excel文件處理方式,不需要Microsoft Excel或COM Interop,從而減少了生產伺服器上的複雜性和開銷,並支持Linux和Docker部署。
IronXL可以處理在除MS Excel外的其他電子表格應用程式中建立的文件嗎?
是的,IronXL能夠讀取和處理來自其他電子表格應用程式的文件,例如OpenOffice Calc和LibreOffice Calc,這使其成為開發人員處理ODS和ODF相容格式時的靈活工具。
在生產伺服器上使用IronXL是否需要安裝Excel?
不需要,使用IronXL時,您無需在生產伺服器上安裝Excel,從而簡化了部署並減少了維護要求。 IronXL可在Windows、Linux、macOS及Docker容器內運行。
IronXL支持處理CSV文件嗎?
是的,IronXL完全支持閱讀和處理CSV文件,以及使用相同的WorkBook.Load API載入其他Excel格式如XLS、XLSX和ODS。
對於.NET開發人員來說,使用IronXL有哪些好處?
IronXL為.NET開發者提供了一個易於使用的程式庫,允許在不需要Microsoft Excel的情況下讀寫及操作Excel文件,提高了生產力並通過清晰、強型別的API縮短了開發時間。
IronXL如何提高處理Excel文件的效率?
IronXL通過消除Excel軟體的需求,提高了效率,提供了型別化的單元格值存取器、執行緒安全的並發處理,以及直接在.NET應用程式中處理Excel文件的輕量級解決方案。




