跳至页脚内容
使用 IRONXL

如何在未安装 Excel 的情况下使用 C# 读取 OpenOffice Excel 文件

在C#中读取和处理OpenDocument电子表格 (ODS) 和Excel文件非常简单,使用正确的库可以轻松完成。 使用IronXL,您可以通过单个方法调用将任何XLS、XLSX、ODS或CSV文件加载到WorkBook对象中,不需要安装Microsoft Excel,也不需要COM注册,更没有Interop相关问题。 本指南将带您逐步完成每个步骤:安装软件包、加载文件、提取类型化的单元格值、处理命名工作表、处理合并单元格以及部署到Linux或容器化环境。

如何在.NET项目中安装IronXL?

NuGet软件包管理器安装

通过NuGet软件包管理器将IronXL添加到您的项目中。 在 Visual Studio 中打开软件包管理器控制台并运行:

Install-Package IronXL
dotnet add package IronXL
Install-Package IronXL
dotnet add package IronXL
SHELL

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}");
$vbLabelText   $csharpLabel

对于XLSX和XLS文件使用相同的调用——只需更改路径即可。 WorkBook.Load返回相同的强类型对象,无论源格式如何,因此您的代码保持一致,无论文件来自Microsoft Excel、LibreOffice或任何其他ODF兼容应用程序。

如何读取工作表中的每一行和单元格?

遍历行集合

遍历所有行和单元格是最常见的Excel处理任务——不论您是验证导入数据、转换记录还是将数据输入报告管道。IronXL在每个Rows集合:

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();
}
$vbLabelText   $csharpLabel

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"}");
$vbLabelText   $csharpLabel

当单元格包含公式时,IronXL评估它并通过相同的类型化属性返回计算结果。 您不需要调用单独的评估方法。 对于可能为空或包含不兼容类型的单元格,库返回该类型的默认值而不是抛出异常,从而简化输入验证逻辑。

IronXL单元格值属性及其等效的.NET类型
属性 .NET类型 当为空时返回 注意事项
`StringValue` `字符串` 空字符串 始终安全,可将任何单元格转换为文本
`IntValue` `int` `0` 截断小数
`DecimalValue` `decimal` `0m` 为财务数据保持精度
`DoubleValue` `double` `0.0` 用于科学或统计值
`BoolValue` `布尔` `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}");
$vbLabelText   $csharpLabel

当工作表名称在设计时已知时,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}");
}
$vbLabelText   $csharpLabel

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}");
}
$vbLabelText   $csharpLabel

加载后,您可以使用csvWorkbook.SaveAs("output.xlsx")将数据保存为XLSX。 这是CSV到Excel转换管道的常见模式——接收CSV文件,用计算列或格式化丰富它,并向用户返回格式化的XLSX报告。

对于制表符分隔文件或自定义分隔符,请使用WorkBook.LoadCSV("file.tsv", file翻译格式: ExcelFile翻译格式.TSV)显式指定格式。

IronXL中支持的输入文件格式
翻译格式 扩展名 生成者 注意事项
XLSX `.xlsx` Excel 2007+,LibreOffice 默认现代格式;基于XML
XLS `.xls` Excel 97--2003 二进制格式;完全读写支持
ODS `.ods` LibreOffice,OpenOffice OpenDocument电子表格标准
CSV `.csv` 任何应用程序 分隔符自动检测;无格式化
TSV `.tsv` 数据库导出 制表符分隔;显式指定格式

IronXL与Microsoft.Office.Interop.Excel如何比较?

Interop、Open XML SDK和IronXL并列

在.NET中用于Excel自动化最常见的替代方案是Microsoft.Office.Interop.Excel。 了解这些权衡有助于您为项目选择正确的工具。

Microsoft Interop封装Excel COM对象模型。 这意味着运行您代码的每台机器上必须安装Excel——包括Web服务器、构建代理和云VM。 COM对象的生命周期管理是手动的:您必须显式释放每个Workbook对象,否则Excel进程会在后台积累并消耗内存,直到服务器重启。 许可证也是一个问题:Office EULA禁止在许多场景中进行服务器端自动化。

IronXL避免了所有这些限制。 它是一个纯托管库,无需COM依赖。 WorkBook对象是一个标准的.NET类; 垃圾收集器处理清理。您可以在开发者笔记本电脑、Azure App Service、Docker容器或运行Linux的Raspberry Pi上运行相同的代码。

Microsoft的Open XML SDK是另一种选择。它提供直接访问OOXML文件格式,无需Excel,但操作级别非常低——您直接操作XML元素。 读取单个单元格值需要导航共享字符串表、单元格引用和样式索引。 IronXL将所有这些包装成单行sheet["A1"].StringValue调用,这在本指南中已多次展示。

如何将Excel处理部署到Linux和Docker?

服务器部署是IronXL不依赖Excel的优势最明显的地方。 您在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"]
SHELL

对于Azure Functions和AWS Lambda,IronXL可以在托管运行时内无需额外配置地工作。 冷启动的开销很小,因为没有COM初始化步骤。

线程安全是内置的:多个线程可以同时打开不同的WorkBook实例而无需协调。 如果您需要并行处理数千个文件——例如,在一个摄取用户上传电子表格的后台作业中——您可以在一组Task.WhenAll,而不会有损坏的风险。

内存使用保持可预测,因为IronXL仅将请求的工作表加载到内存中,而不是在初始化时加载整个工作簿。 对于非常大的文件,这一区别很重要:一个具有十个50MB工作表的工作簿不需要500MB内存来读取一个单一工作表。 IronXL性能文档涵盖了其他处理高容量文件处理场景的策略。

接下来您的步骤是什么?

在您的项目中验证IronXL的最快方法是安装NuGet包,并对您环境中的真实文件运行本指南中的示例。 当您准备好用于生产时,免费试用许可证解锁所有功能,无需代码更改。

探索补充文件读取的相关IronXL功能:

有关许可、跨平台支持或特定文件格式要求的问题,IronXL支持团队通过实时聊天和电子邮件提供服务。

立即开始使用 IronXL。
green arrow pointer

常见问题解答

如何在未安装Excel的情况下,用C#读取OpenOffice Excel文件?

您可以使用IronXL库在 C# 中读取 OpenOffice Excel 文件,而无需在服务器上安装 Excel。它允许您使用单个 WorkBook.Load 方法调用高效地加载 XLS、XLSX、ODS 和 CSV 文件。

IronXL可以处理哪些类型的Excel文件?

IronXL支持处理各种 Excel 文件格式,包括 XLS、XLSX、ODS(OpenDocument Spreadsheet)和 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,这简化了部署并降低了维护需求。IronXLIronXL在 Windows、Linux、macOS 以及 Docker 容器中运行。

IronXL是否支持处理CSV文件?

是的, IronXL完全支持使用相同的 WorkBook.Load API 读取和处理 CSV 文件以及其他 Excel 格式(如 XLS、XLSX 和 ODS)。

对于.NET开发人员来说,使用IronXL有哪些好处?

IronXL为.NET开发人员提供了一个易于使用的库,用于读取、写入和操作 Excel 文件,而无需 Microsoft Excel,通过简洁、强类型的 API 提高生产力并缩短开发时间。

IronXL如何提高处理 Excel 文件的效率?

IronXL通过消除对 Excel 软件的需求来提高效率,提供类型化的单元格值访问器、线程安全的并发处理以及直接在.NET应用程序中处理 Excel 文件的轻量级解决方案。

Curtis Chau
技术作家

Curtis Chau 拥有卡尔顿大学的计算机科学学士学位,专注于前端开发,精通 Node.js、TypeScript、JavaScript 和 React。他热衷于打造直观且美观的用户界面,喜欢使用现代框架并创建结构良好、视觉吸引力强的手册。

除了开发之外,Curtis 对物联网 (IoT) 有浓厚的兴趣,探索将硬件和软件集成的新方法。在空闲时间,他喜欢玩游戏和构建 Discord 机器人,将他对技术的热爱与创造力相结合。

Iron Support Team

We're online 24 hours, 5 days a week.
Chat
Email
Call Me