如何在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
相关产品推荐
相关产品推荐

