C#将JSON数组值合并为CSV单列导出 基于ChoETL及其他方案
解决方案
方案1:基于现有ChoETL库修改实现
你之前的代码问题是没有将读取到的recipients数组显式转换为拼接字符串,ChoETL默认会把数组字段拆分为多列输出。修改后的代码如下:
using (var csv = new ChoCSVWriter(".\\temp\\csvoutput.csv") .WithFirstLineHeader() .QuoteAllFields()) // 确保所有字段都加双引号,匹配目标输出格式 { using (var json = new ChoJSONReader(".\\temp\\tmpjson.json") .WithField("id") .WithField("name") .WithField("activeFlag") // 直接读取identityName数组,用事件转换器拼接为分号分隔字符串 .WithField("identityName", jsonPath: "$.recipients[*].identityName", isArray: true) .Configure(c => c.BeforeRecordFieldLoad += (o, e) => { if (e.Field.Name == "identityName" && e.Value is IEnumerable<string> idens) { e.Value = string.Join(";", idens); } })) { csv.Write(json); } }
方案2:使用System.Text.Json + CsvHelper实现(可控性更高)
如果不想依赖ChoETL的特殊配置规则,可以用.NET官方的JSON库加通用的CsvHelper库实现,逻辑更清晰易维护:
- 先安装依赖NuGet包:
CsvHelper(System.Text.Json在.NET Core 3.0+版本默认自带,无需额外安装) - 实现代码:
using System.Text.Json; using CsvHelper; using System.Globalization; using System.IO; // 定义JSON对应实体类 public class Recipient { public int id { get; set; } public string identityName { get; set; } public string fullName { get; set; } } public class RootObject { public int id { get; set; } public string name { get; set; } public bool activeFlag { get; set; } public List<Recipient> recipients { get; set; } // 预定义拼接好的identityName字段 public string identityName => string.Join(";", recipients.Select(r => r.identityName)); } // 主转换逻辑 var jsonContent = File.ReadAllText(".\\temp\\tmpjson.json"); var data = JsonSerializer.Deserialize<RootObject>(jsonContent); using var writer = new StreamWriter(".\\temp\\csvoutput.csv"); using var csv = new CsvWriter(writer, CultureInfo.InvariantCulture); csv.Configuration.ShouldQuote = (field, context) => true; // 强制所有字段加双引号 csv.WriteHeader<RootObject>(); csv.NextRecord(); // 输出指定字段,忽略原生的recipients数组字段 csv.WriteRecord(new { data.id, data.name, data.activeFlag, data.identityName });
两种方案都可以输出符合要求的CSV格式。
内容的提问来源于stack exchange,提问作者MarioP
相关产品推荐
相关产品推荐

