IRONSOFTWAREHOME
USING IRONXL

Export Excel DataTable in C# | Convert Excel Data

Curtis Chau
Curtis Chau
Updated: August 1, 2026

Exporting Excel data to a DataTable gives you structured, in-memory access to spreadsheet content that works naturally with databases, UI controls, and LINQ queries. The reverse direction -- writing a DataTable back into an Excel file -- is just as important for report generation and data storage workflows. IronXL handles both directions in pure .NET, with no Microsoft Office dependency and no COM interop setup.

Install IronXL before running any of the examples below:

PM > Install-Package IronXL.Excel

Once installed, the WorkBook and WorkSheet types expose ToDataTable and ToDataSet methods that map directly onto System.Data structures. You can also reverse the process by writing DataRow values back into a worksheet and saving the file in XLSX or XLS format.

How Do You Convert an Entire Worksheet to a DataTable?

The ToDataTable method converts an entire worksheet -- or a named range -- into a System.Data.DataTable. Pass true to treat the first row as column headers, so the resulting table's column names match your spreadsheet headings exactly.

using IronXL;
using System.Data;

// Load the workbook from disk
WorkBook workbook = WorkBook.Load("customers.xlsx");

// Grab the default (first) worksheet
WorkSheet worksheet = workbook.DefaultWorkSheet;

// Convert the entire sheet; first row becomes column headers
DataTable dataTable = worksheet.ToDataTable(true);

// Iterate every row and print each cell value
foreach (DataRow row in dataTable.Rows)
{
    for (int i = 0; i < dataTable.Columns.Count; i++)
    {
        Console.Write(row[i] + "\t");
    }
    Console.WriteLine();
}

What the Code Does

WorkBook.Load reads the XLSX file without any Office automation. worksheet.ToDataTable(true) iterates each cell in the sheet and maps it to a DataRow, using the first row as DataColumn names. The resulting DataTable is a standard System.Data object -- you can bind it to a DataGridView, pass it to a SqlBulkCopy, or run LINQ queries against it immediately.

The ToDataTable call supports both XLS and XLSX formats, so the same code works for legacy spreadsheets without modification. See the IronXL DataTable and DataSet documentation for the full API reference.

How Do You Export a Specific Cell Range to a DataTable?

When a worksheet contains multiple data regions, or when you only need a subset of rows and columns, you can export a specific cell range instead of the full sheet. This approach is more efficient for large files because IronXL only processes the selected cells.

using IronXL;
using System.Data;

WorkBook workbook = WorkBook.Load("financial_report.xlsx");

// Access a named worksheet
WorkSheet worksheet = workbook.GetWorkSheet("Summary");

// Select only the region A1:D20 and convert it
DataTable dt = worksheet["A1:D20"].ToDataTable(true);

Console.WriteLine($"Rows: {dt.Rows.Count}, Columns: {dt.Columns.Count}");

foreach (DataRow row in dt.Rows)
{
    foreach (var item in row.ItemArray)
    {
        Console.Write(item + "\t");
    }
    Console.WriteLine();
}

Why Range Selection Matters

The bracket syntax worksheet["A1:D20"] returns an IronXL.Range object. Calling ToDataTable on that range limits processing to exactly those cells, which means faster execution and a smaller memory footprint when the source file has tens of thousands of rows.

You can also specify named ranges, or build the range string dynamically at runtime -- for example, $"A1:D{lastRow}" -- making the approach flexible for variable-length data exports. The Range class API reference documents all available selection and query methods.

How Do You Convert a Multi-Sheet Workbook to a DataSet?

Workbooks with multiple sheets map naturally onto System.Data.DataSet, where each sheet becomes a separate DataTable. The ToDataSet method performs this conversion in a single call.

using IronXL;
using System.Data;

WorkBook workbook = WorkBook.Load("multi_sheet.xlsx");

// Each worksheet becomes a DataTable inside the DataSet
DataSet dataSet = workbook.ToDataSet();

foreach (DataTable table in dataSet.Tables)
{
    Console.WriteLine($"Sheet: {table.TableName}");
    Console.WriteLine($"Rows:  {table.Rows.Count}");
    Console.WriteLine();
}

Accessing Sheets by Name

Each DataTable in the returned DataSet uses the original worksheet name as its TableName property, so you can retrieve a specific sheet with dataSet.Tables["Summary"] rather than iterating the collection. This makes it straightforward to build multi-sheet reporting logic or combine data from several worksheets before writing results to a database.

For more ways to work with multiple sheets and navigate workbook structure, see how to open and manage Excel worksheets.

How Do You Export a DataTable Back to an Excel File?

The import-to-DataTable direction is only half the story. When you need to write structured data back out as a spreadsheet -- for reports, downloads, or archival -- you create a new workbook, populate cells from the DataTable, and save.

using IronXL;
using System.Data;

// Build a sample DataTable
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("ProductID", typeof(int)));
dt.Columns.Add(new DataColumn("ProductName", typeof(string)));
dt.Columns.Add(new DataColumn("UnitPrice", typeof(decimal)));
dt.Rows.Add(1, "Widget Pro", 29.99m);
dt.Rows.Add(2, "Gadget Max", 49.99m);
dt.Rows.Add(3, "Sensor Kit", 14.50m);

// Create a new workbook and worksheet
WorkBook workbook = WorkBook.Create();
WorkSheet worksheet = workbook.CreateWorkSheet("Products");

// Write column headers from DataTable.Columns
for (int col = 0; col < dt.Columns.Count; col++)
{
    worksheet.SetCellValue(0, col, dt.Columns[col].ColumnName);
}

// Write data rows
for (int row = 0; row < dt.Rows.Count; row++)
{
    for (int col = 0; col < dt.Columns.Count; col++)
    {
        worksheet.SetCellValue(row + 1, col, dt.Rows[row][col]);
    }
}

// Save as XLSX
workbook.SaveAs("products_export.xlsx");
Console.WriteLine("Export complete.");

How the Cell-Writing Loop Works

SetCellValue(rowIndex, columnIndex, value) accepts object values, so you pass column names for the header row and raw cell values for data rows without any type conversion. The row offset of row + 1 reserves row 0 for headers. The resulting XLSX file is a fully valid spreadsheet -- no placeholders, no temporary files.

For larger DataTables, consider applying column auto-sizing after writing data so content displays cleanly without manual formatting.

How Do You Bind the DataTable to a DataGridView?

One of the most common reasons to export an Excel sheet to a DataTable is to display it in a Windows Forms DataGridView. Once you have a DataTable, binding is a single line of code.

using IronXL;
using System.Data;
using System.Windows.Forms;

WorkBook workbook = WorkBook.Load("inventory.xlsx");
WorkSheet worksheet = workbook.DefaultWorkSheet;
DataTable dataTable = worksheet.ToDataTable(true);

// Bind directly to a DataGridView
dataGridViewInventory.DataSource = dataTable;

What Happens at Binding Time

Setting DataSource triggers the DataGridView to read column names and row data from the DataTable. Each DataColumn becomes a grid column, and each DataRow becomes a visible row. You can apply sorting, filtering, and selection behavior through the grid's built-in controls without any additional code.

This pattern works equally well with WPF DataGrid, ASP.NET GridView, and any other .NET data-binding infrastructure. For a step-by-step guide, see how to export a DataGridView to Excel for the reverse direction.

How Do You Use LINQ Queries on an Exported DataTable?

After converting a worksheet to a DataTable, you can run LINQ queries using the AsEnumerable() extension method, which transforms each DataRow into a queryable element.

using IronXL;
using System.Data;
using System.Linq;

WorkBook workbook = WorkBook.Load("sales.xlsx");
DataTable dt = workbook.DefaultWorkSheet.ToDataTable(true);

// Filter rows where the "Revenue" column exceeds 10000
var highRevenue = dt.AsEnumerable()
    .Where(row => row.Field<double>("Revenue") > 10000)
    .OrderByDescending(row => row.Field<double>("Revenue"))
    .ToList();

Console.WriteLine($"High-revenue records: {highRevenue.Count}");
foreach (var row in highRevenue)
{
    Console.WriteLine($"{row["Product"]}: {row["Revenue"]:C}");
}

Why LINQ on DataTable Is Useful

LINQ queries give you a readable, strongly typed way to filter, sort, group, and project data from a converted worksheet. row.Field<T>(columnName) handles type coercion cleanly, throwing an InvalidCastException if a value cannot be converted rather than returning a silent null. This makes it easier to catch data quality issues early.

Combine this approach with the range-based export from the earlier section to query specific sheet regions rather than full worksheets, keeping memory usage low for large files.

How Do You Handle Null and Empty Cells During Export?

Excel spreadsheets often have gaps -- empty cells, merged regions, or placeholder text. IronXL maps empty cells to DBNull.Value in the exported DataTable, matching standard ADO.NET behavior so your existing null-handling code works without modification.

How IronXL maps Excel cell states to DataTable values
Excel cell stateDataTable valueNotes
Text valueStringReturned as-is
Numeric valueDouble or DecimalDepends on cell format
Date valueDateTimeParsed from serial number
Boolean valueBooleanTRUE/FALSE in Excel
Empty cellDBNull.ValueStandard ADO.NET null
Formula cellComputed resultIronXL evaluates the formula first

When writing a DataTable back to Excel, DBNull.Value fields produce empty cells, preserving the round-trip fidelity. If you need a default string for null fields, replace DBNull.Value with your placeholder before calling SetCellValue.

For further data preparation guidance, Microsoft's DataTable class documentation covers null handling, constraint management, and row states in depth.

How Do You Save Memory When Exporting Large Worksheets?

For worksheets with many thousands of rows, exporting the entire sheet at once allocates all data in memory simultaneously. Two IronXL patterns reduce peak memory usage:

  • Range export: Use worksheet["A1:D5000"].ToDataTable(true) to process a bounded region instead of the full sheet.
  • Batch processing: Calculate the last used row with worksheet.RowCount, then loop over fixed-size ranges -- for example, 1,000 rows at a time -- and process each batch before moving to the next.

The worksheet.RowCount and worksheet.ColumnCount properties let you build dynamic range strings without hard-coding dimensions:

using IronXL;
using System.Data;

WorkBook workbook = WorkBook.Load("large_dataset.xlsx");
WorkSheet worksheet = workbook.DefaultWorkSheet;

int batchSize = 1000;
int totalRows = worksheet.RowCount;

for (int startRow = 1; startRow <= totalRows; startRow += batchSize)
{
    int endRow = Math.Min(startRow + batchSize - 1, totalRows);
    string rangeAddress = $"A{startRow}:Z{endRow}";

    DataTable batch = worksheet[rangeAddress].ToDataTable(false);
    // Process each batch -- write to database, transform, etc.
    Console.WriteLine($"Processed rows {startRow} to {endRow}");
}

This pattern is particularly relevant for reading large Excel files in C# where memory constraints apply.

How Do You Write the DataTable to a Database?

Once you have a DataTable, inserting it into SQL Server via SqlBulkCopy is the fastest path for large datasets. SqlBulkCopy accepts a DataTable directly and streams rows in batches without building individual INSERT statements.

using IronXL;
using System.Data;
using Microsoft.Data.SqlClient;

WorkBook workbook = WorkBook.Load("orders.xlsx");
DataTable dataTable = workbook.DefaultWorkSheet.ToDataTable(true);

string connectionString = "Server=.;Database=OrdersDB;Trusted_Connection=True;";

using SqlConnection connection = new(connectionString);
connection.Open();

using SqlBulkCopy bulkCopy = new(connection);
bulkCopy.DestinationTableName = "dbo.Orders";
bulkCopy.BatchSize = 500;
bulkCopy.BulkCopyTimeout = 60;

// Map DataTable columns to database columns
bulkCopy.ColumnMappings.Add("OrderID", "OrderID");
bulkCopy.ColumnMappings.Add("CustomerName", "CustomerName");
bulkCopy.ColumnMappings.Add("TotalAmount", "TotalAmount");

bulkCopy.WriteToServer(dataTable);
Console.WriteLine("Bulk insert complete.");

Column Mapping Considerations

The ColumnMappings collection matches DataTable column names to database column names. If both names are identical, you can omit individual mappings and SqlBulkCopy will auto-match by name. Explicit mappings are safer when the spreadsheet column order differs from the database schema.

For more on combining IronXL with database workflows, the C# Excel import guide covers additional import scenarios including validation before insert.

For Entity Framework-based projects, convert your DataTable rows to typed model objects first, then use DbContext.BulkInsert from a library like EFCore.BulkExtensions for ORM-aware batch insertion. Microsoft's SqlBulkCopy documentation explains batching options and transaction support in detail.

What Are Your Next Steps?

You now have a complete toolkit for moving data between Excel and DataTable in both directions using IronXL:

  • Convert a full worksheet with worksheet.ToDataTable(true) for header-aware exports
  • Export a specific cell range with the worksheet["A1:D20"].ToDataTable(true) syntax
  • Convert multi-sheet workbooks with workbook.ToDataSet() for full DataSet access
  • Write DataTable content back to XLSX by iterating DataRow values with SetCellValue
  • Bind the DataTable to UI controls like DataGridView with a single DataSource assignment
  • Feed SqlBulkCopy directly from a DataTable for high-throughput database inserts

To deepen your IronXL skills, explore these related topics:

Start with a free IronXL trial license to run these examples in your own projects. When you are ready to deploy, purchase a production license or chat with the team for licensing guidance.

First Step:
arrow pointer
Curtis Chau
Technical Writer

Curtis Chau holds a Bachelor’s degree in Computer Science (Carleton University) and specializes in front-end development with expertise in Node.js, TypeScript, JavaScript, and React. Passionate about crafting intuitive and aesthetically pleasing user interfaces, Curtis enjoys working with modern frameworks and creating well-structured, visually appealing manuals.

...
Read More

Related Articles

Key in blue circle

Get your free 30-day Trial Key instantly.

Your trial license will be sent to your email address

No limitations. 100% unlocked. No credit card.

bullet_checkedNo credit card or account creation requiredNo limitations. 100% unlocked. No credit card.
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
Book your free Live Demo
Booking Badge

Trusted by Millions of Engineers Worldwide

Iron Software's customer logos
Get Your No-Obligation Consult
Complete the form below or email sales@ironsoftware.com
Your details will always be kept confidential.
Trusted by Millions of Engineers Worldwide
Iron Software's customer logos
Get your free 30-day Trial Key instantly.
No credit card or account creation required