How Do I Set Up IronXL to Read Excel Files in C#?

Setting up IronXL for reading Excel files in your C# project takes just minutes. The library supports both .XLS and .XLSX formats, making it versatile for any Excel-related task.

Follow these steps to get started:

  1. Download the C# Library to read Excel files
  2. Load and read Excel workbooks using WorkBook.Load()
  3. Access worksheets with the GetWorkSheet() method
  4. Read cell values using intuitive syntax like sheet["A1"].Value
  5. Validate and process spreadsheet data programmatically
  6. Export data to databases using Entity Framework

IronXL excels at reading and editing Microsoft Excel documents with C#. The library operates independently—it neither requires Microsoft Excel nor Interop to function. In fact, IronXL provides a faster and more intuitive API than Microsoft.Office.Interop.Excel.

IronXL Includes:

  • Dedicated product support from our .NET engineers
  • Easy installation via Microsoft Visual Studio
  • Free trial test for development. Licenses from $749

Reading and creating Excel files in C# and VB.NET becomes straightforward using the IronXL software library.

Reading .XLS and .XLSX Excel Files Using IronXL

Here's the essential workflow for reading Excel files using IronXL:

  1. Install the IronXL Excel Library via NuGet package or download the .NET Excel DLL
  2. Use the WorkBook.Load() method to read any XLS, XLSX, or CSV document
  3. Access cell values using intuitive syntax: sheet["A11"].DecimalValue
using IronXL;
using System;
using System.Linq;

// Load Excel workbook from file path
WorkBook workBook = WorkBook.Load("test.xlsx");

// Access the first worksheet using LINQ
WorkSheet workSheet = workBook.WorkSheets.First();

// Read integer value from cell A2
int cellValue = workSheet["A2"].IntValue;
Console.WriteLine($"Cell A2 value: {cellValue}");

// Iterate through a range of cells
foreach (var cell in workSheet["A2:A10"])
{
    Console.WriteLine($"Cell {cell.AddressString} = '{cell.Text}'");
}

// Advanced Operations with LINQ
// Calculate sum using built-in Sum() method
decimal sum = workSheet["A2:A10"].Sum();

// Find maximum value using LINQ
decimal max = workSheet["A2:A10"].Max(c => c.DecimalValue);

// Output calculated results
Console.WriteLine($"Sum of A2:A10: {sum}");
Console.WriteLine($"Maximum value: {max}");
using IronXL;
using System;
using System.Linq;

// Load Excel workbook from file path
WorkBook workBook = WorkBook.Load("test.xlsx");

// Access the first worksheet using LINQ
WorkSheet workSheet = workBook.WorkSheets.First();

// Read integer value from cell A2
int cellValue = workSheet["A2"].IntValue;
Console.WriteLine($"Cell A2 value: {cellValue}");

// Iterate through a range of cells
foreach (var cell in workSheet["A2:A10"])
{
    Console.WriteLine($"Cell {cell.AddressString} = '{cell.Text}'");
}

// Advanced Operations with LINQ
// Calculate sum using built-in Sum() method
decimal sum = workSheet["A2:A10"].Sum();

// Find maximum value using LINQ
decimal max = workSheet["A2:A10"].Max(c => c.DecimalValue);

// Output calculated results
Console.WriteLine($"Sum of A2:A10: {sum}");
Console.WriteLine($"Maximum value: {max}");
Imports IronXL

Imports System

Imports System.Linq



' Load Excel workbook from file path

Private workBook As WorkBook = WorkBook.Load("test.xlsx")



' Access the first worksheet using LINQ

Private workSheet As WorkSheet = workBook.WorkSheets.First()



' Read integer value from cell A2

Private cellValue As Integer = workSheet("A2").IntValue

Console.WriteLine($"Cell A2 value: {cellValue}")



' Iterate through a range of cells

For Each cell In workSheet("A2:A10")

	Console.WriteLine($"Cell {cell.AddressString} = '{cell.Text}'")

Next cell



' Advanced Operations with LINQ

' Calculate sum using built-in Sum() method

Dim sum As Decimal = workSheet("A2:A10").Sum()



' Find maximum value using LINQ

Dim max As Decimal = workSheet("A2:A10").Max(Function(c) c.DecimalValue)



' Output calculated results

Console.WriteLine($"Sum of A2:A10: {sum}")

Console.WriteLine($"Maximum value: {max}")
$vbLabelText   $csharpLabel

This code demonstrates several key IronXL features: loading workbooks, accessing cells by address, iterating through ranges, and performing calculations. The WorkBook.Load() method intelligently detects file formats, while the range syntax ["A2:A10"] provides Excel-like cell selection. LINQ integration enables powerful data queries and aggregations on cell collections.

The code examples in this tutorial work with three sample Excel spreadsheets that showcase different data scenarios:

Three Excel spreadsheet files displayed in Visual Studio Solution Explorer Sample Excel files (GDP.xlsx, People.xlsx, and PopulationByState.xlsx) used throughout this tutorial for demonstrating various IronXL operations.


How Can I Install the IronXL C# Library?

Start using IronXL in your project today with a free trial.

First Step:
green arrow pointer


Installing the IronXL.Excel library adds comprehensive Excel functionality to your .NET framework projects. Choose between NuGet installation or manual DLL integration.

Installing the IronXL NuGet Package

  1. In Visual Studio, right-click on your project and select "Manage NuGet Packages..."
  2. Search for "IronXL.Excel" in the Browse tab
  3. Click the Install button to add IronXL to your project

NuGet Package Manager interface showing IronXL.Excel package installation Installing IronXL through Visual Studio's NuGet Package Manager provides automatic dependency management.

Alternatively, install IronXL using the Package Manager Console:

  1. Open the Package Manager Console (Tools → NuGet Package Manager → Package Manager Console)
  2. Run the installation command:
:InstallCmd
:InstallCmd
SHELL

You can also view the package details on the NuGet website.

Manual Installation

For manual installation, download the IronXL .NET Excel DLL and reference it directly in your Visual Studio project.

How Do I Load and Read an Excel Workbook?

The WorkBook class represents an entire Excel file. Load Excel files using the WorkBook.Load() method, which accepts file paths for XLS, XLSX, CSV, and TSV formats.

using System;
using IronXL;

// Initialize WorkBook variable
WorkBook workBook = null;

try
{
    // Load Excel file from specified path
    workBook = WorkBook.Load(@"Spreadsheets\GDP.xlsx");

    Console.WriteLine("Workbook loaded successfully.");

    // Access specific worksheet by name
    WorkSheet sheet = workBook.GetWorkSheet("Sheet1");

    // Read and display cell value
    string cellValue = sheet["A1"].StringValue;
    Console.WriteLine($"Cell A1 contains: {cellValue}");

    // Perform additional operations
    // Count non-empty cells in column A
    int rowCount = sheet["A:A"].Count(cell => !cell.IsEmpty);
    Console.WriteLine($"Column A has {rowCount} non-empty cells");
}
catch (Exception ex)
{
    Console.WriteLine($"Error loading workbook: {ex.Message}");
}
using System;
using IronXL;

// Initialize WorkBook variable
WorkBook workBook = null;

try
{
    // Load Excel file from specified path
    workBook = WorkBook.Load(@"Spreadsheets\GDP.xlsx");

    Console.WriteLine("Workbook loaded successfully.");

    // Access specific worksheet by name
    WorkSheet sheet = workBook.GetWorkSheet("Sheet1");

    // Read and display cell value
    string cellValue = sheet["A1"].StringValue;
    Console.WriteLine($"Cell A1 contains: {cellValue}");

    // Perform additional operations
    // Count non-empty cells in column A
    int rowCount = sheet["A:A"].Count(cell => !cell.IsEmpty);
    Console.WriteLine($"Column A has {rowCount} non-empty cells");
}
catch (Exception ex)
{
    Console.WriteLine($"Error loading workbook: {ex.Message}");
}
Imports System

Imports IronXL



' Initialize WorkBook variable

Private workBook As WorkBook = Nothing



Try

	' Load Excel file from specified path

	workBook = WorkBook.Load("Spreadsheets\GDP.xlsx")



	Console.WriteLine("Workbook loaded successfully.")



	' Access specific worksheet by name

	Dim sheet As WorkSheet = workBook.GetWorkSheet("Sheet1")



	' Read and display cell value

	Dim cellValue As String = sheet("A1").StringValue

	Console.WriteLine($"Cell A1 contains: {cellValue}")



	' Perform additional operations

	' Count non-empty cells in column A

	Dim rowCount As Integer = sheet("A:A").Count(Function(cell) Not cell.IsEmpty)

	Console.WriteLine($"Column A has {rowCount} non-empty cells")

Catch ex As Exception

	Console.WriteLine($"Error loading workbook: {ex.Message}")

End Try
$vbLabelText   $csharpLabel

Each WorkBook contains multiple WorkSheet objects representing individual Excel sheets. Access worksheets by name using GetWorkSheet():

// Validate workbook is loaded
if (workBook == null)
{
    throw new InvalidOperationException("Workbook must be loaded first");
}

// Get worksheet by name
WorkSheet workSheet = workBook.GetWorkSheet("GDPByCountry");

// Handle case where worksheet doesn't exist
if (workSheet == null)
{
    Console.WriteLine("Worksheet 'GDPByCountry' not found");
    // List available worksheets
    foreach (var sheet in workBook.WorkSheets)
    {
        Console.WriteLine($"Available: {sheet.Name}");
    }
}
else
{
    Console.WriteLine($"Successfully loaded worksheet: {workSheet.Name}");
}
// Validate workbook is loaded
if (workBook == null)
{
    throw new InvalidOperationException("Workbook must be loaded first");
}

// Get worksheet by name
WorkSheet workSheet = workBook.GetWorkSheet("GDPByCountry");

// Handle case where worksheet doesn't exist
if (workSheet == null)
{
    Console.WriteLine("Worksheet 'GDPByCountry' not found");
    // List available worksheets
    foreach (var sheet in workBook.WorkSheets)
    {
        Console.WriteLine($"Available: {sheet.Name}");
    }
}
else
{
    Console.WriteLine($"Successfully loaded worksheet: {workSheet.Name}");
}
' Validate workbook is loaded

If workBook Is Nothing Then

	Throw New InvalidOperationException("Workbook must be loaded first")

End If



' Get worksheet by name

Dim workSheet As WorkSheet = workBook.GetWorkSheet("GDPByCountry")



' Handle case where worksheet doesn't exist

If workSheet Is Nothing Then

	Console.WriteLine("Worksheet 'GDPByCountry' not found")

	' List available worksheets

	For Each sheet In workBook.WorkSheets

		Console.WriteLine($"Available: {sheet.Name}")

	Next sheet

Else

	Console.WriteLine($"Successfully loaded worksheet: {workSheet.Name}")

End If
$vbLabelText   $csharpLabel

How Do I Create New Excel Documents in C#?

Create new Excel documents by constructing a WorkBook object with your desired file format. IronXL supports both modern XLSX and legacy XLS formats.

using IronXL;

// Create new XLSX workbook (recommended format)
WorkBook workBook = WorkBook.Create(ExcelFileFormat.XLSX);

// Set workbook metadata
workBook.Metadata.Author = "Your Application";
workBook.Metadata.Comments = "Generated by IronXL";

// Create new XLS workbook for legacy support
WorkBook legacyWorkBook = WorkBook.Create(ExcelFileFormat.XLS);

// Save the workbook
workBook.SaveAs("NewDocument.xlsx");
using IronXL;

// Create new XLSX workbook (recommended format)
WorkBook workBook = WorkBook.Create(ExcelFileFormat.XLSX);

// Set workbook metadata
workBook.Metadata.Author = "Your Application";
workBook.Metadata.Comments = "Generated by IronXL";

// Create new XLS workbook for legacy support
WorkBook legacyWorkBook = WorkBook.Create(ExcelFileFormat.XLS);

// Save the workbook
workBook.SaveAs("NewDocument.xlsx");
Imports IronXL



' Create new XLSX workbook (recommended format)

Private workBook As WorkBook = WorkBook.Create(ExcelFileFormat.XLSX)



' Set workbook metadata

workBook.Metadata.Author = "Your Application"

workBook.Metadata.Comments = "Generated by IronXL"



' Create new XLS workbook for legacy support

Dim legacyWorkBook As WorkBook = WorkBook.Create(ExcelFileFormat.XLS)



' Save the workbook

workBook.SaveAs("NewDocument.xlsx")
$vbLabelText   $csharpLabel

Note: Use ExcelFileFormat.XLS only when compatibility with Excel 2003 and earlier is required.

How Can I Add Worksheets to an Excel Document?

An IronXL WorkBook contains a collection of worksheets. Understanding this structure helps when building multi-sheet Excel files.

Diagram showing WorkBook containing multiple WorkSheets Visual representation of the WorkBook structure containing multiple WorkSheet objects in IronXL.

Create new worksheets using CreateWorkSheet():

// Create multiple worksheets with descriptive names
WorkSheet summarySheet = workBook.CreateWorkSheet("Summary");
WorkSheet dataSheet = workBook.CreateWorkSheet("RawData");
WorkSheet chartSheet = workBook.CreateWorkSheet("Charts");

// Set the active worksheet
workBook.SetActiveTab(0); // Makes "Summary" the active sheet

// Access default worksheet (first sheet)
WorkSheet defaultSheet = workBook.DefaultWorkSheet;
// Create multiple worksheets with descriptive names
WorkSheet summarySheet = workBook.CreateWorkSheet("Summary");
WorkSheet dataSheet = workBook.CreateWorkSheet("RawData");
WorkSheet chartSheet = workBook.CreateWorkSheet("Charts");

// Set the active worksheet
workBook.SetActiveTab(0); // Makes "Summary" the active sheet

// Access default worksheet (first sheet)
WorkSheet defaultSheet = workBook.DefaultWorkSheet;
' Create multiple worksheets with descriptive names

Dim summarySheet As WorkSheet = workBook.CreateWorkSheet("Summary")

Dim dataSheet As WorkSheet = workBook.CreateWorkSheet("RawData")

Dim chartSheet As WorkSheet = workBook.CreateWorkSheet("Charts")



' Set the active worksheet

workBook.SetActiveTab(0) ' Makes "Summary" the active sheet



' Access default worksheet (first sheet)

Dim defaultSheet As WorkSheet = workBook.DefaultWorkSheet
$vbLabelText   $csharpLabel

How Do I Read and Edit Cell Values?

Read and Edit a Single Cell

Access individual cells through the worksheet's indexer property. IronXL's Cell class provides strongly-typed value properties.

using IronXL;

// Load workbook and get worksheet
WorkBook workBook = WorkBook.Load("test.xlsx");
WorkSheet workSheet = workBook.DefaultWorkSheet;

// Access cell B1
IronXL.Cell cell = workSheet["B1"];

// Read cell value with type safety
string textValue = cell.StringValue;
int intValue = cell.IntValue;
decimal decimalValue = cell.DecimalValue;
DateTime? dateValue = cell.DateTimeValue;

// Check cell data type
if (cell.IsNumeric)
{
    Console.WriteLine($"Numeric value: {cell.DecimalValue}");
}
else if (cell.IsText)
{
    Console.WriteLine($"Text value: {cell.StringValue}");
}
using IronXL;

// Load workbook and get worksheet
WorkBook workBook = WorkBook.Load("test.xlsx");
WorkSheet workSheet = workBook.DefaultWorkSheet;

// Access cell B1
IronXL.Cell cell = workSheet["B1"];

// Read cell value with type safety
string textValue = cell.StringValue;
int intValue = cell.IntValue;
decimal decimalValue = cell.DecimalValue;
DateTime? dateValue = cell.DateTimeValue;

// Check cell data type
if (cell.IsNumeric)
{
    Console.WriteLine($"Numeric value: {cell.DecimalValue}");
}
else if (cell.IsText)
{
    Console.WriteLine($"Text value: {cell.StringValue}");
}
Imports IronXL



' Load workbook and get worksheet

Private workBook As WorkBook = WorkBook.Load("test.xlsx")

Private workSheet As WorkSheet = workBook.DefaultWorkSheet



' Access cell B1

Private cell As IronXL.Cell = workSheet("B1")



' Read cell value with type safety

Private textValue As String = cell.StringValue

Private intValue As Integer = cell.IntValue

Private decimalValue As Decimal = cell.DecimalValue

Private dateValue? As DateTime = cell.DateTimeValue



' Check cell data type

If cell.IsNumeric Then

	Console.WriteLine($"Numeric value: {cell.DecimalValue}")

ElseIf cell.IsText Then

	Console.WriteLine($"Text value: {cell.StringValue}")

End If
$vbLabelText   $csharpLabel

The Cell class offers multiple properties for different data types, automatically converting values when possible. For more cell operations, see the Cell formatting tutorial.

// Write different data types to cells
workSheet["A1"].Value = "Product Name";     // String
workSheet["B1"].Value = 99.95m;            // Decimal
workSheet["C1"].Value = DateTime.Today;     // Date
workSheet["D1"].Formula = "=B1*1.2";       // Formula

// Format cells
workSheet["B1"].FormatString = "$#,##0.00";  // Currency format
workSheet["C1"].FormatString = "yyyy-MM-dd"; // Date format

// Save changes
workBook.Save();
// Write different data types to cells
workSheet["A1"].Value = "Product Name";     // String
workSheet["B1"].Value = 99.95m;            // Decimal
workSheet["C1"].Value = DateTime.Today;     // Date
workSheet["D1"].Formula = "=B1*1.2";       // Formula

// Format cells
workSheet["B1"].FormatString = "$#,##0.00";  // Currency format
workSheet["C1"].FormatString = "yyyy-MM-dd"; // Date format

// Save changes
workBook.Save();
' Write different data types to cells

workSheet("A1").Value = "Product Name" ' String

workSheet("B1").Value = 99.95D ' Decimal

workSheet("C1").Value = DateTime.Today ' Date

workSheet("D1").Formula = "=B1*1.2" ' Formula



' Format cells

workSheet("B1").FormatString = "$#,##0.00" ' Currency format

workSheet("C1").FormatString = "yyyy-MM-dd" ' Date format



' Save changes

workBook.Save()
$vbLabelText   $csharpLabel

How Can I Work with Cell Ranges?

The Range class represents a collection of cells, enabling bulk operations on Excel data.

// Select range using Excel notation
Range range = workSheet["D2:D101"];

// Alternative: Use Range class for dynamic selection
Range dynamicRange = workSheet.GetRange(1, 3, 100, 3); // Row 2-101, Column D

// Perform bulk operations
range.Value = 0; // Set all cells to 0
// Select range using Excel notation
Range range = workSheet["D2:D101"];

// Alternative: Use Range class for dynamic selection
Range dynamicRange = workSheet.GetRange(1, 3, 100, 3); // Row 2-101, Column D

// Perform bulk operations
range.Value = 0; // Set all cells to 0
' Select range using Excel notation

Dim range As Range = workSheet("D2:D101")



' Alternative: Use Range class for dynamic selection

Dim dynamicRange As Range = workSheet.GetRange(1, 3, 100, 3) ' Row 2-101, Column D



' Perform bulk operations

range.Value = 0 ' Set all cells to 0
$vbLabelText   $csharpLabel

Process ranges efficiently using loops when cell count is known:

// Data validation example
public class ValidationResult
{
    public int Row { get; set; }
    public string PhoneError { get; set; }
    public string EmailError { get; set; }
    public string DateError { get; set; }
    public bool IsValid => string.IsNullOrEmpty(PhoneError) && 
                           string.IsNullOrEmpty(EmailError) && 
                           string.IsNullOrEmpty(DateError);
}

// Validate data in rows 2-101
var results = new List<ValidationResult>();

for (int row = 2; row <= 101; row++)
{
    var result = new ValidationResult { Row = row };

    // Get row data efficiently
    var phoneCell = workSheet[$"B{row}"];
    var emailCell = workSheet[$"D{row}"];
    var dateCell = workSheet[$"E{row}"];

    // Validate phone number
    if (!IsValidPhoneNumber(phoneCell.StringValue))
        result.PhoneError = "Invalid phone format";

    // Validate email
    if (!IsValidEmail(emailCell.StringValue))
        result.EmailError = "Invalid email format";

    // Validate date
    if (!dateCell.IsDateTime)
        result.DateError = "Invalid date format";

    results.Add(result);
}

// Helper methods
bool IsValidPhoneNumber(string phone) => 
    System.Text.RegularExpressions.Regex.IsMatch(phone, @"^\d{3}-\d{3}-\d{4}$");

bool IsValidEmail(string email) => 
    email.Contains("@") && email.Contains(".");
// Data validation example
public class ValidationResult
{
    public int Row { get; set; }
    public string PhoneError { get; set; }
    public string EmailError { get; set; }
    public string DateError { get; set; }
    public bool IsValid => string.IsNullOrEmpty(PhoneError) && 
                           string.IsNullOrEmpty(EmailError) && 
                           string.IsNullOrEmpty(DateError);
}

// Validate data in rows 2-101
var results = new List<ValidationResult>();

for (int row = 2; row <= 101; row++)
{
    var result = new ValidationResult { Row = row };

    // Get row data efficiently
    var phoneCell = workSheet[$"B{row}"];
    var emailCell = workSheet[$"D{row}"];
    var dateCell = workSheet[$"E{row}"];

    // Validate phone number
    if (!IsValidPhoneNumber(phoneCell.StringValue))
        result.PhoneError = "Invalid phone format";

    // Validate email
    if (!IsValidEmail(emailCell.StringValue))
        result.EmailError = "Invalid email format";

    // Validate date
    if (!dateCell.IsDateTime)
        result.DateError = "Invalid date format";

    results.Add(result);
}

// Helper methods
bool IsValidPhoneNumber(string phone) => 
    System.Text.RegularExpressions.Regex.IsMatch(phone, @"^\d{3}-\d{3}-\d{4}$");

bool IsValidEmail(string email) => 
    email.Contains("@") && email.Contains(".");
' Data validation example

Public Class ValidationResult

	Public Property Row() As Integer

	Public Property PhoneError() As String

	Public Property EmailError() As String

	Public Property DateError() As String

	Public ReadOnly Property IsValid() As Boolean

		Get

			Return String.IsNullOrEmpty(PhoneError) AndAlso String.IsNullOrEmpty(EmailError) AndAlso String.IsNullOrEmpty(DateError)

		End Get

	End Property

End Class



' Validate data in rows 2-101

Private results = New List(Of ValidationResult)()



For row As Integer = 2 To 101

	Dim result = New ValidationResult With {.Row = row}



	' Get row data efficiently

	Dim phoneCell = workSheet($"B{row}")

	Dim emailCell = workSheet($"D{row}")

	Dim dateCell = workSheet($"E{row}")



	' Validate phone number

	If Not IsValidPhoneNumber(phoneCell.StringValue) Then

		result.PhoneError = "Invalid phone format"

	End If



	' Validate email

	If Not IsValidEmail(emailCell.StringValue) Then

		result.EmailError = "Invalid email format"

	End If



	' Validate date

	If Not dateCell.IsDateTime Then

		result.DateError = "Invalid date format"

	End If



	results.Add(result)

Next row



' Helper methods

'INSTANT VB TODO TASK: Local functions are not converted by Instant VB:

'bool IsValidPhoneNumber(string phone)

'{

'	Return System.Text.RegularExpressions.Regex.IsMatch(phone, "^\d{3}-\d{3}-\d{4}$");

'}



'INSTANT VB TODO TASK: Local functions are not converted by Instant VB:

'bool IsValidEmail(string email)

'{

'	Return email.Contains("@") && email.Contains(".");

'}
$vbLabelText   $csharpLabel

How Do I Add Formulas to Excel Spreadsheets?

Apply Excel formulas using the Formula property. IronXL supports standard Excel formula syntax.

// Add formulas to calculate percentages
int lastRow = 50;
for (int row = 2; row < lastRow; row++)
{
    // Calculate percentage: current value / total
    workSheet[$"C{row}"].Formula = $"=B{row}/B{lastRow}";

    // Format as percentage
    workSheet[$"C{row}"].FormatString = "0.00%";
}

// Add summary formulas
workSheet["B52"].Formula = "=SUM(B2:B50)";      // Sum
workSheet["B53"].Formula = "=AVERAGE(B2:B50)";   // Average
workSheet["B54"].Formula = "=MAX(B2:B50)";       // Maximum
workSheet["B55"].Formula = "=MIN(B2:B50)";       // Minimum

// Force formula evaluation
workBook.EvaluateAll();
// Add formulas to calculate percentages
int lastRow = 50;
for (int row = 2; row < lastRow; row++)
{
    // Calculate percentage: current value / total
    workSheet[$"C{row}"].Formula = $"=B{row}/B{lastRow}";

    // Format as percentage
    workSheet[$"C{row}"].FormatString = "0.00%";
}

// Add summary formulas
workSheet["B52"].Formula = "=SUM(B2:B50)";      // Sum
workSheet["B53"].Formula = "=AVERAGE(B2:B50)";   // Average
workSheet["B54"].Formula = "=MAX(B2:B50)";       // Maximum
workSheet["B55"].Formula = "=MIN(B2:B50)";       // Minimum

// Force formula evaluation
workBook.EvaluateAll();
' Add formulas to calculate percentages

Dim lastRow As Integer = 50

Dim row As Integer = 2

Do While row < lastRow

	' Calculate percentage: current value / total

	workSheet($"C{row}").Formula = $"=B{row}/B{lastRow}"



	' Format as percentage

	workSheet($"C{row}").FormatString = "0.00%"

	row += 1

Loop



' Add summary formulas

workSheet("B52").Formula = "=SUM(B2:B50)" ' Sum

workSheet("B53").Formula = "=AVERAGE(B2:B50)" ' Average

workSheet("B54").Formula = "=MAX(B2:B50)" ' Maximum

workSheet("B55").Formula = "=MIN(B2:B50)" ' Minimum



' Force formula evaluation

workBook.EvaluateAll()
$vbLabelText   $csharpLabel

To edit existing formulas, explore the Excel formulas tutorial.

How Can I Validate Spreadsheet Data?

IronXL enables comprehensive data validation for spreadsheets. This example validates phone numbers, emails, and dates using external libraries and built-in C# functionality.

using System.Text.RegularExpressions;
using IronXL;

// Validation implementation
for (int i = 2; i <= 101; i++)
{
    var result = new PersonValidationResult { Row = i };
    results.Add(result);

    // Get cells for current person
    var cells = workSheet[$"A{i}:E{i}"].ToList();

    // Validate phone (column B)
    string phone = cells[1].StringValue;
    if (!Regex.IsMatch(phone, @"^\+?1?\d{10,14}$"))
    {
        result.PhoneNumberErrorMessage = "Invalid phone format";
    }

    // Validate email (column D)
    string email = cells[3].StringValue;
    if (!Regex.IsMatch(email, @"^[^@\s]+@[^@\s]+\.[^@\s]+$"))
    {
        result.EmailErrorMessage = "Invalid email address";
    }

    // Validate date (column E)
    if (!cells[4].IsDateTime)
    {
        result.DateErrorMessage = "Invalid date format";
    }
}
using System.Text.RegularExpressions;
using IronXL;

// Validation implementation
for (int i = 2; i <= 101; i++)
{
    var result = new PersonValidationResult { Row = i };
    results.Add(result);

    // Get cells for current person
    var cells = workSheet[$"A{i}:E{i}"].ToList();

    // Validate phone (column B)
    string phone = cells[1].StringValue;
    if (!Regex.IsMatch(phone, @"^\+?1?\d{10,14}$"))
    {
        result.PhoneNumberErrorMessage = "Invalid phone format";
    }

    // Validate email (column D)
    string email = cells[3].StringValue;
    if (!Regex.IsMatch(email, @"^[^@\s]+@[^@\s]+\.[^@\s]+$"))
    {
        result.EmailErrorMessage = "Invalid email address";
    }

    // Validate date (column E)
    if (!cells[4].IsDateTime)
    {
        result.DateErrorMessage = "Invalid date format";
    }
}
Imports System.Text.RegularExpressions

Imports IronXL



' Validation implementation

For i As Integer = 2 To 101

	Dim result = New PersonValidationResult With {.Row = i}

	results.Add(result)



	' Get cells for current person

	Dim cells = workSheet($"A{i}:E{i}").ToList()



	' Validate phone (column B)

	Dim phone As String = cells(1).StringValue

	If Not Regex.IsMatch(phone, "^\+?1?\d{10,14}$") Then

		result.PhoneNumberErrorMessage = "Invalid phone format"

	End If



	' Validate email (column D)

	Dim email As String = cells(3).StringValue

	If Not Regex.IsMatch(email, "^[^@\s]+@[^@\s]+\.[^@\s]+$") Then

		result.EmailErrorMessage = "Invalid email address"

	End If



	' Validate date (column E)

	If Not cells(4).IsDateTime Then

		result.DateErrorMessage = "Invalid date format"

	End If

Next i
$vbLabelText   $csharpLabel

Save validation results to a new worksheet:

// Create results worksheet
var resultsSheet = workBook.CreateWorkSheet("ValidationResults");

// Add headers
resultsSheet["A1"].Value = "Row";
resultsSheet["B1"].Value = "Valid";
resultsSheet["C1"].Value = "Phone Error";
resultsSheet["D1"].Value = "Email Error";
resultsSheet["E1"].Value = "Date Error";

// Style headers
resultsSheet["A1:E1"].Style.Font.Bold = true;
resultsSheet["A1:E1"].Style.SetBackgroundColor("#4472C4");
resultsSheet["A1:E1"].Style.Font.Color = "#FFFFFF";

// Output validation results
for (int i = 0; i < results.Count; i++)
{
    var result = results[i];
    int outputRow = i + 2;

    resultsSheet[$"A{outputRow}"].Value = result.Row;
    resultsSheet[$"B{outputRow}"].Value = result.IsValid ? "Yes" : "No";
    resultsSheet[$"C{outputRow}"].Value = result.PhoneNumberErrorMessage ?? "";
    resultsSheet[$"D{outputRow}"].Value = result.EmailErrorMessage ?? "";
    resultsSheet[$"E{outputRow}"].Value = result.DateErrorMessage ?? "";

    // Highlight invalid rows
    if (!result.IsValid)
    {
        resultsSheet[$"A{outputRow}:E{outputRow}"].Style.SetBackgroundColor("#FFE6E6");
    }
}

// Auto-fit columns
for (int col = 0; col < 5; col++)
{
    resultsSheet.AutoSizeColumn(col);
}

// Save validated workbook
workBook.SaveAs(@"Spreadsheets\PeopleValidated.xlsx");
// Create results worksheet
var resultsSheet = workBook.CreateWorkSheet("ValidationResults");

// Add headers
resultsSheet["A1"].Value = "Row";
resultsSheet["B1"].Value = "Valid";
resultsSheet["C1"].Value = "Phone Error";
resultsSheet["D1"].Value = "Email Error";
resultsSheet["E1"].Value = "Date Error";

// Style headers
resultsSheet["A1:E1"].Style.Font.Bold = true;
resultsSheet["A1:E1"].Style.SetBackgroundColor("#4472C4");
resultsSheet["A1:E1"].Style.Font.Color = "#FFFFFF";

// Output validation results
for (int i = 0; i < results.Count; i++)
{
    var result = results[i];
    int outputRow = i + 2;

    resultsSheet[$"A{outputRow}"].Value = result.Row;
    resultsSheet[$"B{outputRow}"].Value = result.IsValid ? "Yes" : "No";
    resultsSheet[$"C{outputRow}"].Value = result.PhoneNumberErrorMessage ?? "";
    resultsSheet[$"D{outputRow}"].Value = result.EmailErrorMessage ?? "";
    resultsSheet[$"E{outputRow}"].Value = result.DateErrorMessage ?? "";

    // Highlight invalid rows
    if (!result.IsValid)
    {
        resultsSheet[$"A{outputRow}:E{outputRow}"].Style.SetBackgroundColor("#FFE6E6");
    }
}

// Auto-fit columns
for (int col = 0; col < 5; col++)
{
    resultsSheet.AutoSizeColumn(col);
}

// Save validated workbook
workBook.SaveAs(@"Spreadsheets\PeopleValidated.xlsx");
' Create results worksheet

Dim resultsSheet = workBook.CreateWorkSheet("ValidationResults")



' Add headers

resultsSheet("A1").Value = "Row"

resultsSheet("B1").Value = "Valid"

resultsSheet("C1").Value = "Phone Error"

resultsSheet("D1").Value = "Email Error"

resultsSheet("E1").Value = "Date Error"



' Style headers

resultsSheet("A1:E1").Style.Font.Bold = True

resultsSheet("A1:E1").Style.SetBackgroundColor("#4472C4")

resultsSheet("A1:E1").Style.Font.Color = "#FFFFFF"



' Output validation results

For i As Integer = 0 To results.Count - 1

	Dim result = results(i)

	Dim outputRow As Integer = i + 2



	resultsSheet($"A{outputRow}").Value = result.Row

	resultsSheet($"B{outputRow}").Value = If(result.IsValid, "Yes", "No")

	resultsSheet($"C{outputRow}").Value = If(result.PhoneNumberErrorMessage, "")

	resultsSheet($"D{outputRow}").Value = If(result.EmailErrorMessage, "")

	resultsSheet($"E{outputRow}").Value = If(result.DateErrorMessage, "")



	' Highlight invalid rows

	If Not result.IsValid Then

		resultsSheet($"A{outputRow}:E{outputRow}").Style.SetBackgroundColor("#FFE6E6")

	End If

Next i



' Auto-fit columns

For col As Integer = 0 To 4

	resultsSheet.AutoSizeColumn(col)

Next col



' Save validated workbook

workBook.SaveAs("Spreadsheets\PeopleValidated.xlsx")
$vbLabelText   $csharpLabel

How Do I Export Excel Data to a Database?

Use IronXL with Entity Framework to export spreadsheet data directly to databases. This example demonstrates exporting country GDP data to SQLite.

using System;
using System.ComponentModel.DataAnnotations;
using Microsoft.EntityFrameworkCore;
using IronXL;

// Define entity model
public class Country
{
    [Key]
    public Guid Id { get; set; } = Guid.NewGuid();

    [Required]
    [MaxLength(100)]
    public string Name { get; set; }

    [Range(0, double.MaxValue)]
    public decimal GDP { get; set; }

    public DateTime ImportedDate { get; set; } = DateTime.UtcNow;
}
using System;
using System.ComponentModel.DataAnnotations;
using Microsoft.EntityFrameworkCore;
using IronXL;

// Define entity model
public class Country
{
    [Key]
    public Guid Id { get; set; } = Guid.NewGuid();

    [Required]
    [MaxLength(100)]
    public string Name { get; set; }

    [Range(0, double.MaxValue)]
    public decimal GDP { get; set; }

    public DateTime ImportedDate { get; set; } = DateTime.UtcNow;
}
Imports System

Imports System.ComponentModel.DataAnnotations

Imports Microsoft.EntityFrameworkCore

Imports IronXL



' Define entity model

Public Class Country

	<Key>

	Public Property Id() As Guid = Guid.NewGuid()



	<Required>

	<MaxLength(100)>

	Public Property Name() As String



	<Range(0, Double.MaxValue)>

	Public Property GDP() As Decimal



	Public Property ImportedDate() As DateTime = DateTime.UtcNow

End Class
$vbLabelText   $csharpLabel

Configure Entity Framework context for database operations:

public class CountryContext : DbContext
{
    public DbSet<Country> Countries { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        // Configure SQLite connection
        optionsBuilder.UseSqlite("Data Source=CountryGDP.db");

        // Enable sensitive data logging in development
        #if DEBUG
        optionsBuilder.EnableSensitiveDataLogging();
        #endif
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // Configure decimal precision
        modelBuilder.Entity<Country>()
            .Property(c => c.GDP)
            .HasPrecision(18, 2);
    }
}
public class CountryContext : DbContext
{
    public DbSet<Country> Countries { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        // Configure SQLite connection
        optionsBuilder.UseSqlite("Data Source=CountryGDP.db");

        // Enable sensitive data logging in development
        #if DEBUG
        optionsBuilder.EnableSensitiveDataLogging();
        #endif
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // Configure decimal precision
        modelBuilder.Entity<Country>()
            .Property(c => c.GDP)
            .HasPrecision(18, 2);
    }
}
Public Class CountryContext

	Inherits DbContext



	Public Property Countries() As DbSet(Of Country)



	Protected Overrides Sub OnConfiguring(ByVal optionsBuilder As DbContextOptionsBuilder)

		' Configure SQLite connection

		optionsBuilder.UseSqlite("Data Source=CountryGDP.db")



		' Enable sensitive data logging in development

		#If DEBUG Then

		optionsBuilder.EnableSensitiveDataLogging()

		#End If

	End Sub



	Protected Overrides Sub OnModelCreating(ByVal modelBuilder As ModelBuilder)

		' Configure decimal precision

		modelBuilder.Entity(Of Country)().Property(Function(c) c.GDP).HasPrecision(18, 2)

	End Sub

End Class
$vbLabelText   $csharpLabel

Please note
Note: To use different databases, install the appropriate NuGet package (e.g., Microsoft.EntityFrameworkCore.SqlServer for SQL Server) and modify the connection configuration accordingly.

Import Excel data to database:

using System.Threading.Tasks;
using IronXL;
using Microsoft.EntityFrameworkCore;

public async Task ImportGDPDataAsync()
{
    try
    {
        // Load Excel file
        var workBook = WorkBook.Load(@"Spreadsheets\GDP.xlsx");
        var workSheet = workBook.GetWorkSheet("GDPByCountry");

        using (var context = new CountryContext())
        {
            // Ensure database exists
            await context.Database.EnsureCreatedAsync();

            // Clear existing data (optional)
            await context.Database.ExecuteSqlRawAsync("DELETE FROM Countries");

            // Import data with progress tracking
            int totalRows = 213;
            for (int row = 2; row <= totalRows; row++)
            {
                // Read country data
                var countryName = workSheet[$"A{row}"].StringValue;
                var gdpValue = workSheet[$"B{row}"].DecimalValue;

                // Skip empty rows
                if (string.IsNullOrWhiteSpace(countryName))
                    continue;

                // Create and add entity
                var country = new Country
                {
                    Name = countryName.Trim(),
                    GDP = gdpValue * 1_000_000 // Convert to actual value if in millions
                };

                await context.Countries.AddAsync(country);

                // Save in batches for performance
                if (row % 50 == 0)
                {
                    await context.SaveChangesAsync();
                    Console.WriteLine($"Imported {row - 1} of {totalRows} countries");
                }
            }

            // Save remaining records
            await context.SaveChangesAsync();
            Console.WriteLine($"Successfully imported {await context.Countries.CountAsync()} countries");
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Import failed: {ex.Message}");
        throw;
    }
}
using System.Threading.Tasks;
using IronXL;
using Microsoft.EntityFrameworkCore;

public async Task ImportGDPDataAsync()
{
    try
    {
        // Load Excel file
        var workBook = WorkBook.Load(@"Spreadsheets\GDP.xlsx");
        var workSheet = workBook.GetWorkSheet("GDPByCountry");

        using (var context = new CountryContext())
        {
            // Ensure database exists
            await context.Database.EnsureCreatedAsync();

            // Clear existing data (optional)
            await context.Database.ExecuteSqlRawAsync("DELETE FROM Countries");

            // Import data with progress tracking
            int totalRows = 213;
            for (int row = 2; row <= totalRows; row++)
            {
                // Read country data
                var countryName = workSheet[$"A{row}"].StringValue;
                var gdpValue = workSheet[$"B{row}"].DecimalValue;

                // Skip empty rows
                if (string.IsNullOrWhiteSpace(countryName))
                    continue;

                // Create and add entity
                var country = new Country
                {
                    Name = countryName.Trim(),
                    GDP = gdpValue * 1_000_000 // Convert to actual value if in millions
                };

                await context.Countries.AddAsync(country);

                // Save in batches for performance
                if (row % 50 == 0)
                {
                    await context.SaveChangesAsync();
                    Console.WriteLine($"Imported {row - 1} of {totalRows} countries");
                }
            }

            // Save remaining records
            await context.SaveChangesAsync();
            Console.WriteLine($"Successfully imported {await context.Countries.CountAsync()} countries");
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Import failed: {ex.Message}");
        throw;
    }
}
Imports System.Threading.Tasks

Imports IronXL

Imports Microsoft.EntityFrameworkCore



Public Async Function ImportGDPDataAsync() As Task

	Try

		' Load Excel file

		Dim workBook = WorkBook.Load("Spreadsheets\GDP.xlsx")

		Dim workSheet = workBook.GetWorkSheet("GDPByCountry")



		Using context = New CountryContext()

			' Ensure database exists

			Await context.Database.EnsureCreatedAsync()



			' Clear existing data (optional)

			Await context.Database.ExecuteSqlRawAsync("DELETE FROM Countries")



			' Import data with progress tracking

			Dim totalRows As Integer = 213

			Dim row As Integer = 2

			Do While row <= totalRows

				' Read country data

				Dim countryName = workSheet($"A{row}").StringValue

				Dim gdpValue = workSheet($"B{row}").DecimalValue



				' Skip empty rows

				If String.IsNullOrWhiteSpace(countryName) Then

					row += 1

					Continue Do

				End If



				' Create and add entity

				Dim country As New Country With {

					.Name = countryName.Trim(),

					.GDP = gdpValue * 1_000_000

				}



				Await context.Countries.AddAsync(country)



				' Save in batches for performance

				If row Mod 50 = 0 Then

					Await context.SaveChangesAsync()

					Console.WriteLine($"Imported {row - 1} of {totalRows} countries")

				End If

				row += 1

			Loop



			' Save remaining records

			Await context.SaveChangesAsync()

			Console.WriteLine($"Successfully imported {Await context.Countries.CountAsync()} countries")

		End Using

	Catch ex As Exception

		Console.WriteLine($"Import failed: {ex.Message}")

		Throw

	End Try

End Function
$vbLabelText   $csharpLabel

How Can I Import API Data into Excel Spreadsheets?

Combine IronXL with HTTP clients to populate spreadsheets with live API data. This example uses RestClient.Net to fetch country data.

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json;
using IronXL;

// Define data model matching API response
public class RestCountry
{
    public string Name { get; set; }
    public long Population { get; set; }
    public string Region { get; set; }
    public string NumericCode { get; set; }
    public List<Language> Languages { get; set; }
}

public class Language
{
    public string Name { get; set; }
    public string NativeName { get; set; }
}

// Fetch and process API data
public async Task ImportCountryDataAsync()
{
    using var httpClient = new HttpClient();

    try
    {
        // Call REST API
        var response = await httpClient.GetStringAsync("https://restcountries.com/v3.1/all");
        var countries = JsonConvert.DeserializeObject<List<RestCountry>>(response);

        // Create new workbook
        var workBook = WorkBook.Create(ExcelFileFormat.XLSX);
        var workSheet = workBook.CreateWorkSheet("Countries");

        // Add headers with styling
        string[] headers = { "Country", "Population", "Region", "Code", "Language 1", "Language 2", "Language 3" };
        for (int col = 0; col < headers.Length; col++)
        {
            var headerCell = workSheet[0, col];
            headerCell.Value = headers[col];
            headerCell.Style.Font.Bold = true;
            headerCell.Style.SetBackgroundColor("#366092");
            headerCell.Style.Font.Color = "#FFFFFF";
        }

        // Import country data
        await ProcessCountryData(countries, workSheet);

        // Save workbook
        workBook.SaveAs("CountriesFromAPI.xlsx");
    }
    catch (Exception ex)
    {
        Console.WriteLine($"API import failed: {ex.Message}");
    }
}
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json;
using IronXL;

// Define data model matching API response
public class RestCountry
{
    public string Name { get; set; }
    public long Population { get; set; }
    public string Region { get; set; }
    public string NumericCode { get; set; }
    public List<Language> Languages { get; set; }
}

public class Language
{
    public string Name { get; set; }
    public string NativeName { get; set; }
}

// Fetch and process API data
public async Task ImportCountryDataAsync()
{
    using var httpClient = new HttpClient();

    try
    {
        // Call REST API
        var response = await httpClient.GetStringAsync("https://restcountries.com/v3.1/all");
        var countries = JsonConvert.DeserializeObject<List<RestCountry>>(response);

        // Create new workbook
        var workBook = WorkBook.Create(ExcelFileFormat.XLSX);
        var workSheet = workBook.CreateWorkSheet("Countries");

        // Add headers with styling
        string[] headers = { "Country", "Population", "Region", "Code", "Language 1", "Language 2", "Language 3" };
        for (int col = 0; col < headers.Length; col++)
        {
            var headerCell = workSheet[0, col];
            headerCell.Value = headers[col];
            headerCell.Style.Font.Bold = true;
            headerCell.Style.SetBackgroundColor("#366092");
            headerCell.Style.Font.Color = "#FFFFFF";
        }

        // Import country data
        await ProcessCountryData(countries, workSheet);

        // Save workbook
        workBook.SaveAs("CountriesFromAPI.xlsx");
    }
    catch (Exception ex)
    {
        Console.WriteLine($"API import failed: {ex.Message}");
    }
}
Imports System

Imports System.Collections.Generic

Imports System.Net.Http

Imports System.Threading.Tasks

Imports Newtonsoft.Json

Imports IronXL



' Define data model matching API response

Public Class RestCountry

	Public Property Name() As String

	Public Property Population() As Long

	Public Property Region() As String

	Public Property NumericCode() As String

	Public Property Languages() As List(Of Language)

End Class



Public Class Language

	Public Property Name() As String

	Public Property NativeName() As String

End Class



' Fetch and process API data

Public Async Function ImportCountryDataAsync() As Task

	Dim httpClient As New HttpClient()



	Try

		' Call REST API

		Dim response = Await httpClient.GetStringAsync("https://restcountries.com/v3.1/all")

		Dim countries = JsonConvert.DeserializeObject(Of List(Of RestCountry))(response)



		' Create new workbook

		Dim workBook = WorkBook.Create(ExcelFileFormat.XLSX)

		Dim workSheet = workBook.CreateWorkSheet("Countries")



		' Add headers with styling

		Dim headers() As String = { "Country", "Population", "Region", "Code", "Language 1", "Language 2", "Language 3" }

		For col As Integer = 0 To headers.Length - 1

			Dim headerCell = workSheet(0, col)

			headerCell.Value = headers(col)

			headerCell.Style.Font.Bold = True

			headerCell.Style.SetBackgroundColor("#366092")

			headerCell.Style.Font.Color = "#FFFFFF"

		Next col



		' Import country data

		Await ProcessCountryData(countries, workSheet)



		' Save workbook

		workBook.SaveAs("CountriesFromAPI.xlsx")

	Catch ex As Exception

		Console.WriteLine($"API import failed: {ex.Message}")

	End Try

End Function
$vbLabelText   $csharpLabel

The API returns JSON data in this format:

JSON response structure showing country data with nested language arrays Sample JSON response from the REST Countries API showing hierarchical country information.

Process and write the API data to Excel:

private async Task ProcessCountryData(List<RestCountry> countries, WorkSheet workSheet)
{
    for (int i = 0; i < countries.Count; i++)
    {
        var country = countries[i];
        int row = i + 1; // Start from row 1 (after headers)

        // Write basic country data
        workSheet[$"A{row}"].Value = country.Name;
        workSheet[$"B{row}"].Value = country.Population;
        workSheet[$"C{row}"].Value = country.Region;
        workSheet[$"D{row}"].Value = country.NumericCode;

        // Format population with thousands separator
        workSheet[$"B{row}"].FormatString = "#,##0";

        // Add up to 3 languages
        for (int langIndex = 0; langIndex < Math.Min(3, country.Languages?.Count ?? 0); langIndex++)
        {
            var language = country.Languages[langIndex];
            string columnLetter = ((char)('E' + langIndex)).ToString();
            workSheet[$"{columnLetter}{row}"].Value = language.Name;
        }

        // Add conditional formatting for regions
        if (country.Region == "Europe")
        {
            workSheet[$"C{row}"].Style.SetBackgroundColor("#E6F3FF");
        }
        else if (country.Region == "Asia")
        {
            workSheet[$"C{row}"].Style.SetBackgroundColor("#FFF2E6");
        }

        // Show progress every 50 countries
        if (i % 50 == 0)
        {
            Console.WriteLine($"Processed {i} of {countries.Count} countries");
        }
    }

    // Auto-size all columns
    for (int col = 0; col < 7; col++)
    {
        workSheet.AutoSizeColumn(col);
    }
}
private async Task ProcessCountryData(List<RestCountry> countries, WorkSheet workSheet)
{
    for (int i = 0; i < countries.Count; i++)
    {
        var country = countries[i];
        int row = i + 1; // Start from row 1 (after headers)

        // Write basic country data
        workSheet[$"A{row}"].Value = country.Name;
        workSheet[$"B{row}"].Value = country.Population;
        workSheet[$"C{row}"].Value = country.Region;
        workSheet[$"D{row}"].Value = country.NumericCode;

        // Format population with thousands separator
        workSheet[$"B{row}"].FormatString = "#,##0";

        // Add up to 3 languages
        for (int langIndex = 0; langIndex < Math.Min(3, country.Languages?.Count ?? 0); langIndex++)
        {
            var language = country.Languages[langIndex];
            string columnLetter = ((char)('E' + langIndex)).ToString();
            workSheet[$"{columnLetter}{row}"].Value = language.Name;
        }

        // Add conditional formatting for regions
        if (country.Region == "Europe")
        {
            workSheet[$"C{row}"].Style.SetBackgroundColor("#E6F3FF");
        }
        else if (country.Region == "Asia")
        {
            workSheet[$"C{row}"].Style.SetBackgroundColor("#FFF2E6");
        }

        // Show progress every 50 countries
        if (i % 50 == 0)
        {
            Console.WriteLine($"Processed {i} of {countries.Count} countries");
        }
    }

    // Auto-size all columns
    for (int col = 0; col < 7; col++)
    {
        workSheet.AutoSizeColumn(col);
    }
}
Private Async Function ProcessCountryData(ByVal countries As List(Of RestCountry), ByVal workSheet As WorkSheet) As Task

	For i As Integer = 0 To countries.Count - 1

		Dim country = countries(i)

		Dim row As Integer = i + 1 ' Start from row 1 (after headers)



		' Write basic country data

		workSheet($"A{row}").Value = country.Name

		workSheet($"B{row}").Value = country.Population

		workSheet($"C{row}").Value = country.Region

		workSheet($"D{row}").Value = country.NumericCode



		' Format population with thousands separator

		workSheet($"B{row}").FormatString = "#,##0"



		' Add up to 3 languages

		For langIndex As Integer = 0 To Math.Min(3, If(country.Languages?.Count, 0)) - 1

			Dim language = country.Languages(langIndex)

			Dim columnLetter As String = (ChrW(AscW("E"c) + langIndex)).ToString()

			workSheet($"{columnLetter}{row}").Value = language.Name

		Next langIndex



		' Add conditional formatting for regions

		If country.Region = "Europe" Then

			workSheet($"C{row}").Style.SetBackgroundColor("#E6F3FF")

		ElseIf country.Region = "Asia" Then

			workSheet($"C{row}").Style.SetBackgroundColor("#FFF2E6")

		End If



		' Show progress every 50 countries

		If i Mod 50 = 0 Then

			Console.WriteLine($"Processed {i} of {countries.Count} countries")

		End If

	Next i



	' Auto-size all columns

	For col As Integer = 0 To 6

		workSheet.AutoSizeColumn(col)

	Next col

End Function
$vbLabelText   $csharpLabel

Object Reference and Resources

Explore the comprehensive IronXL API Reference for detailed class documentation and advanced features.

Additional tutorials for Excel operations:

Summary

IronXL.Excel is a comprehensive .NET library for reading and manipulating Excel files in various formats. It operates independently without requiring Microsoft Excel or Interop installation.

For cloud-based spreadsheet manipulation, you might also explore the Google Sheets API Client Library for .NET, which complements IronXL's local file capabilities.

Ready to implement Excel automation in your C# projects? Download IronXL or explore licensing options for production use.

Frequently Asked Questions

What is the best C# library for reading Excel files without Microsoft Office?

IronXL is the leading .NET Excel library for reading and manipulating Excel files without requiring Microsoft Office or Interop. It provides a simple API with methods like WorkBook.Load() for reading files and intuitive cell access using syntax like sheet["A1"].Value.

How do I install a C# Excel library using NuGet?

Install IronXL via NuGet Package Manager in Visual Studio by searching for 'IronXL.Excel' and clicking Install. Alternatively, use the Package Manager Console with the command Install-Package IronXL.Excel to add Excel functionality to your project.

Can I read both XLS and XLSX files in C# without Interop?

Yes, IronXL supports reading both legacy XLS and modern XLSX formats using the same WorkBook.Load() method. The library automatically detects the file format and handles the conversion internally.

How do I access specific cells and ranges in Excel using C#?

IronXL provides intuitive syntax for cell access: use sheet["A1"] for individual cells or sheet["A1:B10"] for ranges. Access cell values with properties like StringValue, IntValue, or DecimalValue for type-safe operations.

How can I validate Excel data programmatically in C#?

Use IronXL to iterate through cells and apply validation logic. Access cells with sheet["A1:E100"], then validate using C# methods like regex for emails or custom functions for business rules. Create validation reports in new worksheets using CreateWorkSheet().

Can I add formulas to Excel spreadsheets programmatically?

Yes, IronXL supports Excel formulas through the Formula property. Set formulas like cell.Formula = "=SUM(A1:A10)" and use workBook.EvaluateAll() to calculate results programmatically.

How do I export Excel data to a SQL database using C#?

Read Excel data using IronXL's WorkBook.Load() and GetWorkSheet() methods, then iterate through cells to create entity objects. Use Entity Framework's AddAsync() and SaveChangesAsync() to persist data to your database.

Can I import REST API data directly into Excel files?

Yes, combine IronXL with HTTP clients to fetch API data and populate spreadsheets. Use WorkBook.Create() to create new files, then write API responses to cells using sheet["A1"].Value. IronXL handles all Excel formatting and structure.

How do I integrate Excel functionality with ASP.NET Core applications?

IronXL fully supports ASP.NET Core. Install via NuGet, then use WorkBook and WorkSheet classes in your controllers. Generate Excel reports, process uploads, or create downloads using IronXL's memory-efficient streaming capabilities.

What are the licensing options for Excel libraries in production?

IronXL offers a free trial for development and testing. Production licenses start from $749, include dedicated support from .NET engineers, and cover deployment across servers, desktop, and cloud environments without additional Office licensing requirements.

Jacob Mellor, Chief Technology Officer @ Team Iron
Chief Technology Officer

Jacob Mellor is Chief Technology Officer at Iron Software and a visionary engineer pioneering C# PDF technology. As the original developer behind Iron Software's core codebase, he has shaped the company's product architecture since its inception, transforming it alongside CEO Cameron Rimington into a 50+ person company serving NASA, Tesla, and global government agencies.

Jacob holds a First-Class Honours Bachelor of Engineering (BEng) in Civil Engineering from the University of Manchester (1998–2001). After opening his first software business in London in 1999 and creating his first .NET components in 2005, he specialized in solving complex problems across the Microsoft ecosystem.

His flagship IronPDF & IronSuite .NET libraries have achieved over 30 million NuGet installations globally, with his foundational code continuing to power developer tools used worldwide. With 25 years of commercial experience and 41 years of coding expertise, Jacob remains focused on driving innovation in enterprise-grade C#, Java, and Python PDF technologies while mentoring the next generation of technical leaders.