如何用Ruby对比两个Excel文件并生成含匹配与不匹配项的第三个文件
解决Ruby对比XLSX文件并保留不匹配项的问题
原代码的核心问题是嵌套循环遍历两个Sheet的所有行,导致Sheet1的每一行会和Sheet2的每一行逐一对比,每次不匹配都会触发else分支重复写入同一行,最终超出Excel行数限制。
正确实现思路
- 先将Sheet2的
URL与Type构建成哈希表(键为URL,值为Type),实现O(1)时间复杂度的快速查找 - 遍历Sheet1的每一行,直接通过哈希表查找对应URL的Type,不存在则设为
nil - 每个Sheet1的行仅处理一次,避免重复写入
修正后的代码
require 'simple_xlsx_reader' require 'write_xlsx' # 初始化结果文件,修正原代码变量名错误 workbook = WriteXLSX.new('sheet3.xlsx') worksheet = workbook.add_worksheet current_row = 0 # 写入结果表头 worksheet.write(current_row, 0, "ID") worksheet.write(current_row, 1, "URL") worksheet.write(current_row, 2, "Type") current_row += 1 # 读取Sheet2数据,构建URL到Type的哈希映射 sheet2_url_map = {} sheet2 = SimpleXlsxReader.open("sheet2.xlsx") sheet2.sheets.first.rows.each(headers: true) do |row| url = row["URL"] # 仅存储非空URL的映射,避免无效数据 sheet2_url_map[url] = row["Type"] unless url.nil? end sheet2.close # 遍历Sheet1数据,匹配并写入结果 sheet1 = SimpleXlsxReader.open("sheet1.xlsx") sheet1.sheets.first.rows.each(headers: true) do |row| id = row["ID"] url = row["URL"] # 从哈希表获取对应Type,无匹配则为nil type = sheet2_url_map[url] # 写入当前行数据,每行仅处理一次 worksheet.write(current_row, 0, id) worksheet.write(current_row, 1, url) worksheet.write(current_row, 2, type) current_row += 1 end sheet1.close # 必须关闭工作簿,确保数据完整写入文件 workbook.close
代码关键点说明
- 哈希映射优化:提前处理Sheet2数据,后续查找无需重复遍历,既提升效率又避免重复写入
- 避免行数超限:每个Sheet1的行仅写入一次结果,彻底解决重复写入导致的行数溢出问题
- 资源管理:添加
workbook.close确保结果文件正确生成,修正原代码变量名错误 - 鲁棒性处理:忽略Sheet2中的空URL,避免无效映射干扰匹配逻辑
内容的提问来源于stack exchange,提问作者calyxofheld
相关产品推荐
相关产品推荐

