标头数量不固定时,使用CsvHelper创建CSV文件

时间:2019-07-16 19:39:24

标签: c# .net .net-core csvhelper

我有json对象列表。每个json对象具有共同的属性和该json对象唯一的一些属性。像下面的示例

post_id

我想使用CsvHelper创建CSV报告,其中每个属性都是标题。如果该属性不存在,则该列的值应为空

这是我目前的实现方式,它当然不考虑额外的属性

{"FirstName":"foo","LastName":"bar"}
{"FirstName":"jhon","LastName":"dow"}
{"FirstName":"james","LastName":"smith","Age":26}
{"LastName":"jones","Age":30, "Address":"1234 Test Drive"}

因此在上面的示例中,结果csv应该具有4个标头 var records = new List<dynamic>(); foreach (var jObj in result) { var record = new ExpandoObject(); foreach (var property in jObj) { record.TryAdd(property.Key, property.Value.ToString()); } records.Add(record); } using (var writer = new StreamWriter(filePath)) { using (var csv = new CsvWriter(writer)) { csv.WriteRecords(records); } } FirstNameLastNameAge

请注意,记录数可能为数千

更新1
以下是我的临时解决方案,直到我找到了更好的方法来避免重复两次

Address

1 个答案:

答案 0 :(得分:0)

如果不必通过处理实时流处理结果,则在与流写入相同的循环内创建和维护标头集和标头列表可能更有效,而跳过标头-首先写入流。然后,您可以构建一个新的流,编写标题,然后只需将原始流复制到其中即可。

是否可以将内存流用于中间写入取决于您的内存要求。

每个请求的伪代码。这实际上只是对现有代码的一小部分重新排列。它需要较少的循环,但需要更多的内存或磁盘。问题的性质需要权衡。

Stream intermediate_stream // memory or file
List headers // only add a set if List is a bottleneck (1000s of properties); list required to maintain ordering
foreach ( obj in list ) :
  foreach ( prop_name in obj.props )
    headers.add_if_unique(prop_name)
  foreach ( name in headers ) // to preserve ordering in output
   intermediate_stream.write(obj.prop_value(name))

Stream final_stream
final_stream.write(headers)
intermediate_stream.copy_to(final_stream)