Search code examples
c#datatableheadercsvhelper

CsvHelper Load DataTable from File with No Header Not Working


I have some simple code that will load a DataTable from a .csv file if it includes a header. Now I need to load a DataTable from a file without a header. I was expecting to set HasHeaderRecord = false and the DataTable would be created with default headers (Field1, Field2, ...). This is not the case, I can see the records are read by the CsvReader but since there are no headers there are no columns created in the DataTable. It seems like this should be simple, what am I missing? Also, this can't be hardcoded or loaded using a class map, since the files are dynamic.

var dt = new DataTable();

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

        var enc = System.Text.ASCIIEncoding.UTF8;

        using (var reader = new StreamReader(FileName, enc, true))
        using (var csv = new CsvReader(reader, csvConfig))
        {
            // Do any configuration to `CsvReader` before creating CsvDataReader.
            using (var dr = new CsvDataReader(csv))
            {
                dt.Load(dr);
            }
        }

Solution

  • Seems to be a bug in the library as you can read here: https://github.com/JoshClose/CsvHelper/issues/1240

    Update: Feb 1st 2024: they fixed it last week

    Since they haven't fixed it in the last 2 years, who knows if they will ever do. Until then you can use this code which should work as expected:

    using (var reader = new StreamReader(FileName, enc, true))
    using (var csv = new CsvReader(reader, csvConfig))
    using (var dr = new CsvDataReader(csv))
    {
        while (dr.Read())
        {
            if (dt.Columns.Count == 0)
            {
                for (int i = 0; i < dr.FieldCount; i++)
                    dt.Columns.Add();
            }
    
            DataRow row = dt.NewRow();
            for (int i = 0; i < dr.FieldCount; i++)
                row[i] = dr.GetString(i);
            dt.Rows.Add(row);
        }
    }