How to Export List to CSV in C# (Native vs. CsvHelper Guide)

watch_later 2025-12-08T14:28:00+05:30

How to Export List to CSV in C# (Native & CsvHelper Examples)

Data portability is a requirement for almost every enterprise application. Whether you are building an administrative dashboard, a reporting tool, or a data migration script, you will eventually need to export a List of Objects to CSV in C#.

C# guide illustration showing how to export a List of objects to CSV file using Native StringBuilder vs CsvHelper library

While CSV (Comma Separated Values) looks like a simple text format, generating it correctly requires handling specific edge cases—such as data containing commas, quotes, or newlines.

This guide covers everything from a quick CsvHelper implementation to a dependency-free Native StringBuilder approach, ensuring your application handles data strictly according to RFC 4180 standards.

Quick Answer: The Fastest Way

If you need to convert a list to CSV immediately and can use a library, CsvHelper is the industry standard. It handles memory management and edge cases (like commas in names) automatically.

Code Snippet:

using CsvHelper;
using System.Globalization;
using System.IO;
 
public void ExportData(List<Employee> datastring filePath)
{
    using (var writer = new StreamWriter(filePath))
    using (var csv = new CsvWriter(writerCultureInfo.InvariantCulture))
    {
        csv.WriteRecords(data);
    }
}

Why CSV Export is Critical

CSV remains the universal language of data exchange. It is lightweight, human-readable, and compatible with virtually every spreadsheet software (Microsoft Excel, Google Sheets) and database system.

However, writing a CSV writer from scratch is often deceptive. A simple string.Join(",", values) works for simple data but fails immediately when a user enters a name like "Smith, John". Without proper handling, that comma splits the name into two columns, corrupting your dataset.

This guide contrasts two methods:

  1. CsvHelper: The robust, automatic solution.
  2. Native C#: The lightweight, manual solution (great for zero-dependency environments).

Prerequisites & Setup

To follow this guide, ensure you have:

  • .NET 6, .NET 8, or newer SDK installed.
  • Visual Studio 2022 or VS Code.

For the first method, we will use the popular NuGet package CsvHelper.

Install via NuGet Package Manager Console:

Install-Package CsvHelper

The Data Model:
Throughout this guide, we will use the following Employee class and data list:

public class Employee
{
    public int Id { getset; }
    public string Name { getset; }
    public string Title { getset; }
    public decimal Salary { getset; }
}
// Sample Data
var employees = new List<Employee>
{
    new Employee { Id = 1, Name = "Nikunj Satasiya", Title = "Developer", Salary = 85000 },
    new Employee { Id = 2, Name = "Smith, John", Title = "Manager", Salary = 95000 }, // Note the comma!
    new Employee { Id = 3, Name = "Bob \"The Builder\"", Title = "Contractor", Salary = 60000 } // Note the quotes!
};

Method 1: The Robust Approach (CsvHelper)

The CsvHelper library is the preferred method for most .NET developers. It relies on reflection to map your class properties to CSV headers automatically.

Why use this method?

  • Automatic Escaping: It automatically handles fields containing commas, newlines, or double quotes.
  • Type Conversion: It handles Dates, Decimals, and Booleans using the correct CultureInfo.
  • Speed: It is highly optimized for memory and speed using Span<T>.

The Implementation

Here is how to write the list to a file:

using CsvHelper;
using System.Globalization;
using System.IO;
using System.Text;
public static void WriteToCsvWithLibrary(List<Employee> employeesstring filePath)
{
    // Use UTF8 encoding to ensure special characters are handled correctly
    using (var writer = new StreamWriter(filePathfalseEncoding.UTF8))
    using (var csv = new CsvWriter(writerCultureInfo.InvariantCulture))
    {
        csv.WriteRecords(employees);
    }
}

The Result:
If you look at the output for "Smith, John", CsvHelper automatically wraps it in quotes:

Id,Name,Title,Salary
1,Nikunj Satasiya,Developer,85000
2,"Smith, John",Manager,95000
3,"Bob ""The Builder""",Contractor,60000

Note: It also escaped the internal quotes in Bob's name by doubling them (""), complying with CSV standards.

Method 2: The Native Approach (StringBuilder)

Sometimes you cannot add external libraries due to company policy, or you are writing a lightweight Azure Function and want to keep the deployment size small. In these cases, use the native StringBuilder.

The Challenge: "Edge Cases"

If you simply do this:

sb.AppendLine($"{emp.Id},{emp.Name},{emp.Title}");

You will generate broken CSV files whenever a comma appears in the data. You must manually sanitize the data.

The Solution: Manual Escaping

We need a helper method that checks if a string contains a comma or a quote. If it does, we must wrap the string in quotes and escape any existing quotes.

using System.Collections.Generic;
using System.IO;
using System.Text;
public static class NativeCsvExporter
{
    public static void WriteToCsvNative(List<Employee> employeesstring filePath)
    {
        var sb = new StringBuilder();
        // 1. Write the Header
        sb.AppendLine("Id,Name,Title,Salary");
        // 2. Loop through data
        foreach (var emp in employees)
        {
            var line = string.Format("{0},{1},{2},{3}",
                emp.Id,
                EscapeCsvValue(emp.Name),
                EscapeCsvValue(emp.Title),
                emp.Salary
            );
            sb.AppendLine(line);
        }
        // 3. Save to file
        File.WriteAllText(filePathsb.ToString(), Encoding.UTF8);
    }
    // CRITICAL: Handles commas and quotes
    private static string EscapeCsvValue(string value)
    {
        if (string.IsNullOrEmpty(value)) return "";
        // Check if value contains comma, newline, or double quote
        if (value.Contains(",") || value.Contains("\"") || value.Contains("\n"))
        {
            // Replace double quotes with double-double quotes (CSV standard)
            value = value.Replace("\"""\"\"");
            // Wrap the entire value in quotes
            return $"\"{value}\"";
        }
        return value;
    }
}

Key Takeaway: The EscapeCsvValue function mimics what CsvHelper does automatically. Without this function, your CSV export is prone to corruption.

Advanced: Asynchronous Export (Async/Await)

In modern .NET applications, especially web APIs, you should avoid blocking the main thread with File I/O operations. Using Async methods ensures your server remains responsive while the file is being written.

Here is the Async version using CsvHelper:

public static async Task WriteToCsvAsync(List<Employee> employeesstring filePath)
{
    using (var writer = new StreamWriter(filePathfalseEncoding.UTF8))
    using (var csv = new CsvWriter(writerCultureInfo.InvariantCulture))
    {
        // Use WriteRecordsAsync
        await csv.WriteRecordsAsync(employees);
    }
}

To call this method:

await WriteToCsvAsync(employees, "data.csv");

Performance: Streaming Large Datasets

What if you have 1 million records?
Loading 1 million objects into a List<T> before writing to CSV will likely cause an OutOfMemoryException.

The solution is to use streaming with IEnumerable and yield return. This processes one record at a time, keeping memory usage low.

1. Create a Data Generator (Simulator):

public static IEnumerable<Employee> GetLargeDataset()
{
    for (int i = 0; i < 1000000; i++)
    {
        // yield return generates data one by one, not all at once
        yield return new Employee
        {
            Id = i,
            Name = $"Worker {i}",
            Title = "Staff",
            Salary = 50000
        };
    }
}

2. Stream to CSV:

public static async Task ExportLargeData(string filePath)
{
    var dataStream = GetLargeDataset(); // Does not execute yet
    using (var writer = new StreamWriter(filePath))
    using (var csv = new CsvWriter(writerCultureInfo.InvariantCulture))
    {
        // Writes rows one by one as they are generated
        await csv.WriteRecordsAsync(dataStream);
    }
}

This approach ensures your application's memory footprint remains flat, regardless of whether you are exporting 1,000 or 1,000,000 rows.

ASP.NET Core: Downloading the CSV

A common requirement is creating a "Download Report" button in a web application. You generally return a FileResult (specifically a FileStreamResult or FileContentResult) from your Controller.

Here is how to generate and download a CSV in an ASP.NET Core Controller without saving it to the server's disk first (using MemoryStream):

[HttpGet("download-report")]
public IActionResult DownloadCsv()
{
    var employees = _repository.GetEmployees(); // Fetch your data
    using (var memoryStream = new MemoryStream())
    using (var streamWriter = new StreamWriter(memoryStream))
    using (var csvWriter = new CsvWriter(streamWriterCultureInfo.InvariantCulture))
    {
        csvWriter.WriteRecords(employees);
        streamWriter.Flush(); // Ensure all data is written to the memory stream
        return File(memoryStream.ToArray(), "text/csv""Employees.csv");
    }
}

Conclusion

Converting a List of Objects to CSV in C# varies in complexity depending on your needs:

  1. For 95% of use cases: Use CsvHelper. It is safer, faster to write, and handles the "comma in name" edge case automatically.
  2. For zero-dependency cases: Use StringBuilder, but ensure you implement the EscapeCsvValue logic to wrap text in quotes where necessary.
  3. For Big Data: Always combine CsvHelper with IEnumerable and yield return to prevent memory overflows.

By following the patterns in this guide, you ensure your data exports are robust, compliant with CSV standards, and performant enough for enterprise-grade applications.

Codingvila provides articles and blogs on web and software development for beginners as well as free Academic projects for final year students in Asp.Net, MVC, C#, Vb.Net, SQL Server, Angular Js, Android, PHP, Java, Python, Desktop Software Application and etc.

If you have any questions, contact us on info.codingvila@gmail.com

sentiment_satisfied Emoticon