Динамическое создание столбцов с помощью csvHelper
у меня есть работник с различными полями, которые извлекаются с сервера. Я использую пакет CSVHelper для преобразования этого класса в лист excel. Рабочий имеет такие поля, как:
class Worker
{
string name;
string phone;
string age;
Dictionary<string,object> customerField;
}
Я могу сопоставить имя, телефон, номер вроде
class WorkerMap : CsvClassMap<Worker>
{
public WorkerMap()
{
Map(m => m.name);
Map(m => m.phone);
Map(m => m.age);
}
}
и я генерирую карту по :
csv.Configuration.RegisterClassMap<WorkerMap>();
напишите список работников по:
csv.WriteRecords(workerList);
как я могу сопоставить словарь customerField с листом excel, чтобы ключ (строка) был другим именем столбца и значение (object) - это значение столбца.
помогает ли CSVHelper делать это во время выполнения. Я просмотрел документацию. Не смог найти ничего, что работало бы на меня.
2 ответов
Я не думаю, что написание словаря поддерживается в настоящее время. Во-первых, CsvHelper было бы трудно узнать, какие заголовки писать. К счастью, не слишком сложно использовать CsvWriter вручную, записывая поле за раз. Если предположить, что каждый работник имеет одинаковые ключи в customerField
затем ваш код может выглядеть примерно так.
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();
}
этот код непроверен, но должен приблизить вас к нужному поведению. Если customerField
ключи словаря не согласованы в списке, тогда код будет немного сложнее, но он все еще разрешим.
словарь не поддерживается, но поддерживается ExpandoObject.
если вы перейдете по первой ссылке выше, вы найдете метод WriteDynamicHeader в использовать на линиях 50 & 57.
С помощью метода расширения я создаю ExpandoObject для каждой записи и использую CsvHelper для записи этого объекта.The это то, из чего я хочу создать запись CSV.
public static class DictionaryCsvExtentions
{
public static dynamic BuildCsvObject(this Dictionary<string, object> document)
{
dynamic csvObj = new ExpandoObject();
foreach (var p in document)
{
AddProperty(csvObj, p.Key, p.Value);
}
return csvObj;
}
private static void AddProperty(ExpandoObject expando, string propertyName, object propertyValue)
{
var expandoDict = expando as IDictionary<string, object>;
if (expandoDict.ContainsKey(propertyName))
{
expandoDict[propertyName] = propertyValue;
}
else
{
expandoDict.Add(propertyName, propertyValue);
}
}
}
теперь я могу создать ExpandoObject из моего словаря, как это
var csvObj = myDictonary.BuildCsvObject();
и с этим, после тестов Джоша в ссылке выше, у нас есть все, что нам нужно, чтобы использовать словарь довольно легко с CsvHelper. Я не думаю ... это лучшее решение для Майкла, просто другой подход.
должное основных ExpandoObject из кода словарь от Здесь (там есть много объяснений!) https://www.oreilly.com/learning/building-c-objects-dynamically