How to Import Excel Data in C# Using IronXL
Working with Microsoft Excel files is a daily requirement for many .NET developers. Whether importing customer data, processing financial reports, or migrating data from spreadsheets to databases, developers need a reliable way to read Excel files without complex dependencies or requiring Excel to be installed. Traditional approaches, such as COM automation through Microsoft.Office.Interop, require a full Office installation, introduce platform restrictions, and create brittle deployment dependencies. IronXL offers a straightforward solution that works across platforms, eliminating all of those problems and enabling Excel operations directly from managed .NET code.

How Do You Install IronXL and Get Started with Excel Import?
Getting started with Excel import in C# takes just minutes with IronXL. The Excel library handles both legacy XLS and modern XLSX formats, along with CSV, TSV, and other spreadsheet formats. Unlike solutions that rely on Microsoft.Office.Interop.Excel, IronXL runs independently on any .NET or .NET Core platform.

Install IronXL via the NuGet Package Manager or the .NET CLI. You can also use the Manage NuGet Packages dialog in Visual Studio and search for "IronXL":
Install-Package IronXL
dotnet add package IronXL
Install-Package IronXL
dotnet add package IronXL

For full installation details, including version compatibility and dependency notes, refer to the IronXL NuGet installation guide. No additional runtime dependencies or Office components are required -- the package is self-contained. Once the package is installed, importing Excel data is straightforward:
using IronXL;
// Load any Excel file
WorkBook workBook = WorkBook.Load("ProductData.xlsx");
// Access the first worksheet
WorkSheet sheet = workBook.WorkSheets[0];
// Read a cell value
string value = sheet["B1"].StringValue;
Console.WriteLine(value);
using IronXL;
// Load any Excel file
WorkBook workBook = WorkBook.Load("ProductData.xlsx");
// Access the first worksheet
WorkSheet sheet = workBook.WorkSheets[0];
// Read a cell value
string value = sheet["B1"].StringValue;
Console.WriteLine(value);
Imports IronXL
' Load any Excel file
Dim workBook As WorkBook = WorkBook.Load("ProductData.xlsx")
' Access the first worksheet
Dim sheet As WorkSheet = workBook.WorkSheets(0)
' Read a cell value
Dim value As String = sheet("B1").StringValue
Console.WriteLine(value)
This code demonstrates the core workflow: loading a workbook, accessing a worksheet, and reading cell values. The WorkBook.Load() method automatically detects the file format -- whether it's XLS, XLSX, or CSV. The intuitive indexer syntax sheet["B1"] makes accessing cells as natural as working with arrays. For a full reference of available members and overloads, see the IronXL API documentation.
Sample Input

Output

How Do You Read Excel Data into C# Objects?
Real applications need more than single-cell values. IronXL excels at importing entire datasets and converting them into usable C# objects. When you need to import structured Excel data, the library provides multiple approaches that map directly to your domain models.
The example below reads rows from a worksheet and maps each row to a typed Product object:
using IronXL;
// Load the Excel file
WorkBook workBook = WorkBook.Load("ProductData.xlsx");
WorkSheet sheet = workBook.DefaultWorkSheet;
// Map rows to typed objects
var products = new List<Product>();
foreach (var row in sheet.Rows)
{
var product = new Product
{
Id = row.Columns[0].IntValue,
Name = row.Columns[1].StringValue,
Price = row.Columns[2].DecimalValue,
IsAvailable = row.Columns[3].BoolValue
};
products.Add(product);
}
foreach (var product in products)
{
Console.WriteLine(
$"Id: {product.Id}, Name: {product.Name}, " +
$"Price: {product.Price}, Available: {product.IsAvailable}"
);
}
using IronXL;
// Load the Excel file
WorkBook workBook = WorkBook.Load("ProductData.xlsx");
WorkSheet sheet = workBook.DefaultWorkSheet;
// Map rows to typed objects
var products = new List<Product>();
foreach (var row in sheet.Rows)
{
var product = new Product
{
Id = row.Columns[0].IntValue,
Name = row.Columns[1].StringValue,
Price = row.Columns[2].DecimalValue,
IsAvailable = row.Columns[3].BoolValue
};
products.Add(product);
}
foreach (var product in products)
{
Console.WriteLine(
$"Id: {product.Id}, Name: {product.Name}, " +
$"Price: {product.Price}, Available: {product.IsAvailable}"
);
}
Imports IronXL
' Load the Excel file
Dim workBook As WorkBook = WorkBook.Load("ProductData.xlsx")
Dim sheet As WorkSheet = workBook.DefaultWorkSheet
' Map rows to typed objects
Dim products As New List(Of Product)()
For Each row In sheet.Rows
Dim product As New Product With {
.Id = row.Columns(0).IntValue,
.Name = row.Columns(1).StringValue,
.Price = row.Columns(2).DecimalValue,
.IsAvailable = row.Columns(3).BoolValue
}
products.Add(product)
Next
For Each product In products
Console.WriteLine(
$"Id: {product.Id}, Name: {product.Name}, " &
$"Price: {product.Price}, Available: {product.IsAvailable}"
)
Next
The typed properties -- IntValue, StringValue, DecimalValue, and BoolValue -- handle type conversion automatically. This approach eliminates manual parsing and reduces errors when working with columns of mixed data types. Many developers on Stack Overflow appreciate this type-safe approach to Excel data import.
Output

How Do You Work with Cell Ranges and LINQ?
For aggregate calculations and filtered queries, IronXL supports range operations with built-in LINQ compatibility:
using IronXL;
WorkBook workBook = WorkBook.Load("ProductData.xlsx");
WorkSheet sheet = workBook.DefaultWorkSheet;
// Read a named cell range
Range dataRange = sheet["A1:D5"];
// Calculate aggregates directly on a range
decimal sum = sheet["C1:C5"].Sum();
Console.WriteLine($"Sum of C1:C5: {sum}");
decimal max = sheet["C1:C5"].Max(c => c.DecimalValue);
Console.WriteLine($"Max of C1:C5: {max}");
// Filter using LINQ
var highValueOrders = dataRange
.Where(cell => cell.DecimalValue > 100)
.Select(cell => cell.Value)
.ToList();
Console.WriteLine("Orders above 100:");
foreach (var order in highValueOrders)
{
Console.WriteLine(order);
}
using IronXL;
WorkBook workBook = WorkBook.Load("ProductData.xlsx");
WorkSheet sheet = workBook.DefaultWorkSheet;
// Read a named cell range
Range dataRange = sheet["A1:D5"];
// Calculate aggregates directly on a range
decimal sum = sheet["C1:C5"].Sum();
Console.WriteLine($"Sum of C1:C5: {sum}");
decimal max = sheet["C1:C5"].Max(c => c.DecimalValue);
Console.WriteLine($"Max of C1:C5: {max}");
// Filter using LINQ
var highValueOrders = dataRange
.Where(cell => cell.DecimalValue > 100)
.Select(cell => cell.Value)
.ToList();
Console.WriteLine("Orders above 100:");
foreach (var order in highValueOrders)
{
Console.WriteLine(order);
}
Imports IronXL
Dim workBook As WorkBook = WorkBook.Load("ProductData.xlsx")
Dim sheet As WorkSheet = workBook.DefaultWorkSheet
' Read a named cell range
Dim dataRange As Range = sheet("A1:D5")
' Calculate aggregates directly on a range
Dim sum As Decimal = sheet("C1:C5").Sum()
Console.WriteLine($"Sum of C1:C5: {sum}")
Dim max As Decimal = sheet("C1:C5").Max(Function(c) c.DecimalValue)
Console.WriteLine($"Max of C1:C5: {max}")
' Filter using LINQ
Dim highValueOrders = dataRange _
.Where(Function(cell) cell.DecimalValue > 100) _
.Select(Function(cell) cell.Value) _
.ToList()
Console.WriteLine("Orders above 100:")
For Each order In highValueOrders
Console.WriteLine(order)
Next
The Range class provides collection-like access to multiple cells simultaneously. LINQ compatibility means you can filter, transform, and aggregate Excel data using familiar C# patterns without converting to intermediate collections first. The built-in aggregation methods such as Sum() and Max() operate directly on cell ranges. For more details on reading workbook data, see the IronXL read Excel file guide.
Output

How Do You Convert Excel to DataTable in C#?
DataTable conversion is essential for database operations and data binding scenarios. IronXL provides built-in methods that handle the conversion from Excel to DataSet or DataTable. This feature is particularly useful when you need to import Excel spreadsheets into SQL Server or other relational databases. Because the resulting object is a standard System.Data.DataTable, it works with any ADO.NET-compatible code path without requiring changes to your data access layer.
using IronXL;
using System.Data;
using System.Data.SqlClient;
// Load Excel file
WorkBook workBook = WorkBook.Load("inventory.xlsx");
// Select the first worksheet
WorkSheet sheet = workBook.WorkSheets.First();
// Convert to DataTable -- first row becomes column headers
DataTable dataTable = sheet.ToDataTable(true);
// Use SqlBulkCopy to insert directly into SQL Server
string connectionString = "Data Source=.;Initial Catalog=InventoryDB;Integrated Security=True;";
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connectionString))
{
bulkCopy.DestinationTableName = "Inventory";
bulkCopy.WriteToServer(dataTable);
}
using IronXL;
using System.Data;
using System.Data.SqlClient;
// Load Excel file
WorkBook workBook = WorkBook.Load("inventory.xlsx");
// Select the first worksheet
WorkSheet sheet = workBook.WorkSheets.First();
// Convert to DataTable -- first row becomes column headers
DataTable dataTable = sheet.ToDataTable(true);
// Use SqlBulkCopy to insert directly into SQL Server
string connectionString = "Data Source=.;Initial Catalog=InventoryDB;Integrated Security=True;";
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connectionString))
{
bulkCopy.DestinationTableName = "Inventory";
bulkCopy.WriteToServer(dataTable);
}
Imports IronXL
Imports System.Data
Imports System.Data.SqlClient
' Load Excel file
Dim workBook As WorkBook = WorkBook.Load("inventory.xlsx")
' Select the first worksheet
Dim sheet As WorkSheet = workBook.WorkSheets.First()
' Convert to DataTable -- first row becomes column headers
Dim dataTable As DataTable = sheet.ToDataTable(True)
' Use SqlBulkCopy to insert directly into SQL Server
Dim connectionString As String = "Data Source=.;Initial Catalog=InventoryDB;Integrated Security=True;"
Using bulkCopy As New SqlBulkCopy(connectionString)
bulkCopy.DestinationTableName = "Inventory"
bulkCopy.WriteToServer(dataTable)
End Using
The ToDataTable() method accepts a boolean parameter indicating whether the first row contains headers. When set to true, IronXL automatically uses the first-row values as column names. The resulting DataTable integrates with ADO.NET, Entity Framework, and data binding controls without any additional configuration.
For more control over the conversion process, you can build the DataTable manually:
using IronXL;
using System.Data;
WorkBook workBook = WorkBook.Load("inventory.xlsx");
WorkSheet sheet = workBook.WorkSheets.First();
// Build DataTable manually for custom column types or validation
DataTable customTable = new DataTable();
for (int col = 0; col < sheet.ColumnCount; col++)
{
customTable.Columns.Add($"Column{col + 1}", typeof(string));
}
foreach (var row in sheet.Rows)
{
var dataRow = customTable.NewRow();
for (int col = 0; col < sheet.ColumnCount; col++)
{
dataRow[col] = row.Columns[col].Value ?? DBNull.Value;
}
customTable.Rows.Add(dataRow);
}
// Print headers
foreach (DataColumn column in customTable.Columns)
{
Console.Write($"{column.ColumnName}\t");
}
Console.WriteLine();
// Print data rows
foreach (DataRow row in customTable.Rows)
{
foreach (var item in row.ItemArray)
{
Console.Write($"{item}\t");
}
Console.WriteLine();
}
using IronXL;
using System.Data;
WorkBook workBook = WorkBook.Load("inventory.xlsx");
WorkSheet sheet = workBook.WorkSheets.First();
// Build DataTable manually for custom column types or validation
DataTable customTable = new DataTable();
for (int col = 0; col < sheet.ColumnCount; col++)
{
customTable.Columns.Add($"Column{col + 1}", typeof(string));
}
foreach (var row in sheet.Rows)
{
var dataRow = customTable.NewRow();
for (int col = 0; col < sheet.ColumnCount; col++)
{
dataRow[col] = row.Columns[col].Value ?? DBNull.Value;
}
customTable.Rows.Add(dataRow);
}
// Print headers
foreach (DataColumn column in customTable.Columns)
{
Console.Write($"{column.ColumnName}\t");
}
Console.WriteLine();
// Print data rows
foreach (DataRow row in customTable.Rows)
{
foreach (var item in row.ItemArray)
{
Console.Write($"{item}\t");
}
Console.WriteLine();
}
Imports IronXL
Imports System.Data
Dim workBook As WorkBook = WorkBook.Load("inventory.xlsx")
Dim sheet As WorkSheet = workBook.WorkSheets.First()
' Build DataTable manually for custom column types or validation
Dim customTable As New DataTable()
For col As Integer = 0 To sheet.ColumnCount - 1
customTable.Columns.Add($"Column{col + 1}", GetType(String))
Next
For Each row In sheet.Rows
Dim dataRow = customTable.NewRow()
For col As Integer = 0 To sheet.ColumnCount - 1
dataRow(col) = If(row.Columns(col).Value, DBNull.Value)
Next
customTable.Rows.Add(dataRow)
Next
' Print headers
For Each column As DataColumn In customTable.Columns
Console.Write($"{column.ColumnName}" & vbTab)
Next
Console.WriteLine()
' Print data rows
For Each row As DataRow In customTable.Rows
For Each item In row.ItemArray
Console.Write($"{item}" & vbTab)
Next
Console.WriteLine()
Next
This approach gives you full flexibility during import. Null values are handled gracefully by converting them to DBNull.Value, ensuring compatibility with database column constraints. For further guidance on writing data back to files, see the IronXL write Excel file guide.
Output

How Do You Work with Formulas, Multi-Sheet Workbooks, and Entity Framework?
IronXL goes beyond basic reading with features for complex real-world scenarios. The library preserves Excel formulas, allowing calculations to be evaluated dynamically. For developers working with complex Excel workbooks, this maintains data integrity throughout the import process.

Reading Formulas and Calculated Values
using IronXL;
WorkBook workBook = WorkBook.Load("FinancialReport.xlsx");
WorkSheet sheet = workBook.GetWorkSheet("Reports");
// Read the evaluated result of a formula cell
decimal calculatedTotal = sheet["E10"].DecimalValue;
Console.WriteLine($"Total: {calculatedTotal}");
// Read the formula string itself
string formula = sheet["E10"].Formula;
Console.WriteLine($"Formula: {formula}"); // e.g. "=SUM(E2:E9)"
using IronXL;
WorkBook workBook = WorkBook.Load("FinancialReport.xlsx");
WorkSheet sheet = workBook.GetWorkSheet("Reports");
// Read the evaluated result of a formula cell
decimal calculatedTotal = sheet["E10"].DecimalValue;
Console.WriteLine($"Total: {calculatedTotal}");
// Read the formula string itself
string formula = sheet["E10"].Formula;
Console.WriteLine($"Formula: {formula}"); // e.g. "=SUM(E2:E9)"
Imports IronXL
Dim workBook As WorkBook = WorkBook.Load("FinancialReport.xlsx")
Dim sheet As WorkSheet = workBook.GetWorkSheet("Reports")
' Read the evaluated result of a formula cell
Dim calculatedTotal As Decimal = sheet("E10").DecimalValue
Console.WriteLine($"Total: {calculatedTotal}")
' Read the formula string itself
Dim formula As String = sheet("E10").Formula
Console.WriteLine($"Formula: {formula}") ' e.g. "=SUM(E2:E9)"
Formula support means importing Excel files with complex calculations works without recreating business logic in code. The library evaluates formulas automatically, returning calculated values while preserving the original formula string. This proves invaluable when importing financial models or reporting templates that contain nested formulas.
Cross-platform compatibility ensures consistent behavior across Windows, Linux, macOS, and container environments. This makes IronXL well-suited for cloud deployments and microservices where Office installation is not feasible. The .NET Foundation's documentation highlights how modern .NET applications benefit from platform independence.
Integrating Excel Data with Entity Framework
Entity Framework integration creates direct Excel-to-database pipelines. The following pattern works cleanly with .NET 10 top-level statements:
using IronXL;
WorkBook workBook = WorkBook.Load("ProductData.xlsx");
WorkSheet sheet = workBook.DefaultWorkSheet;
// Skip the header row, map remaining rows to entity objects
var products = sheet.Rows
.Skip(1)
.Select(row => new Product
{
Name = row.Columns[0].StringValue,
Price = row.Columns[1].DecimalValue
})
.ToList();
using var context = new AppDbContext();
await context.Products.AddRangeAsync(products);
await context.SaveChangesAsync();
Console.WriteLine($"Imported {products.Count} products.");
using IronXL;
WorkBook workBook = WorkBook.Load("ProductData.xlsx");
WorkSheet sheet = workBook.DefaultWorkSheet;
// Skip the header row, map remaining rows to entity objects
var products = sheet.Rows
.Skip(1)
.Select(row => new Product
{
Name = row.Columns[0].StringValue,
Price = row.Columns[1].DecimalValue
})
.ToList();
using var context = new AppDbContext();
await context.Products.AddRangeAsync(products);
await context.SaveChangesAsync();
Console.WriteLine($"Imported {products.Count} products.");
Imports IronXL
Dim workBook As WorkBook = WorkBook.Load("ProductData.xlsx")
Dim sheet As WorkSheet = workBook.DefaultWorkSheet
' Skip the header row, map remaining rows to entity objects
Dim products = sheet.Rows _
.Skip(1) _
.Select(Function(row) New Product With {
.Name = row.Columns(0).StringValue,
.Price = row.Columns(1).DecimalValue
}) _
.ToList()
Using context As New AppDbContext()
Await context.Products.AddRangeAsync(products)
Await context.SaveChangesAsync()
End Using
Console.WriteLine($"Imported {products.Count} products.")
This pattern enables direct Excel-to-database migration with minimal code, making it well-suited for ETL processes, one-time data migrations, and scheduled import jobs. Because the LINQ projection runs in memory before the context saves, you can apply validation or transformation logic at the same step. For creating new Excel files from C# data, see the IronXL create Excel file guide.
Supported File Formats
IronXL handles a wide range of spreadsheet formats without any additional libraries or Office installation. The following table summarizes supported formats and their use cases:
| Format | Extension | Notes |
|---|---|---|
| Excel Workbook | .xlsx | Default format for Excel 2007 and later |
| Legacy Excel Workbook | .xls | Compatible with older Excel versions |
| Comma-Separated Values | .csv | Plain-text tabular data, widely supported |
| Tab-Separated Values | .tsv | Suitable for data with embedded commas |
| Excel Binary Workbook | .xlsb | Compact binary format for large files |
For exporting data back into these formats, see the IronXL export Excel guide.
How Do You Handle Cell Formatting During Import?
When you import Excel files, preserving or inspecting cell formatting is often as important as reading the raw values. IronXL exposes font, color, alignment, and border properties for every cell, so you can apply validation rules or reproduce styles programmatically. This is particularly useful for reports where visual formatting carries semantic meaning -- for example, colored cells indicating risk levels, or bold rows marking totals.
For example, you might want to check whether cells contain bold text -- a common signal that a row is a summary or total row -- before deciding whether to include it in your imported dataset:
using IronXL;
WorkBook workBook = WorkBook.Load("StyledReport.xlsx");
WorkSheet sheet = workBook.DefaultWorkSheet;
foreach (var row in sheet.Rows)
{
var firstCell = row.Columns[0];
// Skip rows where the first cell is bold (typically header or total rows)
if (firstCell.Style.Font.Bold)
{
continue;
}
Console.WriteLine($"Data row: {firstCell.StringValue}");
}
using IronXL;
WorkBook workBook = WorkBook.Load("StyledReport.xlsx");
WorkSheet sheet = workBook.DefaultWorkSheet;
foreach (var row in sheet.Rows)
{
var firstCell = row.Columns[0];
// Skip rows where the first cell is bold (typically header or total rows)
if (firstCell.Style.Font.Bold)
{
continue;
}
Console.WriteLine($"Data row: {firstCell.StringValue}");
}
Imports IronXL
Dim workBook As WorkBook = WorkBook.Load("StyledReport.xlsx")
Dim sheet As WorkSheet = workBook.DefaultWorkSheet
For Each row In sheet.Rows
Dim firstCell = row.Columns(0)
' Skip rows where the first cell is bold (typically header or total rows)
If firstCell.Style.Font.Bold Then
Continue For
End If
Console.WriteLine($"Data row: {firstCell.StringValue}")
Next
For a full reference on cell and range formatting, including number format strings and background color access, see the IronXL cell formatting guide. You can also apply merge operations to output files after processing -- see the IronXL merge cells guide.
How Do You Choose the Right IronXL License for Your Project?
IronXL offers flexible licensing options to match the scale of your project. A free trial license is available for evaluation, which gives you access to all features without time restrictions during development. The trial adds a watermark to output files, which is removed with a valid production license.

For teams building production applications, IronXL licensing includes options for individual developers, teams, and organization-wide deployments. All production licenses include:
- Royalty-free redistribution rights
- Priority support from the IronXL development team
- Access to all current and minor-version updates during the license period
If you are evaluating IronXL alongside other Excel libraries, the IronXL features overview provides a detailed breakdown of what is included at each tier.
To begin using IronXL in your project today, visit the IronXL product page or start directly with the IronXL documentation for setup guides, how-to articles, and API references covering every feature in the library.
Frequently Asked Questions
How can I import Excel data in C#?
You can use IronXL to import Excel data in C# easily, without needing Microsoft Excel installed on your system.
What are the benefits of using IronXL for Excel file manipulation?
IronXL allows developers to read, write, and manipulate Excel files in C# without complex dependencies, and it works across different platforms.
Do I need Microsoft Office installed to use IronXL?
No, IronXL eliminates the need for Microsoft Office installation, allowing you to work with Excel files directly within your C# applications.
Can IronXL handle both XLSX and CSV file formats?
Yes, IronXL supports various Excel file formats, including XLSX and CSV, making it versatile for different data processing needs.
Is IronXL suitable for processing large Excel files?
Yes, IronXL is designed to efficiently handle large Excel files, allowing developers to process extensive datasets without performance issues.
What platforms does IronXL support?
IronXL is compatible with multiple platforms, enabling cross-platform development and deployment of applications handling Excel files.
How does IronXL simplify data migration from Excel to databases?
IronXL provides straightforward methods to read and export data from Excel sheets, making it easier to transfer data to databases without complex coding.
Can I use IronXL to automate Excel report generation?
Yes, IronXL allows for the automation of Excel report generation, enabling you to programmatically create and manipulate Excel files in C#.
Is IronXL suitable for both small-scale and enterprise-level applications?
IronXL is versatile and scalable, making it suitable for both small-scale projects and large enterprise-level applications requiring Excel file manipulation.




