Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic creation of columns using csvHelper

I have a worker with various fields that are fetched from server. I am using CSVHelper package to convert this class to an excel sheet. Worker has Fields like :

class Worker
{ 
    string name;
    string phone;
    string age;
    Dictionary<string,object> customerField;
}

I can map the name, phone, number like

class WorkerMap : CsvClassMap<Worker>
{
    public WorkerMap()
    {
        Map(m => m.name);
        Map(m => m.phone);
        Map(m => m.age);
    }
}

And I generate the map by :

csv.Configuration.RegisterClassMap<WorkerMap>();

Write the list of workers by :

csv.WriteRecords(workerList);

How can I map the customerField dictionary to the excel sheet such that the Key (string) is another column name and the value(object) is the value of the column.

Does CSVHelper help us do it at runtime. I looked through the documentation. Couldn't find anything that worked for me.

like image 341
hyoyin_Kyuoma Avatar asked Feb 09 '17 10:02

hyoyin_Kyuoma


1 Answers

I don't think that writing a dictionary is supported at this time. For one thing, CsvHelper would have a difficult time knowing what headers to write. Fortunately, it's not too complex to use CsvWriter manually, writing a field at a time. If we assume that each Worker has the same keys in customerField then your code might look something like this.

var firstWorker = workerList.First();
var keys = firstWorker.customerField.Keys.ToList();

var headers = new []{ "name", "phone", "age"}.Concat(keys).ToList();
var csv = new CsvWriter( textWriter );

// Write the headers
foreach( var header in headers )
{
    csv.WriteField(header);
}
csv.NextRecord();

// Write the rows
foreach( var item in workerList)
{
    csv.WriteField(item.name);
    csv.WriteField(item.phone);
    csv.WriteField(item.age);
    var dict = worker.customerField;
    foreach (var key in keys)
    {
        csv.WriteField(dict[key]);
    }
    csv.NextRecord();
}

This code is untested, but should get you pretty close to the behavior you need. If the customerField dictionary keys are not consistent in the list then the code would be a bit more complicated but it's still solvable.

like image 87
Michael Richardson Avatar answered Sep 28 '22 16:09

Michael Richardson