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

如何在C#中合并列不同的CSV文件?

用C#合并列结构不一致的CSV文件

实现思路

  • 先遍历所有目标CSV文件,收集所有出现过的列名,生成包含所有列的完整列头集合
  • 逐个读取每个CSV的内容,将每行数据映射到完整列头中,缺失的列填充空字符串
  • 将完整列头和所有映射后的行写入到目标Master.csv文件

C# 实现代码

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

class CsvMerger
{
    static void Main(string[] args)
    {
        // 要合并的CSV文件路径列表,可根据实际情况修改
        string[] csvFiles = { "1.csv", "2.csv" };
        string outputFile = "Master.csv";
        
        HashSet<string> allColumns = new HashSet<string>();
        List<List<string>> allMappedRows = new List<List<string>>();
        
        // 第一步:收集所有唯一列名
        foreach (string filePath in csvFiles)
        {
            using (var reader = new StreamReader(filePath))
            {
                string header = reader.ReadLine();
                if (!string.IsNullOrEmpty(header))
                {
                    foreach (string col in header.Split(',').Select(c => c.Trim()))
                    {
                        allColumns.Add(col);
                    }
                }
            }
        }
        
        // 生成有序的最终列头(保留列的首次出现顺序)
        List<string> finalColumnHeaders = new List<string>();
        foreach (string filePath in csvFiles)
        {
            using (var reader = new StreamReader(filePath))
            {
                string header = reader.ReadLine();
                if (!string.IsNullOrEmpty(header))
                {
                    foreach (string col in header.Split(',').Select(c => c.Trim()))
                    {
                        if (!finalColumnHeaders.Contains(col))
                        {
                            finalColumnHeaders.Add(col);
                        }
                    }
                }
            }
        }
        // 补充未被加入的列(处理后续文件中首次出现的列)
        foreach (string col in allColumns)
        {
            if (!finalColumnHeaders.Contains(col))
            {
                finalColumnHeaders.Add(col);
            }
        }
        
        // 第二步:读取每个CSV的行,映射到最终列结构
        foreach (string filePath in csvFiles)
        {
            using (var reader = new StreamReader(filePath))
            {
                string header = reader.ReadLine();
                if (string.IsNullOrEmpty(header))
                    continue;
                
                string[] fileColumns = header.Split(',').Select(c => c.Trim()).ToArray();
                var columnIndexMap = fileColumns.Select((col, idx) => new { Column = col, Index = idx })
                                                .ToDictionary(x => x.Column, x => x.Index);
                
                string line;
                while ((line = reader.ReadLine()) != null)
                {
                    if (string.IsNullOrWhiteSpace(line))
                        continue;
                    
                    string[] rowValues = line.Split(',');
                    List<string> mappedRow = new List<string>();
                    
                    foreach (string finalCol in finalColumnHeaders)
                    {
                        if (columnIndexMap.TryGetValue(finalCol, out int idx))
                        {
                            mappedRow.Add(idx < rowValues.Length ? rowValues[idx].Trim() : string.Empty);
                        }
                        else
                        {
                            mappedRow.Add(string.Empty);
                        }
                    }
                    
                    allMappedRows.Add(mappedRow);
                }
            }
        }
        
        // 第三步:写入合并后的CSV文件
        using (var writer = new StreamWriter(outputFile))
        {
            // 写入列头
            writer.WriteLine(string.Join(",", finalColumnHeaders));
            
            // 写入所有行,用双引号包裹字段避免逗号干扰
            foreach (var row in allMappedRows)
            {
                writer.WriteLine(string.Join(",", row.Select(val => $"\"{val}\"")));
            }
        }
        
        Console.WriteLine($"合并完成,已生成文件:{outputFile}");
    }
}

注意事项

  • 代码默认使用逗号作为CSV分隔符,若你的CSV使用其他分隔符(如制表符\t),需将所有Split(',')替换为Split('\t')
  • 代码中用双引号包裹每个字段,可避免字段内容包含逗号时导致的格式错误
  • 若CSV文件存在编码问题,可在StreamReader和StreamWriter中指定编码,例如new StreamReader(filePath, Encoding.UTF8)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 21:46:17