You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在C#中按Control_Code分组将CSV转换为多份JSON文件

解决方案:C#按Control_Code分组将CSV转换为多份JSON文件

场景与需求

我是C#和JSON新手,需处理如下格式的固定宽度CSV文件:

Time             Control_Code   Metric  Organisation    Value   DateTime

2018-10-21T00:08:03 JKX           3721      AD450          20   2018-10-21T00:08:00
2018-10-21T00:08:03 BHY           1234      HG650          88   2018-10-21T00:08:00

要求:

  • 按Control_Code分组,每个分组生成独立的JSON文件
  • 同Control_Code的指标数据整合到JSON的metrics数组中
  • 目标JSON格式示例(以JKX为例):
{
    "time": "2018-10-21T00:08:03",
    "control_Code": "JKX",
    "metrics": [
        {
            "metric": 3721,
            "organisation": "AD450",
            "value": 20,
            "datetime": "2018-10-21T00:08:00"
        }
    ]
}

(注:若需保留原属性大小写,可调整JSON序列化配置)


实现步骤

1. 安装依赖NuGet包

使用CsvHelper处理固定宽度CSV(比手动解析更稳定),用.NET内置的System.Text.Json做JSON序列化:

  • 打开NuGet包管理器,搜索并安装CsvHelper

2. 定义数据模型

根据CSV结构和目标JSON结构,创建三个类:

// 映射CSV每一行的结构
public class CsvRecord
{
    public string Time { get; set; }
    public string Control_Code { get; set; }
    public int Metric { get; set; }
    public string Organisation { get; set; }
    public int Value { get; set; }
    public string DateTime { get; set; }
}

// 最终输出的JSON根结构
public class ControlCodeJson
{
    public string Time { get; set; }
    public string Control_Code { get; set; }
    public List<MetricItem> metrics { get; set; } = new();
}

// JSON中metrics数组的子项结构
public class MetricItem
{
    public int Metric { get; set; }
    public string Organisation { get; set; }
    public int Value { get; set; }
    // 若需严格匹配示例中的"Datetime"大小写,添加此特性
    [JsonPropertyName("Datetime")]
    public string DateTime { get; set; }
}

3. 配置CSV映射(处理固定宽度)

创建映射类,指定CSV列的索引(适配固定宽度格式):

using CsvHelper.Configuration;

public class CsvRecordMap : ClassMap<CsvRecord>
{
    public CsvRecordMap()
    {
        Map(m => m.Time).Index(0);
        Map(m => m.Control_Code).Index(1);
        Map(m => m.Metric).Index(2);
        Map(m => m.Organisation).Index(3);
        Map(m => m.Value).Index(4);
        Map(m => m.DateTime).Index(5);
    }
}

4. 读取CSV、分组并生成JSON

完整代码示例:

using System.Globalization;
using System.Text.Json;
using CsvHelper;
using System.IO;

class Program
{
    static void Main(string[] args)
    {
        // 替换为你的CSV文件路径
        string csvPath = @"C:\your-path\data.csv";
        List<CsvRecord> csvRecords;

        // 读取CSV文件
        using (var reader = new StreamReader(csvPath))
        using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
        {
            csv.Context.RegisterClassMap<CsvRecordMap>();
            // 跳过空行(如果CSV有多余空行)
            csv.Context.Configuration.IgnoreBlankLines = true;
            csvRecords = csv.GetRecords<CsvRecord>().ToList();
        }

        // 按Control_Code分组
        var groupedData = csvRecords.GroupBy(record => record.Control_Code);

        // JSON序列化配置:格式化输出,可选camelCase
        var jsonOptions = new JsonSerializerOptions
        {
            WriteIndented = true,
            // 若不需要camelCase,注释掉下面一行
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase
        };

        // 遍历分组生成JSON文件
        foreach (var group in groupedData)
        {
            string controlCode = group.Key;
            var jsonModel = new ControlCodeJson
            {
                Time = group.First().Time,
                Control_Code = controlCode,
                metrics = group.Select(record => new MetricItem
                {
                    Metric = record.Metric,
                    Organisation = record.Organisation,
                    Value = record.Value,
                    DateTime = record.DateTime
                }).ToList()
            };

            // 序列化并写入文件,文件名用Control_Code命名
            string jsonString = JsonSerializer.Serialize(jsonModel, jsonOptions);
            string outputPath = $"{controlCode}.json";
            File.WriteAllText(outputPath, jsonString);
        }
    }
}

关键注意点

  • 如果同Control_Code的Time字段不一致,需额外处理(比如取第一条、合并提示或报错),上述代码默认取分组内第一条记录的Time
  • 若CSV是逗号分隔而非固定宽度,只需修改CsvRecordMap为按列名映射,无需指定索引
  • 若使用Newtonsoft.Json替代System.Text.Json,只需替换序列化代码,并将JsonPropertyName改为JsonProperty

内容的提问来源于stack exchange,提问作者Beanymattd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 18:22:14