IRONSOFTWAREHOME
USING IRONXL

C# DataGridView Export to Excel: Complete Guide with Formatting | IronXL

Curtis Chau
Curtis Chau
Updated: August 1, 2026

C# DataGridView Export to Excel with Formatting: The Complete Guide: Image 1 - C# DataGridView Export to Excel with Formatting

Exporting DataGridView data to an Excel file is one of the most common tasks in Windows Forms development. When building business applications that display tabular data -- whether sales reports, inventory records, or customer lists -- users expect to click a button and receive a properly formatted Excel file they can share or analyze further. The challenge is doing this cleanly, without depending on a Microsoft Excel installation on every end-user machine, and without wrestling with COM interop cleanup code that leaks memory or breaks silently. This guide walks you through the complete process of exporting DataGridView to Excel in C# using IronXL, covering everything from project setup through advanced cell formatting, so you end up with production-ready code.

First Step:
arrow pointer

How Do You Set Up a Windows Forms Project for DataGridView Export?

Traditional approaches to exporting DataGridView data relied on Microsoft Interop -- you would open Add Reference, navigate to the COM tab, select the Microsoft Excel Object Library, and write fragile code that called Marshal.ReleaseComObject to avoid memory leaks. That pattern requires Microsoft Excel installed on every machine where the application runs, performs slowly with large datasets, and often produces COMException errors in deployment environments that lack Office licenses. Microsoft's own guidance on Office Automation explicitly recommends third-party libraries for server-side and automated scenarios.

IronXL removes all of those dependencies. It is a pure .NET library that reads and writes .xlsx, .xls, .csv, and .ods files without Microsoft Office or any COM registration. You install it through NuGet and start writing code immediately.

Installing IronXL via NuGet

Start by creating a new Windows Forms App project in Visual Studio targeting .NET 10. Add a DataGridView control and a Button to the form surface. Name the button btnExport and give it the label "Export to Excel". Then open the NuGet Package Manager Console and run:

PM > Install-Package IronXL.Excel

Add the required namespaces to the top of your form file:

using IronXL;
using System.Data;

These two namespaces cover all the IronXL types you need for reading and writing Excel workbooks, and the standard System.Data types for working with DataTable objects that bridge your DataGridView to the export pipeline.

How Do You Load Sample Data into a DataGridView Control?

Before building the export logic, populate your DataGridView with representative data. The Form1_Load event is the right place to bind a DataTable as the data source. In a real application you would query a database or call a service; here a hard-coded DataTable illustrates the structure clearly. The DataGridView control overview on Microsoft Docs provides additional context on how the control manages data sources.

Binding a DataTable to DataGridView

void Form1_Load(object sender, EventArgs e)
{
    DataTable dt = new DataTable();
    dt.Columns.Add("ProductID", typeof(int));
    dt.Columns.Add("ProductName", typeof(string));
    dt.Columns.Add("Price", typeof(decimal));
    dt.Columns.Add("Stock", typeof(int));

    dt.Rows.Add(1, "Laptop", 999.99m, 50);
    dt.Rows.Add(2, "Mouse", 29.99m, 200);
    dt.Rows.Add(3, "Keyboard", 79.99m, 150);
    dt.Rows.Add(4, "Monitor", 349.99m, 75);
    dt.Rows.Add(5, "Webcam", 89.99m, 120);

    dataGridView1.DataSource = dt;
}

This code uses top-level statement style for the event handler signature. The DataTable has four typed columns -- integer, string, decimal, and integer -- which IronXL will preserve when writing to the Excel workbook. Typed columns matter because IronXL writes numeric columns as numeric cells rather than text, which lets users sort and sum values in Excel without reformatting.

C# DataGridView Export to Excel with Formatting: The Complete Guide: Image 2 - UI for the form

The DataGridView renders a column header row automatically from the DataTable column names. When you export, you want that header row preserved in the Excel file, which means your export code must handle headers separately from data rows -- the next section covers exactly that.

For production use, the same pattern applies whether the DataTable comes from Entity Framework, Dapper, ADO.NET, or any other data access layer. The DataGridView binding is decoupled from the export code, so you can swap the data source without touching the export logic.

How Do You Export DataGridView Data to an Excel File?

The core export logic runs inside the button click handler. IronXL provides a LoadFromDataTable method on WorkSheet that handles the column-to-cell mapping automatically. The cleanest approach extracts a DataTable from the DataGridView and passes it directly. The Open XML SDK, which underlies the .xlsx format, is documented by Microsoft and confirms why pure .NET solutions like IronXL outperform Interop for programmatic generation.

Button Click Export Handler

void btnExport_Click(object sender, EventArgs e)
{
    try
    {
        DataTable dt = new DataTable();

        foreach (DataGridViewColumn column in dataGridView1.Columns)
            dt.Columns.Add(column.HeaderText);

        foreach (DataGridViewRow row in dataGridView1.Rows)
        {
            if (row.IsNewRow) continue;

            DataRow dataRow = dt.NewRow();
            for (int i = 0; i < dataGridView1.Columns.Count; i++)
                dataRow[i] = row.Cells[i].Value ?? DBNull.Value;

            dt.Rows.Add(dataRow);
        }

        WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
        WorkSheet worksheet = workbook.DefaultWorkSheet;
        worksheet.Name = "Product Data";

        worksheet.LoadFromDataTable(dt, true);

        string outputPath = Path.Combine(
            Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
            "DataGridViewExport.xlsx"
        );

        workbook.SaveAs(outputPath);
        MessageBox.Show($"Exported successfully to:\n{outputPath}", "Export Complete",
            MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
    catch (Exception ex)
    {
        MessageBox.Show($"Export failed: {ex.Message}", "Error",
            MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

C# DataGridView Export to Excel with Formatting: The Complete Guide: Image 3 - Generated Excel file

The LoadFromDataTable(dt, true) call takes the DataTable and a boolean flag that tells IronXL to write the column names as the first Excel row -- those become your header cells. The workbook is saved to the user's Desktop using Environment.SpecialFolder.Desktop rather than a hard-coded path, which makes the code portable across user accounts.

The null check (?? DBNull.Value) prevents a NullReferenceException when a cell contains no value. This is important for real-world data where optional fields may be empty. IronXL writes DBNull as an empty cell rather than the string "DBNull", so the output stays clean.

For more details on reading data back from Excel files into a DataGridView, see the IronXL DataTable documentation, which covers the reverse operation and how to convert Excel to DataSet for multi-sheet workbooks.

How Do You Apply Professional Formatting to the Exported Excel File?

Plain data in an Excel file is functional, but professionally formatted output -- bold headers, column widths fitted to content, alternating row background colors -- makes the difference between a tool users trust and one they export and immediately reformat by hand. IronXL exposes a rich cell styling API that covers fonts, colors, borders, number formats, and alignment. The OOXML specification for spreadsheet styles defines the underlying format that IronXL writes, giving you confidence the output opens correctly in any compliant application.

Applying Header Styles and Alternating Row Colors

void ExportWithFormatting(object sender, EventArgs e)
{
    WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
    WorkSheet worksheet = workbook.DefaultWorkSheet;
    worksheet.Name = "Formatted Export";

    string[] headers = { "ID", "Product Name", "Price", "Stock" };

    // Write and style header row
    for (int col = 0; col < headers.Length; col++)
    {
        char colLetter = (char)('A' + col);
        string cellAddress = $"{colLetter}1";

        worksheet.SetCellValue(0, col, headers[col]);
        worksheet[cellAddress].Style.Font.Bold = true;
        worksheet[cellAddress].Style.Font.Height = 12;
        worksheet[cellAddress].Style.SetBackgroundColor("#4472C4");
        worksheet[cellAddress].Style.Font.Color = "#FFFFFF";
        worksheet[cellAddress].Style.HorizontalAlignment =
            IronXL.Styles.HorizontalAlignment.Center;
    }

    // Write data rows with alternating background colors
    int rowIndex = 1;
    foreach (DataGridViewRow row in dataGridView1.Rows)
    {
        if (row.IsNewRow) continue;

        for (int col = 0; col < dataGridView1.Columns.Count; col++)
        {
            worksheet.SetCellValue(rowIndex, col,
                row.Cells[col].Value?.ToString() ?? string.Empty);
        }

        if (rowIndex % 2 == 0)
        {
            string rangeAddress = $"A{rowIndex + 1}:D{rowIndex + 1}";
            worksheet[rangeAddress].Style.SetBackgroundColor("#D6DCE5");
        }

        rowIndex++;
    }

    // Format the Price column as currency
    worksheet["C2:C100"].Style.Format = "$#,##0.00";

    // Auto-fit column widths
    worksheet.AutoSizeColumn(0);
    worksheet.AutoSizeColumn(1);
    worksheet.AutoSizeColumn(2);
    worksheet.AutoSizeColumn(3);

    string outputPath = Path.Combine(
        Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
        "FormattedExport.xlsx"
    );

    workbook.SaveAs(outputPath);
    MessageBox.Show("Formatted export complete.", "Done",
        MessageBoxButtons.OK, MessageBoxIcon.Information);
}

C# DataGridView Export to Excel with Formatting: The Complete Guide: Image 4 - Output for the generated formatted Excel file

The formatting code applies several techniques. The header row gets a blue background (#4472C4) with white text, 12-point bold font, and centered alignment -- a standard business spreadsheet style. Data rows alternate between white and light gray (#D6DCE5) every even row, which makes it easier for users to read across wide tables without losing their place. The Price column uses Excel's built-in currency format ($#,##0.00), so values display with dollar signs and two decimal places in the spreadsheet without changing the underlying numeric data. AutoSizeColumn fits each column to its longest value so no content is truncated.

You can extend this pattern further with cell border styling, conditional formatting, and data validation rules. For reports that must match a corporate template, you can also set the page layout and print area so the exported file is ready to print without adjustment.

How Do You Handle Large Datasets and Performance Tuning?

When a DataGridView is bound to thousands of rows, iterating cell by cell becomes noticeably slow. Two optimizations improve performance significantly. First, use LoadFromDataTable instead of per-cell SetCellValue calls. Second, if your data source is a DataTable, pass it directly to IronXL rather than extracting values through the DataGridView rows:

void ExportLargeDataset(DataTable sourceTable)
{
    WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLSX);
    WorkSheet worksheet = workbook.DefaultWorkSheet;

    // Direct DataTable load -- fastest path for large data
    worksheet.LoadFromDataTable(sourceTable, true);

    // Apply header styling after load
    int colCount = sourceTable.Columns.Count;
    for (int col = 0; col < colCount; col++)
    {
        char colLetter = (char)('A' + col);
        worksheet[$"{colLetter}1"].Style.Font.Bold = true;
        worksheet[$"{colLetter}1"].Style.SetBackgroundColor("#4472C4");
        worksheet[$"{colLetter}1"].Style.Font.Color = "#FFFFFF";
    }

    workbook.SaveAs(Path.Combine(
        Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
        "LargeExport.xlsx"
    ));
}

For datasets with more than 10,000 rows, running the export on a background thread keeps the UI responsive. Wrap the export logic in Task.Run and marshal the MessageBox.Show call back to the UI thread using Invoke. IronXL is thread-safe for write operations on separate WorkBook instances, so you can run multiple exports concurrently if needed.

Additional performance resources:

How Do You Compare IronXL to Microsoft Interop for DataGridView Export?

Many developers start with Microsoft Excel Interop because it ships with Office and requires no additional packages. However, Interop has real-world costs that show up quickly in production environments. The following table summarizes the key differences:

IronXL vs. Microsoft Excel Interop for DataGridView Export
CapabilityIronXLMicrosoft Interop
Requires Microsoft Excel installedNoYes
Works in server / cloud environmentsYesNo (unsupported by Microsoft)
COM object cleanup requiredNoYes (Marshal.ReleaseComObject)
Performance with large datasetsFast (pure .NET)Slow (COM marshalling overhead)
Install methodNuGetCOM reference / Office installation
Supported .NET versions.NET 4.6.2 -- .NET 10.NET Framework only (limited)
XLSX, CSV, ODS supportYesXLSX/XLS only via Excel

Microsoft's own documentation warns against using Office Interop on servers or in service accounts, citing stability and licensing concerns. IronXL works correctly in Azure App Service, Windows Service hosts, Docker containers, and any other headless environment where running a desktop application like Excel is not feasible.

For teams already using Interop who want to migrate, IronXL's API maps closely enough that most WorkBook and WorkSheet operations translate directly. The IronXL migration guide covers common Interop patterns and their IronXL equivalents.

What Are Your Next Steps?

Exporting DataGridView data to Excel using IronXL requires only a NuGet package install and a few lines of code, replacing the fragile COM interop approach with a clean, maintainable solution that works in any deployment environment. The techniques covered here -- basic export, formatted output, large-dataset optimization, and a comparison table -- give you everything needed to ship this feature in a production Windows Forms application.

From here, explore these related capabilities:

Start a free IronXL trial to test the full feature set in your project, or review the IronXL licensing options when you are ready for production deployment.

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