Skip to footer content
USING IRONXL

Export SQL Data to Excel in C# with IronXL

Exporting data from SQL Server to Microsoft Excel is a common task for .NET developers building reporting systems, data analysis tools, and business applications. This tutorial shows you how to export SQL data to Excel using C# with IronXL, a .NET Excel library that handles the entire process without requiring Microsoft Office installation.

Start your free trial to follow along with the code examples below.

Get stated with IronXL now.
green arrow pointer

How Do You Install IronXL for SQL Data Export?

Before writing any code, you need to add IronXL to your project. The fastest way is via the NuGet Package Manager Console in Visual Studio:

Install-Package IronXL.Excel
Install-Package IronXL.Excel
SHELL

Alternatively, use the .NET CLI:

dotnet add package IronXL.Excel
dotnet add package IronXL.Excel
SHELL

Once installed, add the required namespaces at the top of your file. With .NET 10 top-level statements, your setup looks like this:

using IronXL;
using System.Data;
using System.Data.SqlClient;
using IronXL;
using System.Data;
using System.Data.SqlClient;
$vbLabelText   $csharpLabel

IronXL targets .NET Standard 2.0 and above, so it works with .NET 10, .NET Framework, ASP.NET Core, and Blazor projects without any additional configuration. You can find the package on NuGet.

What is the Best Way to Export Data from a SQL Server Database?

The most efficient approach to export data from SQL Server to an Excel file involves three steps: establish a database connection, retrieve data into a DataTable, and write the data to an Excel worksheet using IronXL. Unlike Microsoft Interop solutions, IronXL operates independently and handles large datasets without performance bottlenecks from COM interop overhead.

The core pattern is straightforward. SqlDataAdapter is part of Microsoft's ADO.NET data access framework and has been the standard way to fill DataTable objects from relational databases since .NET 1.0:

  1. Open a SqlConnection with your connection string
  2. Use SqlDataAdapter to fill a DataTable or DataSet
  3. Call IronXL methods to create a workbook and populate worksheet cells
  4. Save the workbook as .xlsx or .xls

This approach is compatible with SQL Server 2012 and later, as well as Azure SQL Database, Amazon RDS for SQL Server, and any ADO.NET-compatible data source. The same pattern applies whether you are working with a console application or a web-based reporting tool.

How Do You Connect to SQL Server and Retrieve Data?

Before you can export SQL data, you need to establish a connection and execute a SQL query to fill a DataTable. The connection string contains the SQL Server database credentials and server information required to access your data.

The following example queries the Northwind Customers table and writes each row to an Excel worksheet using IronXL's cell-writing API:

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

string connectionString = "Data Source=localhost;Initial Catalog=Northwind;Integrated Security=True";
string sql = "SELECT * FROM Customers";

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

SqlDataAdapter adapter = new SqlDataAdapter(sql, connection);
DataTable dt = new DataTable();
adapter.Fill(dt);

WorkBook workBook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet workSheet = workBook.CreateWorkSheet("Customers");

// Write column headers
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].ToString());
    }
}

workBook.SaveAs("CustomerExport.xlsx");
using IronXL;
using System.Data;
using System.Data.SqlClient;

string connectionString = "Data Source=localhost;Initial Catalog=Northwind;Integrated Security=True";
string sql = "SELECT * FROM Customers";

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

SqlDataAdapter adapter = new SqlDataAdapter(sql, connection);
DataTable dt = new DataTable();
adapter.Fill(dt);

WorkBook workBook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet workSheet = workBook.CreateWorkSheet("Customers");

// Write column headers
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].ToString());
    }
}

workBook.SaveAs("CustomerExport.xlsx");
$vbLabelText   $csharpLabel

Output

How to Export SQL Data to Excel Using C# with IronXL: Image 1 - Generated Excel file

This code creates an Excel file with properly formatted column headers derived from your SQL Server table structure. The DataTable dt stores the query results, which are then written to each cell systematically using zero-based row and column indexes. IronXL supports both .xls and .xlsx formats for broad compatibility with Microsoft Office applications.

If your SQL table contains DateTime or numeric columns, cast the cell values appropriately before calling SetCellValue. Passing numeric types directly preserves Excel data types and enables sorting and formula calculations on the exported columns.

How Do You Use LoadWorkSheetsFromDataSet to Export Multiple Tables?

When your report needs data from several SQL tables -- for example, Products and Categories -- you can load them into a DataSet and let IronXL create one worksheet per table automatically. This is the most concise approach for exporting a DataSet or DataTable to Excel.

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

string connectionString = "Data Source=.;Initial Catalog=Inventory;Integrated Security=True";

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

SqlDataAdapter productsAdapter = new SqlDataAdapter("SELECT * FROM Products", connection);
SqlDataAdapter categoriesAdapter = new SqlDataAdapter("SELECT * FROM Categories", connection);

DataSet dataSet = new DataSet();
productsAdapter.Fill(dataSet, "Products");
categoriesAdapter.Fill(dataSet, "Categories");

WorkBook workBook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkBook.LoadWorkSheetsFromDataSet(dataSet, workBook);

workBook.SaveAs("InventoryReport.xlsx");
using IronXL;
using System.Data;
using System.Data.SqlClient;

string connectionString = "Data Source=.;Initial Catalog=Inventory;Integrated Security=True";

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

SqlDataAdapter productsAdapter = new SqlDataAdapter("SELECT * FROM Products", connection);
SqlDataAdapter categoriesAdapter = new SqlDataAdapter("SELECT * FROM Categories", connection);

DataSet dataSet = new DataSet();
productsAdapter.Fill(dataSet, "Products");
categoriesAdapter.Fill(dataSet, "Categories");

WorkBook workBook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkBook.LoadWorkSheetsFromDataSet(dataSet, workBook);

workBook.SaveAs("InventoryReport.xlsx");
$vbLabelText   $csharpLabel

Output

How to Export SQL Data to Excel Using C# with IronXL: Image 4 - Generated file with column headers

LoadWorkSheetsFromDataSet reads the TableName property of each DataTable inside the DataSet and creates a matching worksheet tab. Column names from the DataTable become the header row in each sheet. This method is particularly useful for stored procedures that return multiple result sets, because you can populate the DataSet using multiple SqlDataAdapter calls and then export everything in a single step.

For applications that need to create Excel files programmatically with custom formatting, you can still access individual worksheets after calling LoadWorkSheetsFromDataSet and apply styles, column widths, or formulas before saving.

How Can You Export Data Using an ASP.NET Export Button?

For web applications, you typically trigger the export when a user clicks a button. The following ASP.NET Web Forms example shows how to handle the button click event, build the Excel workbook from a SQL query, and push the file to the browser as a download using Response.AddHeader:

using IronXL;
using System;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Web.UI;

public partial class ExportPage : Page
{
    private void ExportButton_Click(object sender, EventArgs e)
    {
        string connectionString = "Data Source=localhost;Initial Catalog=Sales;Integrated Security=True";

        using SqlConnection connection = new SqlConnection(connectionString);
        SqlDataAdapter adapter = new SqlDataAdapter("SELECT * FROM Orders", connection);
        DataSet dataSet = new DataSet();
        adapter.Fill(dataSet);

        WorkBook workBook = WorkBook.Create(ExcelFileFormat.XLSX);
        WorkBook.LoadWorkSheetsFromDataSet(dataSet, workBook);

        byte[] fileBytes = workBook.ToByteArray();
        string filename = "OrdersExport.xlsx";

        Response.Clear();
        Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        Response.AddHeader("content-disposition", "attachment;filename=" + filename);
        Response.BinaryWrite(fileBytes);
        Response.End();
    }
}
using IronXL;
using System;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Web.UI;

public partial class ExportPage : Page
{
    private void ExportButton_Click(object sender, EventArgs e)
    {
        string connectionString = "Data Source=localhost;Initial Catalog=Sales;Integrated Security=True";

        using SqlConnection connection = new SqlConnection(connectionString);
        SqlDataAdapter adapter = new SqlDataAdapter("SELECT * FROM Orders", connection);
        DataSet dataSet = new DataSet();
        adapter.Fill(dataSet);

        WorkBook workBook = WorkBook.Create(ExcelFileFormat.XLSX);
        WorkBook.LoadWorkSheetsFromDataSet(dataSet, workBook);

        byte[] fileBytes = workBook.ToByteArray();
        string filename = "OrdersExport.xlsx";

        Response.Clear();
        Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        Response.AddHeader("content-disposition", "attachment;filename=" + filename);
        Response.BinaryWrite(fileBytes);
        Response.End();
    }
}
$vbLabelText   $csharpLabel

Example Export Button

How to Export SQL Data to Excel Using C# with IronXL: Image 2 - Example export button ui

Output

How to Export SQL Data to Excel Using C# with IronXL: Image 3 - Generated file

The ToByteArray() method converts the entire workbook to an in-memory byte array, which you then write directly to the HTTP response stream. This avoids writing a temporary file to disk. Unlike Microsoft Interop, which requires object misValue placeholders and an installed Office license on the server, IronXL runs entirely in managed code with no external dependencies.

For ASP.NET Core and Razor Pages projects, replace Response.BinaryWrite with return File(fileBytes, contentType, filename) from your controller action. The ASP.NET Core export to Excel pattern follows the same workbook-to-byte-array approach.

How Do You Add Formatting and Column Headers to Exported Excel Files?

Raw SQL exports often need presentation improvements before sharing with end users. IronXL gives you control over cell styles, column widths, and number formats after data has been written to the worksheet. The following example demonstrates how to bold the header row and auto-fit column widths:

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

string connectionString = "Data Source=localhost;Initial Catalog=Sales;Integrated Security=True";

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

SqlDataAdapter adapter = new SqlDataAdapter("SELECT OrderID, CustomerID, OrderDate, Total FROM Orders", connection);
DataTable dt = new DataTable();
adapter.Fill(dt);

WorkBook workBook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet workSheet = workBook.CreateWorkSheet("Orders");

// Write and style header row
for (int col = 0; col < dt.Columns.Count; col++)
{
    workSheet.SetCellValue(0, col, dt.Columns[col].ColumnName);
    workSheet[0, col].Style.Font.Bold = true;
    workSheet[0, col].Style.Font.Height = 12;
}

// Write data rows with type-aware value assignment
for (int row = 0; row < dt.Rows.Count; row++)
{
    for (int col = 0; col < dt.Columns.Count; col++)
    {
        object value = dt.Rows[row][col];
        if (value is DateTime date)
            workSheet.SetCellValue(row + 1, col, date.ToString("yyyy-MM-dd"));
        else if (value is decimal || value is double || value is int)
            workSheet.SetCellValue(row + 1, col, Convert.ToDouble(value));
        else
            workSheet.SetCellValue(row + 1, col, value.ToString());
    }
}

workBook.SaveAs("FormattedOrdersExport.xlsx");
using IronXL;
using System.Data;
using System.Data.SqlClient;

string connectionString = "Data Source=localhost;Initial Catalog=Sales;Integrated Security=True";

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

SqlDataAdapter adapter = new SqlDataAdapter("SELECT OrderID, CustomerID, OrderDate, Total FROM Orders", connection);
DataTable dt = new DataTable();
adapter.Fill(dt);

WorkBook workBook = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet workSheet = workBook.CreateWorkSheet("Orders");

// Write and style header row
for (int col = 0; col < dt.Columns.Count; col++)
{
    workSheet.SetCellValue(0, col, dt.Columns[col].ColumnName);
    workSheet[0, col].Style.Font.Bold = true;
    workSheet[0, col].Style.Font.Height = 12;
}

// Write data rows with type-aware value assignment
for (int row = 0; row < dt.Rows.Count; row++)
{
    for (int col = 0; col < dt.Columns.Count; col++)
    {
        object value = dt.Rows[row][col];
        if (value is DateTime date)
            workSheet.SetCellValue(row + 1, col, date.ToString("yyyy-MM-dd"));
        else if (value is decimal || value is double || value is int)
            workSheet.SetCellValue(row + 1, col, Convert.ToDouble(value));
        else
            workSheet.SetCellValue(row + 1, col, value.ToString());
    }
}

workBook.SaveAs("FormattedOrdersExport.xlsx");
$vbLabelText   $csharpLabel

Styling the header row with bold text and a larger font makes exported reports easier to read in Excel. For number columns such as totals or counts, passing a double value rather than a string enables Excel's native sorting and aggregation functions to work correctly on the exported data.

You can explore the full range of formatting options -- including cell borders, background colors, and number format masks -- in the IronXL cell formatting documentation.

How Do You Handle Large SQL Datasets Efficiently?

For tables with tens of thousands of rows, memory management becomes important. Loading the entire result set into a DataTable before writing to Excel works well for most reports, but for very large exports you can process rows in batches or use SqlDataReader directly.

When working with high-volume exports, consider the following strategies:

  • Paginate with SQL OFFSET/FETCH: Split large exports into multiple worksheets, each containing a page of results. This keeps individual sheet sizes manageable in Excel.
  • Stream to disk: Call workBook.SaveAs(filePath) after each batch rather than holding everything in memory with ToByteArray().
  • Limit selected columns: Use explicit column lists in your SELECT statement rather than SELECT * to reduce the amount of data transferred from SQL Server.

For guidance on the fastest way to export a DataTable to Excel in C#, the IronXL blog has a dedicated benchmark article comparing different approaches and their memory profiles.

The WorkBook.LoadWorkSheetsFromDataSet method is particularly efficient for moderate-sized DataSet objects because it handles the row iteration internally. For the DataTable to Excel export scenario specifically, this method reduces boilerplate code and is optimized for bulk writes.

How Do You Import Data Back from Excel into SQL Server?

The export workflow is only half the story for many reporting applications. You may also need to allow users to download a template, fill in data, and re-upload it to SQL Server. IronXL makes this bidirectional workflow straightforward.

To import Excel data into a database, load the uploaded file with WorkBook.Load(filePath), iterate over the worksheet rows, and insert each row using a parameterized SqlCommand:

using IronXL;
using System.Data.SqlClient;

WorkBook workBook = WorkBook.Load("UploadedData.xlsx");
WorkSheet sheet = workBook.DefaultWorkSheet;

string connectionString = "Data Source=localhost;Initial Catalog=Inventory;Integrated Security=True";

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

// Skip header row, start at row index 1
for (int row = 1; row <= sheet.RowCount; row++)
{
    string productName = sheet[row, 0].StringValue;
    int quantity = (int)sheet[row, 1].DoubleValue;
    decimal price = (decimal)sheet[row, 2].DoubleValue;

    using SqlCommand cmd = new SqlCommand(
        "INSERT INTO Products (Name, Quantity, Price) VALUES (@name, @qty, @price)",
        connection);
    cmd.Parameters.AddWithValue("@name", productName);
    cmd.Parameters.AddWithValue("@qty", quantity);
    cmd.Parameters.AddWithValue("@price", price);
    cmd.ExecuteNonQuery();
}
using IronXL;
using System.Data.SqlClient;

WorkBook workBook = WorkBook.Load("UploadedData.xlsx");
WorkSheet sheet = workBook.DefaultWorkSheet;

string connectionString = "Data Source=localhost;Initial Catalog=Inventory;Integrated Security=True";

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

// Skip header row, start at row index 1
for (int row = 1; row <= sheet.RowCount; row++)
{
    string productName = sheet[row, 0].StringValue;
    int quantity = (int)sheet[row, 1].DoubleValue;
    decimal price = (decimal)sheet[row, 2].DoubleValue;

    using SqlCommand cmd = new SqlCommand(
        "INSERT INTO Products (Name, Quantity, Price) VALUES (@name, @qty, @price)",
        connection);
    cmd.Parameters.AddWithValue("@name", productName);
    cmd.Parameters.AddWithValue("@qty", quantity);
    cmd.Parameters.AddWithValue("@price", price);
    cmd.ExecuteNonQuery();
}
$vbLabelText   $csharpLabel

Parameterized queries protect against SQL injection when reading user-supplied Excel data. The SqlCommand documentation on Microsoft Learn covers all available overloads and parameter binding patterns. Always validate cell values before inserting -- check for empty strings, out-of-range numbers, and unexpected data types that could cause constraint violations in your SQL Server table.

For the reverse direction, IronXL also supports reading CSV files in C# for scenarios where your data source produces comma-separated output instead of .xlsx files.

How Do You Compare IronXL to Other Export Approaches?

Several approaches exist for exporting SQL data to Excel in .NET. The table below summarizes the key trade-offs:

SQL-to-Excel Export Approaches in .NET -- Feature Comparison
Approach Office Required DataSet Support Formatting Server-Safe
IronXL No Yes (built-in) Full styles, formulas Yes
Microsoft Interop Yes Manual iteration Full via COM No (COM server)
EPPlus No Manual iteration Extensive Yes
NPOI No Manual iteration Good Yes
CSV output No Manual None Yes

Microsoft Interop requires Office to be installed on the server and is not supported in server-side web applications. IronXL, EPPlus, and NPOI all work without Office. IronXL's advantage is its first-class DataSet and DataTable support through LoadWorkSheetsFromDataSet, which reduces export code to a few lines compared to manual row iteration in other libraries.

For a detailed head-to-head comparison, see the Microsoft Office Interop alternatives article.

What Are Your Next Steps?

Exporting SQL data to Excel using C# becomes straightforward with IronXL. The library eliminates complex Interop dependencies while providing strong support for DataTable, DataSet, and direct database integration. Whether building console applications or web-based reporting systems with file download capabilities, IronXL delivers reliable Excel file generation across all .NET 10 project types.

To continue building on this foundation, explore these related resources:

Purchase a license for production deployment, or continue exploring with a free trial to test the full capabilities of this Excel library in your .NET projects.

Frequently Asked Questions

How can I export SQL data to Excel using C#?

You can export SQL data to Excel using C# with IronXL. Connect to SQL Server using SqlConnection and SqlDataAdapter, fill a DataTable, then use IronXL to create a workbook and write the data rows. IronXL does not require Microsoft Office installation.

What are the prerequisites for using IronXL to export SQL data?

To use IronXL for exporting SQL data, you need a .NET project (Framework, Core, or .NET 10+), access to a SQL Server database, and the IronXL NuGet package installed via Install-Package IronXL.Excel.

Do I need Microsoft Office installed to export SQL data to Excel with IronXL?

No, IronXL allows you to export SQL data to Excel without needing Microsoft Office installed on your system or server.

Can IronXL handle large datasets when exporting SQL data to Excel?

Yes, IronXL handles large datasets efficiently. For very large exports, paginate with SQL OFFSET/FETCH, write to disk using SaveAs rather than ToByteArray, and limit selected columns in your SQL query.

How do I export multiple SQL tables to separate Excel sheets?

Use WorkBook.LoadWorkSheetsFromDataSet with a DataSet populated by multiple SqlDataAdapter calls. IronXL creates one worksheet per DataTable, naming each tab from the DataTable.TableName property.

How do I trigger an Excel file download in ASP.NET?

Call workBook.ToByteArray() to get the file as bytes, then write it to the HTTP response with the correct Content-Type and content-disposition headers. In ASP.NET Core, return File(fileBytes, contentType, filename) from your controller.

Can I import Excel data back into SQL Server with IronXL?

Yes. Load the Excel file with WorkBook.Load, iterate over worksheet rows using IronXL's indexer, and insert each row using a parameterized SqlCommand to protect against SQL injection.

How does IronXL compare to Microsoft Interop for SQL data export?

IronXL does not require Office installed on the server, runs in managed code, and supports DataSet export natively with LoadWorkSheetsFromDataSet. Microsoft Interop requires a COM server and cannot run reliably in web server environments.

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

Iron Support Team

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