Search code examples
sortingcsvhelper

csvHelper Sort field while writing


I am trying to use CsvHelper library to write CSV stream to a file. All is well however I am stuck with 2 things

  • How do I add additional columns to the csv file. The additional column value will be a constant but will only be known at runtime.
  • Is there a way to sort the CSV file on a particular field if I am writing one record at a time and also when I am writing all at once
        static void Main(string[] args)
        {
            
            var records = new List<MyTest>
            {
                new MyTest { Id = 1, Name = "John", Extra = "hello" },
                new MyTest { Id = 2, Name = "Jack", Extra = "hi" },
            };

            using (var writer = new StreamWriter("C:\\Users\\machina\\AppData\\Local\\Temp\\file.csv"))
            using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
            {
                csv.Context.RegisterClassMap<TestMap<MyTest>>();

                csv.WriteRecords<MyTest>(records);
            }
        }
    }

    public interface IData
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

    public abstract class AbTest : IData
    {
        public abstract int Id { get; set; }
        public abstract string Name { get; set; }

        public abstract string Extra { get; set; }
    }

    
    public class MyTest : AbTest
    {
        public override int Id { get; set; }
        public override string Name { get; set; }

        public override string Extra { get; set; }
    }


    public class TestMap<T> : ClassMap<MyTest>
    {
        public TestMap()
        {
            AutoMap(CultureInfo.InvariantCulture);

        }
    }

The above works as I have prepared the data records however what I want to achieve is to dynamically add Extra column values to my existing stream of csv data which does not have it.

Also I saw DynamicPropertySort under csvconfiguration and wanted to check if this can be used in any way to sort the fields in my CSV stream before its written even when its writing one record at a time?
I am a novoice developer so let me know if there is a better way to achieve this.


Solution

    1. The easiest way to dynamically add columns would likely be to manually write out each row.

    2. DynamicPropertySort is just used for ordering the columns of a dynamic object. You can sort on a particular field using the linq OrderBy() method.

    static void Main(string[] args)
    {
        
        var records = new List<MyTest>
        {
            new MyTest { Id = 1, Name = "John", Extra = "hello" },
            new MyTest { Id = 2, Name = "Jack", Extra = "hi" },
        };
        
        var extraField1 = 10;
        var extraField2 = "Testing";
        
        using (var writer = new StreamWriter("C:\\Users\\machina\\AppData\\Local\\Temp\\file.csv"))
        using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
        {
            csv.Context.RegisterClassMap<TestMap>();
            
            var orderedRecords = records.OrderBy(r => r.Name);
            
            csv.WriteHeader<MyTest>();
            csv.WriteField("ExtraField1");
            csv.WriteField("ExtraField2");
            csv.NextRecord();
    
            foreach (var record in orderedRecords)
            {
                csv.WriteRecord(record);
                csv.WriteField(extraField1);
                csv.WriteField(extraField2);
                csv.NextRecord();
            }
        }
    }