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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 16:45:10