你是不是也经常遇到这种烦心事打开一个 Excel 表格里面乱七八糟一大堆光重复的数据就占了一半无论是做数据清洗、出报表还是搞分析去重几乎是逃不掉的“必修课”。今天咱就聊聊怎么用Free Spire.XLS for .NET这个免费组件不用装 Office 几行 C# 代码就把重复行安排得明明白白。实现思路先理清楚核心逻辑弄懂原理再写代码会更轻松选好关键列——比如按 A 列的值判断是否重复。遍历数据把相同值的行归到一组。每组里只留第一行索引最小的其他的统统记下来。从后往前删掉这些“多余”的行避免删着删着索引乱套。简单说分组→保留第一个→删后面的。准备工作打开你的项目在 NuGet 里搜一下FreeSpire.XLS这个包并安装或直接使用Install-Package FreeSpire.XLS这款免费组件足以应对绝大多数中小型项目的数据处理需求。分步代码解析下面咱们一步步拆解代码边写边理解。假设本地有一份 Test.xlsx 文件A 列存在大量重复数据我们要保留首次出现的行删掉后续所有重复行。1. 加载文件拿到工作表usingSpire.Xls;usingSystem.Linq;WorkbookworkbooknewWorkbook();workbook.LoadFromFile(Test.xlsx);Worksheetsheetworkbook.Worksheets[0];2. 确定数据范围用sheet.LastRow拿到最后有数据的行构造一个从 A1 到 A 列末尾的范围。如果你想跳过表头把A1改成A2就行。varrangesheet.Range[$A1:A{sheet.LastRow}];3. 找出需要删除的重复行号用 LINQ 极简实现分组筛选省去手写循环的繁琐。这里特意提一句优先用DisplayedText它能拿到单元格最终展示效果适配格式、公式计算值比单纯取Value靠谱得多能避免很多莫名的判重错误。varduplicatedRowsrange.Rows.GroupBy(rowrow.Columns[0].DisplayedText)// 按 A 列显示的内容分组.Where(groupgroup.Count()1)// 只要有重复的分组.SelectMany(groupgroup.Skip(1))// 跳过每组第一个剩下的就是要删的.Select(rowrow.Columns[0].Row)// 取出这些行的行号.ToList();简单梳理下这段代码的逻辑按单元格内容分组后只保留有重复的组每组跳过第一条剩下的就是我们要删掉的行。4. 删除重复行直接按行号正着删后面的行号会变容易删错。所以咱们从后往前删或者动态调整索引。下面两种写法都可以方式一倒序删推荐易懂foreach(introwNuminduplicatedRows.OrderByDescending(rr)){sheet.DeleteRow(rowNum);}方式二循环里减 ifor(inti0;iduplicatedRows.Count;i){sheet.DeleteRow(duplicatedRows[i]-i);}5. 保存结果处理完成后直接导出新文件还能自由指定 Excel 版本格式workbook.SaveToFile(RemoveDuplicateRows.xlsx);完整代码示例整合所有步骤直接复制到控制台项目就能运行测试usingSpire.Xls;usingSystem.Linq;namespaceRemoveDuplicateRows{classProgram{staticvoidMain(string[]args){WorkbookworkbooknewWorkbook();workbook.LoadFromFile(Test.xlsx);Worksheetsheetworkbook.Worksheets[0];varrangesheet.Range[$A1:A{sheet.LastRow}];varduplicatedRowsrange.Rows.GroupBy(xx.Columns[0].DisplayedText).Where(xx.Count()1).SelectMany(xx.Skip(1)).Select(xx.Columns[0].Row).ToList();// 从后往前删稳稳的foreach(introwNuminduplicatedRows.OrderByDescending(rr)){sheet.DeleteRow(rowNum);}workbook.SaveToFile(RemoveDuplicateRows.xlsx);}}}几个你可能关心的小细节想按多列判断重复改一下 GroupBy 就行比如 A 列和 B 列都相同才算重复.GroupBy(rownew{Col1row.Columns[0].DisplayedText,Col2row.Columns[1].DisplayedText})第一行是表头不想删它那就从 A2 开始取范围varrangesheet.Range[$A2:A{sheet.LastRow}];别忘了释放资源Workbook实例使用完后建议手动释放资源或者用using语句包裹避免程序长时间运行造成内存堆积。using(WorkbookworkbooknewWorkbook()){// 你的代码}整体看下来这套方案上手简单、适配性强既能满足单列、多列去重也能适配带表头的业务表格。把这段代码稍作封装就能直接用到日常数据自动化、后台报表生成等场景里省去大量手动处理表格的重复工作。