使用csvHelper动态创建列

我有一个工作人员,从服务器获取各种字段。 我正在使用CSVHelper包将此类转换为excel表。 工人有像以下字段:

class Worker { string name; string phone; string age; Dictionary customerField; } 

我可以映射姓名,电话,号码等

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

我通过以下方式生成地图:

 csv.Configuration.RegisterClassMap(); 

写下工人名单:

 csv.WriteRecords(workerList); 

如何将customerField字典映射到Excel工作表,以便Key(字符串)是另一个列名,值(object)是列的值。

CSVHelper是否帮助我们在运行时执行此操作。 我查看了文档。 找不到任何对我有用的东西。

我认为目前不支持编写字典。 首先,CsvHelper很难知道要写什么标题。 幸运的是,手动使用CsvWriter并不是太复杂,一次写一个字段。 如果我们假设每个Worker在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字典键在列表中不一致,那么代码会更复杂但仍然可以解决。

不支持Dictionary,但支持ExpandoObject。

https://github.com/JoshClose/CsvHelper/blob/48e70742e06007dae3a635c418b7e3358f667c4f/src/CsvHelper.Tests/Writing/MultipleHeadersTest.cs

https://github.com/JoshClose/CsvHelper/blob/b74a2f95a101158f4cdedd25fae6e8392b58855b/src/CsvHelper.Tests/Writing/DynamicTests.cs

如果您按照上面的第一个链接,您将在第50和57行找到WriteDynamicHeader方法。

借助扩展方法,我为每条记录创建一个ExpandoObject,并使用CsvHelper来编写该Dictionary 。Dictionary Dictionary参数命名document是我希望从中创建CSV记录的。

 public static class DictionaryCsvExtentions { public static dynamic BuildCsvObject(this Dictionary 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; if (expandoDict.ContainsKey(propertyName)) { expandoDict[propertyName] = propertyValue; } else { expandoDict.Add(propertyName, propertyValue); } } } 

现在我可以像这样在我的字典中创建一个ExpandoObject

 var csvObj = myDictonary.BuildCsvObject(); 

在此之后,按照上面链接中的Josh测试,我们需要使用与CsvHelper无缝地使用字典。 我不认为这是迈克尔的更好的解决方案,只是一种不同的方法。

信用到期的信用来自字典代码的基本ExpandoObject来自这里(其中有更多解释!) https://www.oreilly.com/learning/building-c-objects-dynamically