Search code examples
c#.netcsvhelper

Using CSVHelper to read a CSV file and need to extract columns to arrays


I have this code here that works how I want, but I'm developing on .Net Standard and cannot use the Microsoft.VisualBasic.FileIO library. I would like to be able to do the same thing using CsvHelper

Is it possible with CsvHelper to, first get the header row as a string array. Second, get each row as a string array of items?

using Microsoft.VisualBasic.FileIO;

using (TextFieldParser csvParser = new TextFieldParser("FilePath"))
{
    csvParser.CommentTokens = new string[] { "#" };
    csvParser.SetDelimiters(new string[] { "," });
    csvParser.HasFieldsEnclosedInQuotes = true;
    csvParser.TrimWhiteSpace = true;

    string[] fields = csvParser.ReadFields();
    int arraySize = fields.Length;

    int index = Array.IndexOf(fields, columnExtracted);

    while (!csvParser.EndOfData)
    {
        fields = csvParser.ReadFields();
        string column = fields[index];
        Console.WriteLine(column);
    }
}

I tried the following code that reads the cells but breaks the line when faced with a delimiter because of the line string Csv = string.Join("\n", result.ToArray()); Is there a way to put all the info in an array? It's already stored in a string list but I cannot retrieve the data by an index.

List<string> result = new List<string>();
string value;
using (TextReader fileReader = File.OpenText("FilePath"))
{
    var csv = new CsvReader(fileReader, CultureInfo.InvariantCulture);
    csv.Configuration.HasHeaderRecord = true;
    while (csv.Read())
    {
        for (int i = 0; csv.TryGetField<string>(i, out value); i++)
        {
            result.Add(value);
        }
        if (csv.Read() == false)
            break;
    }
}
string Csv = string.Join("\n", result.ToArray());

EDIT

This is my new code now after the feedback. But, it seems that it's leaving out the header row when iterating through the List that stores all the records.

 public List<string> HeaderColumnParser(string columnExtracted, string PathToFile)
        {
            List<string> result = new List<string>();
            string value;
            using (TextReader fileReader = File.OpenText(PathToFile))
            {
                var csv = new CsvReader(fileReader, CultureInfo.InvariantCulture);

                csv.Read();
                csv.ReadHeader();
                string[] header = csv.Context.HeaderRecord;
                int extractedIndex = Array.IndexOf(header, columnExtracted);

                while (csv.Read())
                {
                    string[] row = csv.Context.Record;
                    string column = row[extractedIndex];
                    result.Add(column);
                }
            }
            return result;

Solution

  • This should work if you want each row as a string array.

    Updated for current version of CsvHelper

    • csv.Context.HeaderRecord is now csv.Context.Reader.HeaderRecord
    • csv.Context.Record is now csv.Context.Parser.Record
    using (MemoryStream stream = new MemoryStream())
    using (StreamWriter writer = new StreamWriter(stream))
    using (StreamReader reader = new StreamReader(stream))
    using (CsvReader csv = new CsvReader(reader, CultureInfo.InvariantCulture))
    {
        writer.WriteLine("Id,Name,Column3,Column4,Column5");
        writer.WriteLine("1,One,Item1,Item2,Item3");
        writer.WriteLine("2,Two,Item4,Item5,Item6");
        writer.Flush();
        stream.Position = 0;
        reader.BaseStream.Position = 0;
    
        csv.Read();
        csv.ReadHeader();
    
        string[] header = csv.Context.Reader.HeaderRecord;
        var columnExtracted = "Column3";
    
        int extractedIndex = Array.IndexOf(header, columnExtracted);
    
        while (csv.Read())
        {
            string[] row = csv.Context.Parser.Record;
            var column = row[extractedIndex];
            Console.WriteLine(column);
        }
    }
    Console.ReadKey();