DEV Community

Allen Yang
Allen Yang

Posted on

How to Export Data to Excel Using C#: A Complete Developer’s Guide

Write Data into Excel Files with C#

In the world of software development, the ability to generate reports and export data in familiar formats is a frequent requirement. For many business applications, Microsoft Excel remains the de facto standard for data analysis, sharing, and presentation. As C# developers, we often face the challenge of programmatically transforming application data into well-structured Excel files. This isn't always straightforward; directly manipulating Excel files can be complex, involving intricate file formats and potential compatibility issues.

This tutorial aims to demystify the process, providing a comprehensive guide on how to efficiently write data to Excel files using C#. We'll explore practical approaches, from basic cell population to exporting complex data structures, ensuring your C# applications can seamlessly integrate with Excel.

The Challenge of Excel Data Export in C

C# applications frequently need to generate Excel reports for various purposes: financial summaries, inventory lists, user activity logs, or data analytics results. While CSV files offer a simpler export mechanism, they lack the rich formatting, multiple worksheets, and advanced features that Excel provides. Generating a true Excel file (.xlsx or .xls) from scratch or manipulating existing ones programmatically introduces several complexities:

  • File Format Complexity: Excel's .xlsx format (Open XML) is essentially a collection of XML files compressed into a ZIP archive. Directly interacting with this structure requires deep knowledge of the Open XML SDK, which can be verbose and time-consuming for common tasks.
  • Formatting and Styling: Beyond raw data, users often expect formatted spreadsheets – bold headers, specific date formats, colored cells, and defined column widths. Implementing these programmatically can be intricate.
  • Performance: For large datasets, efficient writing is crucial to avoid performance bottlenecks.
  • Compatibility: Ensuring the generated Excel files are compatible across different versions of Microsoft Excel.

While several libraries exist, Spire.XLS for .NET emerges as a robust and efficient solution for handling these challenges. It provides an intuitive API that abstracts away the complexities of the Excel file format, allowing developers to focus on the data and presentation aspects of their reports. Its comprehensive feature set and ease of use make it particularly well-suited for C# projects requiring extensive Excel manipulation.

Setting Up Your C# Project with Spire.XLS

Before we dive into writing data, let's set up a basic C# project and integrate the Spire.XLS for .NET library.

  1. Create a New C# Project:
    Open Visual Studio and create a new Console Application (.NET Core or .NET Framework, depending on your preference). Name it something descriptive, like ExcelDataExporter.

  2. Install Spire.XLS for .NET via NuGet:
    Spire.XLS is distributed as a NuGet package. In Visual Studio, right-click on your project in the Solution Explorer, select "Manage NuGet Packages...", and then:

    • Go to the "Browse" tab.
    • Search for Spire.XLS.
    • Select Spire.XLS and click "Install".
    • Accept any license agreements.

    Alternatively, you can use the Package Manager Console:

    Install-Package Spire.XLS
    
  3. Add Necessary using Directives:
    At the top of your C# file (e.g., Program.cs), add the following using statements to access the Spire.XLS functionalities:

    using Spire.Xls;
    using Spire.Xls.Charts; // Potentially needed for advanced charting, but good to include
    using System.Data;      // For working with DataTables
    using System.Collections.Generic; // For working with lists
    

Your project is now configured to start writing data to Excel files.

Writing Basic Data to an Excel Worksheet

Let's begin with the fundamentals: creating a new workbook, adding a worksheet, and populating individual cells with data.

using System;
using Spire.Xls;

namespace ExcelDataExporter
{
    class Program
    {
        static void Main(string[] args)
        {
            // 1. Create a new workbook instance
            Workbook workbook = new Workbook();

            // 2. Get the first worksheet (default worksheet is created automatically)
            // You can also add a new one: workbook.Worksheets.Add("MyDataSheet");
            Worksheet sheet = workbook.Worksheets[0];
            sheet.Name = "Product Sales"; // Rename the worksheet

            // 3. Write string data to a cell
            sheet.Range["A1"].Text = "Product Name";
            sheet.Range["B1"].Text = "Quantity Sold";
            sheet.Range["C1"].Text = "Unit Price";
            sheet.Range["D1"].Text = "Total Revenue";

            // 4. Write numeric data to cells
            sheet.Range["A2"].Text = "Laptop";
            sheet.Range["B2"].NumberValue = 150;
            sheet.Range["C2"].NumberValue = 1200.50;

            sheet.Range["A3"].Text = "Mouse";
            sheet.Range["B3"].NumberValue = 300;
            sheet.Range["C3"].NumberValue = 25.00;

            // 5. Write a formula to a cell
            // This formula calculates B2 * C2
            sheet.Range["D2"].Formula = "=B2*C2"; 
            sheet.Range["D3"].Formula = "=B3*C3";

            // Optional: Auto-fit columns for better readability
            sheet.AutoFitColumn(1); // Column A
            sheet.AutoFitColumn(2); // Column B
            sheet.AutoFitColumn(3); // Column C
            sheet.AutoFitColumn(4); // Column D

            // 6. Save the Excel file
            string filePath = "BasicSalesData.xlsx";
            workbook.SaveToFile(filePath, ExcelVersion.Version2016); // Specify Excel version

            Console.WriteLine($"Excel file saved to: {System.IO.Path.GetFullPath(filePath)}");

            // 7. Dispose of the workbook to release resources
            workbook.Dispose();
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

In this example:

  • We instantiate a Workbook object, which represents the entire Excel file.
  • We access the first Worksheet within the workbook.
  • The Range property allows us to target specific cells (e.g., sheet.Range["A1"]).
  • We use Text for string values and NumberValue for numerical data. Spire.XLS also supports DateTimeValue for dates.
  • Formulas can be directly assigned using the Formula property.
  • Finally, SaveToFile persists the workbook to disk, and Dispose() is called to release unmanaged resources.
Data Type in C# Spire.XLS Property Example
string Range.Text sheet.Range["A1"].Text = "Hello";
int, double Range.NumberValue sheet.Range["B2"].NumberValue = 123.45;
DateTime Range.DateTimeValue sheet.Range["C3"].DateTimeValue = DateTime.Now;
bool Range.BooleanValue sheet.Range["D4"].BooleanValue = true;
Formula Range.Formula sheet.Range["E5"].Formula = "=SUM(A1:A4)";

Advanced Data Export Techniques

Exporting individual cells is useful, but real-world applications often deal with collections of objects or DataTable structures. Spire.XLS excels at handling these scenarios efficiently.

Exporting from a List of Custom Objects

Let's define a simple Product class and export a List<Product> to Excel.

using System;
using System.Collections.Generic;
using Spire.Xls;
using Spire.Xls.Core.Spreadsheet; // For ICellStyle

namespace ExcelDataExporter
{
    public class Product
    {
        public int ProductId { get; set; }
        public string Name { get; set; }
        public decimal Price { get; set; }
        public int Stock { get; set; }
        public bool IsActive { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            // ... (previous setup code) ...

            // Create a list of products
            List<Product> products = new List<Product>
            {
                new Product { ProductId = 101, Name = "Gaming Laptop", Price = 1500.00m, Stock = 50, IsActive = true },
                new Product { ProductId = 102, Name = "Wireless Mouse", Price = 35.50m, Stock = 200, IsActive = true },
                new Product { ProductId = 103, Name = "Mechanical Keyboard", Price = 120.00m, Stock = 75, IsActive = false },
                new Product { ProductId = 104, Name = "27-inch Monitor", Price = 300.00m, Stock = 120, IsActive = true }
            };

            Workbook workbook = new Workbook();
            Worksheet sheet = workbook.Worksheets[0];
            sheet.Name = "Product Inventory";

            // Add headers
            sheet.Range["A1"].Text = "Product ID";
            sheet.Range["B1"].Text = "Product Name";
            sheet.Range["C1"].Text = "Unit Price";
            sheet.Range["D1"].Text = "Stock Quantity";
            sheet.Range["E1"].Text = "Active Status";

            // Apply formatting to headers
            ICellStyle headerStyle = workbook.Styles.Add("HeaderStyle");
            headerStyle.Font.IsBold = true;
            headerStyle.KnownColor = ExcelColors.LightBlue;
            headerStyle.Borders[BordersLineType.EdgeBottom].LineStyle = CellBorderLineStyle.Thin;
            sheet.Range["A1:E1"].Style = headerStyle;

            // Write data from the list
            for (int i = 0; i < products.Count; i++)
            {
                int row = i + 2; // Start from row 2 after headers
                Product product = products[i];

                sheet.Range[$"A{row}"].NumberValue = product.ProductId;
                sheet.Range[$"B{row}"].Text = product.Name;
                sheet.Range[$"C{row}"].NumberValue = (double)product.Price; // Cast decimal to double for Spire.XLS NumberValue
                sheet.Range[$"D{row}"].NumberValue = product.Stock;
                sheet.Range[$"E{row}"].BooleanValue = product.IsActive;
            }

            // Optional: Format price column as currency
            sheet.Range["C2:C" + (products.Count + 1)].NumberFormat = "$#,##0.00";

            // Auto-fit all columns
            sheet.AutoFitColumns();

            string filePath = "ProductInventory.xlsx";
            workbook.SaveToFile(filePath, ExcelVersion.Version2016);
            Console.WriteLine($"Excel file saved to: {System.IO.Path.GetFullPath(filePath)}");
            workbook.Dispose();
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

This example demonstrates:

  • Iterating through a List<T> and writing each property to a corresponding cell.
  • Applying basic styling to headers (bold, background color).
  • Setting number formats for currency display.

Exporting from a DataTable

Spire.XLS offers a highly efficient way to import data directly from a DataTable. This is particularly useful when dealing with data retrieved from databases.

using System;
using System.Data;
using Spire.Xls;

namespace ExcelDataExporter
{
    class Program
    {
        static void Main(string[] args)
        {
            // ... (previous setup code) ...

            // Create a sample DataTable
            DataTable dt = new DataTable("Employees");
            dt.Columns.Add("ID", typeof(int));
            dt.Columns.Add("FirstName", typeof(string));
            dt.Columns.Add("LastName", typeof(string));
            dt.Columns.Add("HireDate", typeof(DateTime));
            dt.Columns.Add("Salary", typeof(decimal));

            dt.Rows.Add(1, "Alice", "Smith", new DateTime(2020, 1, 15), 65000.00m);
            dt.Rows.Add(2, "Bob", "Johnson", new DateTime(2019, 7, 1), 72000.50m);
            dt.Rows.Add(3, "Charlie", "Brown", new DateTime(2021, 3, 20), 58000.75m);

            Workbook workbook = new Workbook();
            Worksheet sheet = workbook.Worksheets[0];
            sheet.Name = "Employee Data";

            // Import DataTable directly to the worksheet
            // The 'true' argument means to include column headers
            sheet.InsertDataTable(dt, true, 1, 1); // Start writing from cell A1

            // Apply formatting (e.g., date format, currency format)
            sheet.Range["D2:D" + (dt.Rows.Count + 1)].NumberFormat = "yyyy-mm-dd";
            sheet.Range["E2:E" + (dt.Rows.Count + 1)].NumberFormat = "$#,##0.00";

            // Auto-fit all columns
            sheet.AutoFitColumns();

            string filePath = "EmployeeDataExport.xlsx";
            workbook.SaveToFile(filePath, ExcelVersion.Version2016);
            Console.WriteLine($"Excel file saved to: {System.IO.Path.GetFullPath(filePath)}");
            workbook.Dispose();
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

The InsertDataTable method is incredibly powerful, handling column headers and data types automatically. This is often the most efficient way to export tabular data.

Method Granularity Best Use Case Overhead
Range.Text/NumberValue Cell-by-cell Small, custom data, highly specific formatting per cell Low, but tedious for large datasets
InsertDataTable() Entire table Exporting DataTable objects (e.g., from database queries) Minimal, highly optimized
Looping List<T> Row-by-row Exporting custom object collections Moderate, allows row/column level customization

Error Handling and Best Practices

When working with file operations, robust error handling is crucial.

  • try-catch Blocks: Always wrap your Excel file operations in try-catch blocks to handle potential IOException (e.g., file in use, permission issues) or other exceptions.
  • using Statements: The Workbook object, like many file-related objects, implements IDisposable. Always enclose its instantiation in a using statement to ensure that resources are properly released, even if an error occurs. This prevents file locking issues or memory leaks.

    using (Workbook workbook = new Workbook())
    {
        // ... Excel operations ...
        workbook.SaveToFile(filePath, ExcelVersion.Version2016);
    } // workbook.Dispose() is automatically called here
    
  • Path Validation: Ensure the output directory exists and the application has write permissions to it.

  • Performance for Large Data: For extremely large datasets, consider writing data in chunks or using Spire.XLS's more advanced features like InsertArray for raw data, which can be faster than InsertDataTable in some scenarios.

Conclusion

Exporting data to Excel from C# applications is a common requirement that, without the right tools, can be complex and time-consuming. As this tutorial has demonstrated, libraries like Spire.XLS for .NET provide a powerful, intuitive, and efficient way to achieve this. From writing basic values to individual cells to seamlessly exporting complex data structures like List<T> and DataTable objects, Spire.XLS streamlines the entire process.

By following the steps and examples provided, developers can easily integrate robust Excel data export capabilities into their C# projects, delivering practical and professional reports. Embrace these techniques to enhance your applications and provide your users with the flexible data output they expect.

Top comments (0)