Skip to footer content
USING IRONXL

How to Read Excel Files in C# Using IronXL

Reading Excel files in C# applications is a recurring requirement for business software, data processing pipelines, and reporting systems. Traditional approaches using Microsoft Office Interop require Excel installed on every server or workstation, creating brittle dependencies that complicate deployment and licensing. IronXL removes that dependency entirely -- your application reads XLSX, XLS, CSV, and other spreadsheet formats without Office installed anywhere in the environment.

This tutorial walks you through every technique you need: installing the library, loading workbooks, extracting typed cell values, iterating rows and columns, running aggregate calculations, and building a complete employee-data reader. All examples use C# with top-level statements targeting .NET 10.


How Do You Install IronXL for Excel Processing?

Open the NuGet Package Manager Console in Visual Studio and run the following command to add IronXL to your project. Alternatively, if you prefer working from a terminal, use the .NET CLI command shown on the second line:

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

The package installs in seconds and adds a single managed assembly reference to your project. No COM registration, no Office Primary Interop Assemblies, and no version-specific Excel dependencies to manage.

After installation, add the using directive at the top of each file that works with spreadsheet data:

using IronXL;
using IronXL;
$vbLabelText   $csharpLabel

That single namespace gives you access to WorkBook, WorkSheet, cell ranges, typed value properties, aggregate functions, and every other IronXL type. The NuGet Gallery page for IronXL.Excel lists every available release and its full dependency tree.


What Excel File Formats Does IronXL Support?

Understanding the formats your application must handle shapes both the API calls you make and the storage decisions your project adopts.

XLSX -- the default format since Excel 2007 -- is a ZIP archive of XML files. It supports more than one million rows, rich formatting, pivot tables, and named ranges. Most modern data pipelines produce XLSX output, so this is the format you encounter most often.

XLS is the legacy binary format used by Excel 2003 and earlier. Some enterprise systems still export XLS, so reliable support for this format matters when integrating with older infrastructure. IronXL reads XLS files without any special configuration on your part.

XLSM extends XLSX with macro support. IronXL reads the spreadsheet data from XLSM files even if it does not execute the embedded VBA code, which is the correct behavior for server-side data extraction.

CSV and TSV are plain-text tabular formats widely used for data interchange between systems. WorkBook.LoadCSV handles comma-separated files, and IronXL returns the same WorkBook object your code already knows how to navigate, keeping your data-reading logic uniform regardless of the source format.

IronXL detects the file format automatically from the file extension when you call WorkBook.Load. You do not need to specify the format explicitly in most cases, which simplifies code that must handle inputs arriving from multiple sources.

Supported Excel file formats in IronXL
Format Extension Load Method Notes
Open XML Workbook .xlsx WorkBook.Load Default modern format
Legacy Binary .xls WorkBook.Load Excel 2003 and earlier
Macro-enabled .xlsm WorkBook.Load Data read; macros not executed
Comma-separated .csv WorkBook.LoadCSV Optimized CSV parser
Tab-separated .tsv WorkBook.Load Tab delimiter variant

How Do You Load and Read an Excel Workbook?

The WorkBook.Load method is the entry point for all file-based operations. Pass the file path and IronXL returns a fully populated workbook object you can immediately query:

using IronXL;

// Load the workbook; format is detected automatically
WorkBook workbook = WorkBook.Load("Employees.xlsx");

// Access the first worksheet
WorkSheet sheet = workbook.DefaultWorkSheet;

// Read a single cell by A1 address
string companyName = sheet["A1"].StringValue;
Console.WriteLine($"Company: {companyName}");

// Access sheets by name or by zero-based index
WorkSheet byName  = workbook.GetWorkSheet("Sales");
WorkSheet byIndex = workbook.WorkSheets[1];

// Load a password-protected file
WorkBook secured = WorkBook.Load("Confidential.xlsx", "p@ssw0rd");
using IronXL;

// Load the workbook; format is detected automatically
WorkBook workbook = WorkBook.Load("Employees.xlsx");

// Access the first worksheet
WorkSheet sheet = workbook.DefaultWorkSheet;

// Read a single cell by A1 address
string companyName = sheet["A1"].StringValue;
Console.WriteLine($"Company: {companyName}");

// Access sheets by name or by zero-based index
WorkSheet byName  = workbook.GetWorkSheet("Sales");
WorkSheet byIndex = workbook.WorkSheets[1];

// Load a password-protected file
WorkBook secured = WorkBook.Load("Confidential.xlsx", "p@ssw0rd");
$vbLabelText   $csharpLabel

The DefaultWorkSheet property returns the first sheet, covering the majority of single-sheet files. When your file contains multiple sheets, GetWorkSheet retrieves by name and WorkSheets[n] retrieves by zero-based index. The WorkBook API reference documents every overload and property on the workbook object.

VB.NET Reading Excel Files Using IronXL: A Step-by-Step Guide Without Microsoft Office: Image 1 - Installation

Input

VB.NET Reading Excel Files Using IronXL: A Step-by-Step Guide Without Microsoft Office: Image 2 - Sample Excel Input

Output

VB.NET Reading Excel Files Using IronXL: A Step-by-Step Guide Without Microsoft Office: Image 3 - Console Output


How Do You Read Typed Cell Values from Excel?

Every cell in IronXL exposes typed properties that return values in the exact data type you need -- no manual parsing or casting required. The typed properties handle coercion from the underlying cell representation automatically:

using IronXL;

WorkBook workbook = WorkBook.Load("Employees.xlsx");
WorkSheet sheet   = workbook.DefaultWorkSheet;

// Extract typed values from row 2
int      employeeId = sheet["A2"].IntValue;
string   name       = sheet["B2"].StringValue;
string   department = sheet["C2"].StringValue;
decimal  salary     = sheet["D2"].DecimalValue;
DateTime hireDate   = sheet["E2"].DateTimeValue;

Console.WriteLine($"ID:         {employeeId}");
Console.WriteLine($"Name:       {name}");
Console.WriteLine($"Department: {department}");
Console.WriteLine($"Salary:     {salary:C}");
Console.WriteLine($"Hired:      {hireDate:d}");

// Use the Text property for the formatted display value
string formattedSalary = sheet["D2"].Text;   // "$75,000.00"
string formattedDate   = sheet["E2"].Text;   // "28/02/2026"

// Guard against empty cells before reading
if (!sheet["B3"].IsEmpty)
{
    string value = sheet["B3"].StringValue;
}
using IronXL;

WorkBook workbook = WorkBook.Load("Employees.xlsx");
WorkSheet sheet   = workbook.DefaultWorkSheet;

// Extract typed values from row 2
int      employeeId = sheet["A2"].IntValue;
string   name       = sheet["B2"].StringValue;
string   department = sheet["C2"].StringValue;
decimal  salary     = sheet["D2"].DecimalValue;
DateTime hireDate   = sheet["E2"].DateTimeValue;

Console.WriteLine($"ID:         {employeeId}");
Console.WriteLine($"Name:       {name}");
Console.WriteLine($"Department: {department}");
Console.WriteLine($"Salary:     {salary:C}");
Console.WriteLine($"Hired:      {hireDate:d}");

// Use the Text property for the formatted display value
string formattedSalary = sheet["D2"].Text;   // "$75,000.00"
string formattedDate   = sheet["E2"].Text;   // "28/02/2026"

// Guard against empty cells before reading
if (!sheet["B3"].IsEmpty)
{
    string value = sheet["B3"].StringValue;
}
$vbLabelText   $csharpLabel

The Text property returns the display value exactly as formatted in Excel -- useful when you need the formatted number string rather than the raw numeric. For cells that contain Excel formulas, IronXL evaluates the expression and returns the computed result through the same typed properties. Additional value properties -- BoolValue, DoubleValue, FloatValue -- appear in the cell value reference.


How Do You Iterate Through Excel Rows and Columns?

Processing every record in a dataset requires iterating across rows and columns. IronXL's range syntax maps directly onto Excel's A1 notation, so selecting a block of cells is familiar to anyone who has written spreadsheet formulas:

using IronXL;

WorkBook workbook = WorkBook.Load("Employees.xlsx");
WorkSheet sheet   = workbook.DefaultWorkSheet;

// Iterate a single column range
Console.WriteLine("Employee List:");
foreach (var cell in sheet["B2:B100"])
{
    if (!string.IsNullOrEmpty(cell.Text))
        Console.WriteLine($"  - {cell.Text}");
}

// Iterate all rows and all columns using the Rows property
foreach (var row in sheet.Rows)
{
    foreach (var cell in row)
        Console.Write(cell.Text.PadRight(15));
    Console.WriteLine();
}
using IronXL;

WorkBook workbook = WorkBook.Load("Employees.xlsx");
WorkSheet sheet   = workbook.DefaultWorkSheet;

// Iterate a single column range
Console.WriteLine("Employee List:");
foreach (var cell in sheet["B2:B100"])
{
    if (!string.IsNullOrEmpty(cell.Text))
        Console.WriteLine($"  - {cell.Text}");
}

// Iterate all rows and all columns using the Rows property
foreach (var row in sheet.Rows)
{
    foreach (var cell in row)
        Console.Write(cell.Text.PadRight(15));
    Console.WriteLine();
}
$vbLabelText   $csharpLabel

The range sheet["B2:B100"] returns an enumerable collection of cell objects. Checking string.IsNullOrEmpty skips blank rows gracefully. The Rows property -- documented in the worksheet data range guide -- walks the sheet one row at a time and exposes each row's cells without requiring you to know the column count in advance.

Output

VB.NET Reading Excel Files Using IronXL: A Step-by-Step Guide Without Microsoft Office: Image 4 - Excel Rows Output


How Do You Run Aggregate Calculations on Excel Data?

IronXL includes built-in aggregate functions that compute results directly on cell ranges -- no manual accumulation loops required:

using IronXL;

WorkBook workbook = WorkBook.Load("Employees.xlsx");
WorkSheet sheet   = workbook.DefaultWorkSheet;

// Built-in aggregate methods work on any named range
decimal total   = sheet["D2:D200"].Sum();
decimal highest = sheet["D2:D200"].Max();
decimal lowest  = sheet["D2:D200"].Min();
decimal average = sheet["D2:D200"].Avg();

Console.WriteLine($"Total Payroll:  {total:C}");
Console.WriteLine($"Highest Salary: {highest:C}");
Console.WriteLine($"Lowest Salary:  {lowest:C}");
Console.WriteLine($"Average Salary: {average:C}");

// Combine with LINQ for filtered aggregation
decimal itTotal = sheet["D2:D200"]
    .Where(c => sheet[$"C{c.RowIndex}"].StringValue == "IT")
    .Sum(c => c.DecimalValue);
Console.WriteLine($"IT Department Total: {itTotal:C}");
using IronXL;

WorkBook workbook = WorkBook.Load("Employees.xlsx");
WorkSheet sheet   = workbook.DefaultWorkSheet;

// Built-in aggregate methods work on any named range
decimal total   = sheet["D2:D200"].Sum();
decimal highest = sheet["D2:D200"].Max();
decimal lowest  = sheet["D2:D200"].Min();
decimal average = sheet["D2:D200"].Avg();

Console.WriteLine($"Total Payroll:  {total:C}");
Console.WriteLine($"Highest Salary: {highest:C}");
Console.WriteLine($"Lowest Salary:  {lowest:C}");
Console.WriteLine($"Average Salary: {average:C}");

// Combine with LINQ for filtered aggregation
decimal itTotal = sheet["D2:D200"]
    .Where(c => sheet[$"C{c.RowIndex}"].StringValue == "IT")
    .Sum(c => c.DecimalValue);
Console.WriteLine($"IT Department Total: {itTotal:C}");
$vbLabelText   $csharpLabel

Sum, Min, Max, and Avg automatically skip empty cells and handle numeric conversion behind the scenes. Chaining LINQ queries onto the range gives you filtered aggregates -- department subtotals, date-range sums, and conditional counts -- all without leaving the IronXL API.


How Do You Build a Complete Employee Data Reader?

The following example assembles everything covered so far into a production-ready console application that loads an employee spreadsheet, formats each record, accumulates salary totals, handles write-back, and catches errors gracefully:

using IronXL;

try
{
    WorkBook workbook = WorkBook.Load("Employees.xlsx");
    WorkSheet sheet   = workbook.DefaultWorkSheet;

    Console.WriteLine("=== Employee Data Report ===\n");

    int     rowNumber     = 2;
    decimal totalSalary   = 0m;
    int     employeeCount = 0;

    while (!string.IsNullOrEmpty(sheet[$"A{rowNumber}"].StringValue))
    {
        int      id         = sheet[$"A{rowNumber}"].IntValue;
        string   name       = sheet[$"B{rowNumber}"].StringValue;
        string   department = sheet[$"C{rowNumber}"].StringValue;
        decimal  salary     = sheet[$"D{rowNumber}"].DecimalValue;

        Console.WriteLine($"{id,4}  {name,-20}  {department,-15}  {salary,10:C}");

        totalSalary   += salary;
        employeeCount += 1;
        rowNumber     += 1;
    }

    Console.WriteLine($"\nTotal Employees: {employeeCount}");
    Console.WriteLine($"Total Payroll:   {totalSalary:C}");

    // Write a new record back to the sheet and save
    sheet["A10"].Value = 1010;
    sheet["B10"].Value = "Jane Doe";
    sheet["C10"].Value = "Finance";
    sheet["D10"].Value = 75000;
    workbook.SaveAs("Employees-Updated.xlsx");
}
catch (Exception ex)
{
    Console.WriteLine($"Error reading Excel file: {ex.Message}");
}
using IronXL;

try
{
    WorkBook workbook = WorkBook.Load("Employees.xlsx");
    WorkSheet sheet   = workbook.DefaultWorkSheet;

    Console.WriteLine("=== Employee Data Report ===\n");

    int     rowNumber     = 2;
    decimal totalSalary   = 0m;
    int     employeeCount = 0;

    while (!string.IsNullOrEmpty(sheet[$"A{rowNumber}"].StringValue))
    {
        int      id         = sheet[$"A{rowNumber}"].IntValue;
        string   name       = sheet[$"B{rowNumber}"].StringValue;
        string   department = sheet[$"C{rowNumber}"].StringValue;
        decimal  salary     = sheet[$"D{rowNumber}"].DecimalValue;

        Console.WriteLine($"{id,4}  {name,-20}  {department,-15}  {salary,10:C}");

        totalSalary   += salary;
        employeeCount += 1;
        rowNumber     += 1;
    }

    Console.WriteLine($"\nTotal Employees: {employeeCount}");
    Console.WriteLine($"Total Payroll:   {totalSalary:C}");

    // Write a new record back to the sheet and save
    sheet["A10"].Value = 1010;
    sheet["B10"].Value = "Jane Doe";
    sheet["C10"].Value = "Finance";
    sheet["D10"].Value = 75000;
    workbook.SaveAs("Employees-Updated.xlsx");
}
catch (Exception ex)
{
    Console.WriteLine($"Error reading Excel file: {ex.Message}");
}
$vbLabelText   $csharpLabel

The while loop terminates when column A becomes empty, making the reader adaptive to spreadsheets of any length without requiring a hard-coded row count. Writing values back follows the same cell-address syntax as reading, and SaveAs persists the changes to a new file so the original remains untouched. The try/catch block handles missing files, locked workbooks, and corrupted data -- all scenarios that occur in production environments where input files arrive from external sources.

Output

VB.NET Reading Excel Files Using IronXL: A Step-by-Step Guide Without Microsoft Office: Image 5 - Employee Data Output

The how-to guide for creating spreadsheets and the guide for converting XLSX to CSV show how to combine reading and writing in end-to-end workflows. The cell styling guide covers font sizes, colors, and borders when formatted output is a requirement.

VB.NET Reading Excel Files Using IronXL: A Step-by-Step Guide Without Microsoft Office: Image 6 - Windows Form Output


How Do You Handle Advanced Reading Scenarios?

Several less-common but important scenarios arise in real projects. Named ranges, worksheet discovery, and CSV loading each have dedicated API support.

Named ranges let you reference data by a logical label rather than a cell address. If the workbook author defined a named range called SalaryTable, you access it directly through GetRangeByName:

var range = workbook.GetRangeByName("SalaryTable");
decimal total = range.Sum();
Console.WriteLine($"Named range total: {total:C}");
var range = workbook.GetRangeByName("SalaryTable");
decimal total = range.Sum();
Console.WriteLine($"Named range total: {total:C}");
$vbLabelText   $csharpLabel

Worksheet discovery enumerates every sheet in the workbook, which is useful when processing files with a variable number of tabs:

foreach (WorkSheet ws in workbook.WorkSheets)
    Console.WriteLine($"Sheet: {ws.Name}, Rows: {ws.RowCount}");
foreach (WorkSheet ws in workbook.WorkSheets)
    Console.WriteLine($"Sheet: {ws.Name}, Rows: {ws.RowCount}");
$vbLabelText   $csharpLabel

CSV loading uses a dedicated method optimized for plain-text files, returning a WorkSheet you navigate with the same range API:

WorkBook csv    = WorkBook.LoadCSV("data.csv");
WorkSheet first = csv.DefaultWorkSheet;
Console.WriteLine(first["A1"].StringValue);
WorkBook csv    = WorkBook.LoadCSV("data.csv");
WorkSheet first = csv.DefaultWorkSheet;
Console.WriteLine(first["A1"].StringValue);
$vbLabelText   $csharpLabel

These patterns cover the advanced reading scenarios that appear in data migration projects, ETL pipelines, and automated reporting systems. For the complete API surface, see the IronXL object reference.

Additional authoritative references:


What Are Your Next Steps?

IronXL turns Excel file reading from a dependency-laden Interop challenge into a few lines of straightforward C# code. Loading workbooks, extracting typed values, iterating row by row, running aggregate calculations, and handling edge cases all follow the same consistent API pattern -- without Microsoft Office installed anywhere in your deployment environment.

To move from tutorial to production:

  1. Start a free trial to unlock the full IronXL feature set and validate it against your own Excel files before committing to a license.
  2. Browse the complete IronXL documentation for guides on writing, formatting, styling, and converting spreadsheets.
  3. Explore the object reference and full API to discover every class, method, and property available in the library.
  4. Review the how-to guide for creating spreadsheets when your workflow requires generating output files as well as reading input files.
  5. Check the IronXL blog post index for additional tutorials covering real-world scenarios such as report generation, data validation, and multi-sheet consolidation.

Frequently Asked Questions

What is IronXL?

IronXL is a .NET library that allows developers to read, edit, and create Excel files in various formats such as XLSX and XLS without needing Microsoft Office installed.

How do you read Excel files in C# with IronXL?

Call WorkBook.Load with the file path to open the workbook, then access cells using A1 notation and typed properties such as StringValue, IntValue, and DecimalValue.

Why choose IronXL over Microsoft Office Interop for reading Excel files?

IronXL requires no Microsoft Office installation, eliminating COM dependencies and simplifying server-side deployment.

What Excel file formats can IronXL read?

IronXL reads XLSX, XLS, XLSM, CSV, and TSV formats. Format detection is automatic based on file extension.

Can IronXL handle large Excel files efficiently?

Yes, IronXL is optimized for performance and can handle large Excel files, making it suitable for data-intensive applications.

Does IronXL work with .NET 10?

Yes, IronXL supports modern .NET versions including .NET 10, as well as .NET Framework projects.

How do you run aggregate calculations with IronXL?

Use the built-in Sum, Min, Max, and Avg methods on any cell range. These methods skip empty cells automatically.

Can IronXL read password-protected Excel files?

Yes, pass the password as the second argument to WorkBook.Load: WorkBook.Load("file.xlsx", "password").

Jordi Bardia
Software Engineer
Jordi is most proficient in Python, C# and C++, when he isn’t leveraging his skills at Iron Software; he’s game programming. Sharing responsibilities for product testing, product development and research, Jordi adds immense value to continual product improvement. The varied experience keeps him challenged and engaged, and he ...
Read More

Iron Support Team

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