I have a records in my DB which i would like to generate CSV, I am using CsvHelper library for that. The data structure of the records which needs to generated as a csv is given below.
Observer "additional_details" column, it contains a JSON object. A new column should be added in the csv output for each unique JSON key. See the image below
This is what I am trying to do at the moment:-
My c# model
public class Data
{
public bool ConfirmedAttendance {get; set;}
public bool DigitalDelivery {get; set;}
public string ProfileCode {get; set;}
public ExpandoObject AdditionalDetails { get; set; }
}
So, I will be getting a `IList<Data> _data;`
using var stream = new MemoryStream();
using var writer = new StreamWriter(stream);
using var csvWriter = new CsvWriter(writer, System.Globalization.CultureInfo.CurrentCulture);
csvWriter.Configuration.HasHeaderRecord = true;
csvWriter.WriteHeader<Data>();
//A dictionary to hold each column and its value.
var _addintionalDetails = new Dictionary<string, string>();
//populating the above dictionary with the unique json key.
foreach (var record in _data)
{
foreach (var item in (IDictionary<String, Object>)record.AdditionalDetails)
{
if(!_addintionalDetails.ContainsKey(item.Key))
{
_addintionalDetails.Add(item.Key, item.Value.ToString());
}
}
}
//Adding new column in the csv output from the above dictionary.
foreach (var header in _addintionalDetails)
{
csvWriter.WriteField(header.Key.Humanize(LetterCasing.AllCaps));
}
await csvWriter.NextRecordAsync();
//Adding records to my csv
foreach (var row in input.Records)
{
//How to add records for additional details ??
await AddRecordAsync(csvWriter, row);
}
writer.Flush();
stream.Seek(0, SeekOrigin.Begin);
input.Stream = stream.ToArray();
private static async Task AddRecordAsync(CsvWriter csvWriter, Data row)
{
csvWriter.WriteRecord<Data>(row);
await csvWriter.NextRecordAsync();
}
Here is an updated version of AddRecordAsync
. You would also need to pass the _addintionalDetails
to it.
private static async Task AddRecordAsync(CsvWriter csvWriter, Data row, Dictionary<string, string> _addintionalDetails)
{
csvWriter.WriteRecord(row);
var additional = row.AdditionalDetails as IDictionary<string, object>;
foreach (var header in _addintionalDetails)
{
if (additional.ContainsKey(header.Key))
{
csvWriter.WriteField(additional[header.Key]);
}
else
{
csvWriter.WriteField(string.Empty);
}
}
await csvWriter.NextRecordAsync();
}