C# WPF如何比对两个CSV文件并将不匹配行输出为新CSV文件
实现思路
首先你需要在窗口类的顶部提前声明全局变量存储文件内容,你现有代码应该已经定义了对应变量,没加的话补上即可:
// 放在窗口类内部、所有方法外面 private string path = string.Empty; private string mainFile = string.Empty; private string compareFile = string.Empty;
Compare按钮的实现逻辑分四步走:
步骤1:前置校验
- 判断compareFile是否为空,为空就提示用户先上传待比对文件
- 把两个CSV的文本按换行符拆成独立行,同时跳过空行避免报错
- 校验两个文件的表头是否一致,不一致的话无法正常比对,直接弹提示终止流程
步骤2:构建mainFile的快速查询结构
用id作为唯一键,把mainFile除表头外的所有行存在字典里,比对时不需要每次遍历整个mainFile,效率更高
步骤3:遍历比对行
遍历compareFile除表头的每一行:
- 拆分当前行拿到id值
- 去mainFile的字典中查询该id:
- 没查到:说明该id是compareFile独有的,属于不匹配行
- 查到了但整行内容和compareFile当前行不一致:说明同id下字段内容有差异,属于不匹配行
- 把所有不匹配的行存入单独的列表
步骤4:导出差异文件
弹出保存文件对话框让用户选择导出路径,把表头+所有不匹配的行写入新的CSV文件即可
完整代码示例
using Microsoft.Win32; // 必须加这个引用,否则文件对话框会报错 private void btnCompare_Click(object sender, RoutedEventArgs e) { // 校验是否已上传待比对文件 if (string.IsNullOrEmpty(compareFile)) { MessageBox.Show("请先上传待比对的CSV文件"); return; } // 把两个文件内容拆成行数组,自动过滤空行 var mainLines = mainFile.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries).ToList(); var compareLines = compareFile.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries).ToList(); // 校验两个文件表头是否一致 if (mainLines[0] != compareLines[0]) { MessageBox.Show("两个CSV文件的表头不一致,无法比对"); return; } // 构建mainFile的查询字典,key为行id,value为整行内容 Dictionary<string, string> mainDic = new Dictionary<string, string>(); for (int i = 1; i < mainLines.Count; i++) // 跳过表头从第二行开始 { var line = mainLines[i]; var id = line.Split(',')[0]; // 取第一列作为唯一id if (!mainDic.ContainsKey(id)) { mainDic.Add(id, line); } } // 存储不匹配的行,先写入表头 List<string> diffLines = new List<string>(); diffLines.Add(mainLines[0]); // 遍历比对compareFile的所有行 for (int i = 1; i < compareLines.Count; i++) { var currentLine = compareLines[i]; var currentId = currentLine.Split(',')[0]; // id不存在或者内容不一致都判定为不匹配 if (!mainDic.ContainsKey(currentId) || mainDic[currentId] != currentLine) { diffLines.Add(currentLine); } } // 无差异的提示 if (diffLines.Count == 1) { MessageBox.Show("两个文件内容完全一致,没有不匹配的行"); return; } // 导出差异文件 SaveFileDialog saveDialog = new SaveFileDialog(); saveDialog.Filter = "CSV文件(*.csv)|*.csv|所有文件(*.*)|*.*"; saveDialog.FileName = "差异结果.csv"; if (saveDialog.ShowDialog() == true) { File.WriteAllLines(saveDialog.FileName, diffLines); MessageBox.Show($"差异文件已导出,共找到{diffLines.Count - 1}条不匹配行"); } }
注意事项
- 上述代码默认你的CSV单元格内容本身不包含逗号,如果实际场景中单元格有逗号且用引号包裹(比如
10,"Jaime, Jr",Odell,...),需要用专门的CSV解析库处理,避免拆分错误 - 如果需要同时输出mainFile有但compareFile没有的行,只需要再遍历一次mainDic的key,判断compareFile中是否存在该id,不存在就加入差异列表即可
内容的提问来源于stack exchange,提问作者mully
相关产品推荐
相关产品推荐

