C# Read CSV File

Summary: in this tutorial, you’ll learn how to use read CSV files in C# using the CsvHelper library.

Introduction to the CSVhelper library

CsvHelper is a popular open-source library for reading and writing CSV (Comma Separated Value) files in C#.

CSVHelper is fast, flexible, and easy to use. It provides you with features to customize the CSV parsing and writing process. For example, it can map CSV columns to object properties, specify custom delimiters and quotes, and handle type conversions and errors.

The CsvHelper library is available as a NuGet package. Therefore, you need to install it via the command line or using Visual Studio’s NuGet Package Manager.

Installing CsvHelper

The following shows you how to install the CsvHelper library using the package manager console, .Net CLI console, and Visual Studio:

Package Manager Console

Install-Package CsvHelper

.NET CLI Console

dotnet add package CsvHelper

Visual Studio

If you use Visual Studio, you can follow these steps:

First, right-click the Dependencies and select the Manager NuGet Packages... menu item:

Second, type the CsvHelper, choose the package as shown in the following picture, and click the Install button:

Preparing a sample CSV file for reading

Download the following data.csv file and copy it to the project directory. To allow the program to read the CSV file, you need to change its setting so that Visual Studio will copy it to the output directory:

Reading a CSV file into a collection of dynamic objects

The following program reads the data.csv file and converts CSV rows into dynamic objects:

using CsvHelper;
using System.Globalization;
using static System.Console;


using var reader = new StreamReader("data.csv");
using var csv = new CsvReader(reader, CultureInfo.InvariantCulture);

// read CSV file
var records = csv.GetRecords<dynamic>();


// output
foreach (var r in records)
{
    WriteLine($"{r.FirstName,-15}{r.LastName,-10}{r.JoinedDate,15}{r.Salary,15}{r.Active,5}");
}Code language: PHP (php)

Output:

John           Smith            2/1/2023     245,941.00  Yes
Sarah          Johnson          3/1/2023     208,902.00  Yes
Michael        Brown            3/1/2023     215,970.00  Yes
Emily          Davis            2/1/2023     239,648.00  Yes
David          Wilson           3/1/2023     190,999.00  Yes
Jennifer       Martinez         2/1/2023     132,277.00  Yes
Robert         Garcia           2/1/2023     157,395.00  Yes
Jessica        Lee              2/1/2023     210,666.00  Yes
Christopher    Rodriguez        2/1/2023      83,272.00  Yes
Amanda         Taylor           2/1/2023     143,537.00  Yes

How it works.

First, create a StreamReader object to read the contents of the CSV file data:

using var reader = new StreamReader("data.csv");Code language: JavaScript (javascript)

The using statement ensures that the StreamReader object is disposed properly.

Second, create a new CsvHelper object with the StreamReader object and CultureInfo.InvariantCulture. The CultureInfo.InvariantCulture object specifies the culture settings for the CSV file.

using var csv = new CsvReader(reader, CultureInfo.InvariantCulture);Code language: JavaScript (javascript)

Third, read the CSV file using the GetRecords<dynamic> method that returns an IEnumerable<dynamic>. Each object in the IEnumerable<dynamic> represents a row in the CSV file:

var records = csv.GetRecords<dynamic>();Code language: HTML, XML (xml)

Finally, write each row of the CSV file to the console using a foreach loop. Note that we use the ,-15, ,-10, ,15, ,15, and ,5 format specifiers to format the output with appropriate padding and alignment:

foreach (var r in records)
{
    WriteLine($"{r.FirstName,-15}{r.LastName,-10}{r.JoinedDate,15}{r.Salary,15}{r.Active,5}");
}Code language: PHP (php)

Reading a CSV file into a collection of specific objects

The following read the data.csv file and convert each row to an Employee object:

using CsvHelper;
using System.Globalization;
using static System.Console;

class Employee
{
    public string? FirstName { get; set; }
    public string? LastName { get; set; }
    public DateOnly? JoinedDate { get; set; }
    public decimal? Salary { get; set; }
    public string? Active { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        using var reader = new StreamReader("data.csv");
        using var csv = new CsvReader(reader, CultureInfo.InvariantCulture);

        // Read CSV file
        var employees = csv.GetRecords<Employee>();


        // Output
        foreach (var e in employees)
        {
            WriteLine($"{e.FirstName,-15}{e.LastName,-10}{e.JoinedDate,15}{e.Salary,15}{e.Active,5}");
        }
    }
}Code language: JavaScript (javascript)

How it works.

First, define the Employee class with the FirstName, LastName, JoinedDate, Salary, and Active fields. Each field is corresponding to a column in the data.csv file:

class Employee
{
    public string? FirstName { get; set; }
    public string? LastName { get; set; }
    public DateOnly? JoinedDate { get; set; }
    public Decimal? Salary { get; set; }
    public String? Active { get; set; }
}Code language: JavaScript (javascript)

Second, read the data.csv file and map each row to an Employee object in the Main() method of the Program class:

class Program
{
    static void Main(string[] args)
    {
        using var reader = new StreamReader("data.csv");
        using var csv = new CsvReader(reader, CultureInfo.InvariantCulture);

        // Read CSV file
        var employees = csv.GetRecords<Employee>();


        // Output
        foreach (var e in employees)
        {
            WriteLine($"{e.FirstName,-15}{e.LastName,-10}{e.JoinedDate,15}{e.Salary,15}{e.Active,5}");
        }
    }
}
Code language: JavaScript (javascript)

In this program, we pass the Employee class to the GetRecords<Employee> instead of dynamic.

Reading a CSV file without a header

If you delete the header of the data.csv file and execute the above program, you’ll get an exception. To avoid the error, you need to create a CsvConfiguration object and pass it to the CsvHelper class:

using CsvHelper;
using CsvHelper.Configuration;
using System.Globalization;
using static System.Console;

class Employee
{
    public string? FirstName { get; set; }
    public string? LastName { get; set; }
    public DateOnly? JoinedDate { get; set; }
    public Decimal? Salary { get; set; }
    public String? Active { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        using var reader = new StreamReader("data.csv");

        var csvConfig = new CsvConfiguration(CultureInfo.InvariantCulture)
        {
            HasHeaderRecord = false
        };

        using var csv = new CsvReader(reader, csvConfig);

        // Read CSV file
        var employees = csv.GetRecords<Employee>();

        // Output
        foreach (var e in employees)
        {
            WriteLine($"{e.FirstName,-15}{e.LastName,-10}{e.JoinedDate,15}{e.Salary,15}{e.Active,5}");
        }
    }
}Code language: JavaScript (javascript)

Reading a CSV file with spaces in the header

If the header in the CSV file has spaces for example First Name instead of FirstName, you need to preprocess it before reading the file.

To do that you can use PrepareHeaderForMatch option of the CsvConfiguration object. For example, you can remove the spaces like the following example:

using CsvHelper;
using CsvHelper.Configuration;
using System.Globalization;
using static System.Console;

class Employee
{
    public string? FirstName { get; set; }
    public string? LastName { get; set; }
    public DateOnly? JoinedDate { get; set; }
    public decimal? Salary { get; set; }
    public string? Active { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        using var reader = new StreamReader("data.csv");

        var csvConfig = new CsvConfiguration(CultureInfo.InvariantCulture)
        {
            PrepareHeaderForMatch = args => args.Header.Replace(" ", string.Empty)
        };

        using var csv = new CsvReader(reader, csvConfig);

        // Read CSV file
        var employees = csv.GetRecords<Employee>();

        // Output
        foreach (var e in employees)
        {
            WriteLine($"{e.FirstName,-15}{e.LastName,-10}{e.JoinedDate,15}{e.Salary,15}{e.Active,5}");
        }
    }
}Code language: JavaScript (javascript)

In this program, we set the PrepareHeaderForMatch option in the CsvConfiguration object. We assign a lambda expression to the PrepareHeaderForMatch property.

The lambda expression accepts a PrepareHeaderForMatchArgs object and replaces the spaces in the CSV header.

var csvConfig = new CsvConfiguration(CultureInfo.InvariantCulture)
{
    PrepareHeaderForMatch = args => args.Header.Replace(" ", string.Empty)
};Code language: JavaScript (javascript)

Summary

  • Use the CsvHelper package to read CSV files.
  • Use the CsvConfiguration object to customize the way the CsvHelper parses the CSV files.
Was this tutorial helpful ?