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

使用EPPlus库识别并高亮Excel表重复记录的技术问题

解决整行重复识别、高亮与批注的问题

我明白你的问题所在了——你当前的代码是在检查单个单元格值是否重复,而不是基于多列组合判断整行是否重复,这就是为什么它总是返回true的原因(比如不同行的FirstName可能有相同值,但这并不代表整行是重复记录)。我们来修正这个逻辑,实现你需要的功能:基于指定多列识别重复行,然后对整行应用高亮和批注。

原代码的核心问题

你的代码遍历了所有工作表的所有单元格,只要任何单元格的值在列表中存在就返回true,这完全不符合“整行重复”的判断逻辑。比如两个不同的员工可能有相同的名字,但地址不同,这时候你的代码会误判为重复。

正确的实现思路

要实现基于多列的整行重复判断,我们需要:

  • 先确定用来判断重复的关键列组合(比如FirstName、LastName、Address这三列)
  • 遍历数据行(跳过表头行),把每行的关键列值组合成一个唯一标识
  • 用字典记录这个标识对应的行号,当遇到重复标识时,标记为重复行并处理
  • 对重复行执行高亮整行、添加批注的操作

完整实现代码

下面是基于EPPlus的完整代码,包含重复行识别、高亮和批注功能:

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

public static bool IdentifyAndMarkDuplicateRows(string path)
{
    bool hasDuplicates = false;
    // 设置EPPlus的License(EPPlus 5+需要,若用旧版本可注释)
    ExcelPackage.LicenseContext = LicenseContext.NonCommercial;

    using (ExcelPackage excel = new ExcelPackage(new FileInfo(path)))
    {
        // 定位到EmployeeSheet工作表
        ExcelWorksheet sheet = excel.Workbook.Worksheets["EmployeeSheet"];
        if (sheet == null)
        {
            throw new Exception("未找到EmployeeSheet工作表");
        }

        // 1. 获取关键列的索引(假设第一行是表头)
        var headerRow = sheet.Cells[1, 1, 1, sheet.Dimension.End.Column];
        int firstNameCol = headerRow.First(c => c.Value.ToString().Equals("FirstName", StringComparison.OrdinalIgnoreCase)).Start.Column;
        int lastNameCol = headerRow.First(c => c.Value.ToString().Equals("LastName", StringComparison.OrdinalIgnoreCase)).Start.Column;
        int addressCol = headerRow.First(c => c.Value.ToString().Equals("Address", StringComparison.OrdinalIgnoreCase)).Start.Column;

        // 2. 用字典存储已出现的行标识(关键列组合)和对应的行号
        Dictionary<string, int> seenRows = new Dictionary<string, int>();

        // 3. 遍历数据行(从第2行开始,跳过表头)
        int startRow = 2;
        int endRow = sheet.Dimension.End.Row;
        int endCol = sheet.Dimension.End.Column;

        for (int row = startRow; row <= endRow; row++)
        {
            // 获取当前行的关键列值,处理null情况
            string firstName = sheet.Cells[row, firstNameCol].Value?.ToString() ?? string.Empty;
            string lastName = sheet.Cells[row, lastNameCol].Value?.ToString() ?? string.Empty;
            string address = sheet.Cells[row, addressCol].Value?.ToString() ?? string.Empty;

            // 组合成唯一标识(用特殊字符分隔,避免不同组合产生相同字符串)
            string rowIdentifier = string.Join("|", firstName, lastName, address);

            if (seenRows.ContainsKey(rowIdentifier))
            {
                // 发现重复行,标记状态
                hasDuplicates = true;
                int originalRow = seenRows[rowIdentifier];

                // 高亮当前重复行
                sheet.Cells[row, 1, row, endCol].Style.Fill.PatternType = ExcelFillStyle.Solid;
                sheet.Cells[row, 1, row, endCol].Style.Fill.BackgroundColor.SetColor(System.Drawing.Color.LightPink);

                // 高亮原始重复行(可选)
                sheet.Cells[originalRow, 1, originalRow, endCol].Style.Fill.PatternType = ExcelFillStyle.Solid;
                sheet.Cells[originalRow, 1, originalRow, endCol].Style.Fill.BackgroundColor.SetColor(System.Drawing.Color.LightPink);

                // 给当前重复行添加批注
                ExcelComment comment = sheet.Cells[row, firstNameCol].Comment ?? sheet.Cells[row, firstNameCol].AddComment(string.Empty, "Duplicate Check");
                comment.Text = $"此行为重复记录,原始行位于第{originalRow}行";
                comment.AutoFit = true;
            }
            else
            {
                // 记录新的行标识
                seenRows.Add(rowIdentifier, row);
            }
        }

        // 保存修改
        excel.Save();
    }

    return hasDuplicates;
}

代码关键点说明

  • 关键列定位:通过表头名称动态查找列索引,避免硬编码列号,适配不同的表格结构
  • 行标识生成:用|分隔关键列值,确保不同的列组合不会产生相同的标识(如果你的数据中包含|,可以换成其他特殊字符)
  • 重复处理:不仅标记当前重复行,还可以选择高亮原始重复行,批注中明确指出原始行位置
  • 空值处理:用?? string.Empty把null值转为空字符串,避免组合标识时出现null异常
  • 样式设置:使用EPPlus的Style API设置整行填充色,实现高亮效果

使用注意事项

  1. 确保你的项目已引用EPPlus NuGet包(可以通过NuGet安装:Install-Package EPPlus)
  2. 若使用EPPlus 5及以上版本,需要设置LicenseContext(代码中已包含)
  3. 确保表头行的列名与代码中指定的一致(大小写不敏感)
  4. 如果需要基于更多列判断重复,只需要添加对应的列索引获取和标识组合即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 19:42:37