在日常数据处理中,excel 表格中的重复行是一个常见问题。无论是数据清洗、报表生成还是数据分析,去除重复记录都是一项基础且关键的操作。本文将详细介绍如何使用 free spire.xls for .net(一款免费、无需安装 microsoft office 的 excel 操作组件),通过 c# 代码以编程方式删除 excel 工作表中的重复行。
实现思路
删除重复行的核心逻辑如下:
- 指定关键列:确定用于判断重复的列(例如第一列 a 列)。
- 分组识别:遍历数据区域,根据关键列的值对每一行进行分组。
- 标记重复行:在每个分组中,保留第一次出现的行(索引最小),将其余行的行号记录下来。
- 安全删除:按照行号从大到小的顺序删除这些重复行,避免因删除操作导致的索引错位。
详细步骤解析
1. 安装免费库
在编写代码之前,通过 nuget 安装所需的免费库:
install-package freespire.xls
或者在 visual studio 的“管理 nuget 程序包”中搜索 freespire.xls 并安装。
注意:免费版提供了大部分基础功能,足以应对中小规模数据的处理需求。
2. 加载工作簿和工作表
using spire.xls;
using system.linq;
// 创建 workbook 实例并加载文档
workbook workbook = new workbook();
workbook.loadfromfile("test.xlsx");
// 获取第一个工作表
worksheet sheet = workbook.worksheets[0];
3. 确定数据范围
为了仅对实际存在数据的行进行操作,我们使用工作表的 lastrow 属性获取最后有效行号,并构造一个从 a1 到 a 列最后一行的范围(例如 a1:a100)。实际使用时,可以根据需要调整起始行,例如跳过标题行。
// 假设数据从第1行开始,以 a 列作为判重依据
string rangeaddress = $"a1:a{sheet.lastrow}";
var range = sheet.range[rangeaddress];
4. 找出需要删除的重复行号
利用 linq 对范围内的每一行进行分组。displayedtext 属性返回单元格在 excel 界面上的显示文本(会考虑格式、公式计算结果等),相比直接使用 value 或 text 更为可靠。
var duplicatedrows = range.rows
.groupby(row => row.columns[0].displayedtext) // 按第一列的显示文本分组
.where(group => group.count() > 1) // 只筛选存在重复的分组
.selectmany(group => group.skip(1)) // 跳过每组的第一行(保留行),取其余重复行
.select(row => row.columns[0].row) // 获取这些行的行号
.tolist();
range.rows返回范围内的所有行对象。groupby根据 a 列的显示文本对行进行分组。skip(1)忽略每个分组中的第一行(即保留的那一行)。- 最终得到
list<int>,其中包含所有待删除行的行号(升序排列)。
5. 删除重复行
关键点:如果直接按照升序的行号顺序删除,会导致后续行号发生偏移。正确的做法是从后往前删除,这样可以保证每次删除时行号仍然准确。
// 将行号降序排列,然后逐个删除
foreach (int rownum in duplicatedrows.orderbydescending(r => r))
{
sheet.deleterow(rownum);
}
也可以使用索引修正 法:sheet.deleterow(duplicatedrows[i] - i),两种方法效果相同,但从后往前删除的逻辑更为直观。
6. 保存结果
workbook.savetofile("removeduplicaterows.xlsx", excelversion.version2016);
默认保存为 .xlsx 格式,也可以指定为 .xls 或其他 excel 版本。
完整代码示例
将以上步骤整合为一个完整的控制台应用程序(包含资源释放建议):
using spire.xls;
using system.linq;
namespace removeduplicaterows
{
class program
{
static void main(string[] args)
{
// 使用 using 语句确保资源被正确释放
using (workbook workbook = new workbook())
{
// 加载文档
workbook.loadfromfile("test.xlsx");
// 获取第一个工作表
worksheet sheet = workbook.worksheets[0];
// 定义判重范围(a列,从第1行到最后有效行)
var range = sheet.range[$"a1:a{sheet.lastrow}"];
// 获取需要删除的重复行号
var duplicatedrows = range.rows
.groupby(x => x.columns[0].displayedtext)
.where(x => x.count() > 1)
.selectmany(x => x.skip(1))
.select(x => x.columns[0].row)
.tolist();
// 从后向前删除重复行,避免索引错乱
foreach (int rownum in duplicatedrows.orderbydescending(r => r))
{
sheet.deleterow(rownum);
}
// 保存结果
workbook.savetofile("removeduplicaterows.xlsx");
}
}
}
}
关键点与注意事项
1. 判断重复的依据列
上面的代码仅基于 a 列进行判重。如果需要根据多列组合(例如 a 列和 b 列同时相同才算重复),只需修改 groupby 的键:
.groupby(row => new
{
col1 = row.columns[0].displayedtext,
col2 = row.columns[1].displayedtext
})
2. 保留表头(标题行)
如果第一行是标题行,不应参与重复判断和删除。只需将范围的起始行改为第 2 行:
var range = sheet.range[$"a2:a{sheet.lastrow}"];
同时,lastrow 属性会自动包含最后一行数据,因此标题行不受影响。删除重复行后,表头行将保持不变。
3.displayedtext与value的区别
| 属性 | 说明 | 推荐场景 |
|---|---|---|
displayedtext | 返回单元格在 excel 界面上显示的内容,考虑了数字格式、日期格式、公式等 | 业务上的重复判断(推荐) |
value | 返回原始值(公式计算结果,但可能忽略显示格式) | 需要精确原始值的场景 |
在简单文本情况下两者结果一致,但推荐使用 displayedtext 以避免因格式差异导致的误判。
4. 内存与资源释放
workbook 类实现了 idisposable 接口,强烈建议使用 using 语句或手动调用 dispose() 方法,以避免内存泄漏,尤其是在处理大型文件时。
本文演示了使用 c# 删除 excel 重复行的完整流程,包括加载文件、识别重复行、删除行以及保存结果。该方法灵活可定制,支持单列或多列判重,能够无缝集成到数据清洗的自动化流程中。
到此这篇关于c#代码实现删除excel中的重复行的文章就介绍到这了,更多相关c#删除excel重复行内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论