Excel 文件比对神器:让数据对比变得像游戏一样有趣!
办公工具
有时候你需要比较两个 Excel 文件的内容,这就像是在大海捞针!然而,今天我要向大家介绍一个 Python 工具,它可以让 Excel 文件的比对变得像游戏一样简单、愉快。是的,我不是在开玩笑,这真的有可能!
走进代码的世界:打怪升级的历程
想象一下,你需要在两个庞大的 Excel 文件中找出不同。这个过程就像是《魔兽世界》里的打怪升级,一不小心就会陷入数据的泥潭。然而,今天的主角——我们的 Excel 文件比对工具,将带你一路平趟,一键搞定数据对比,轻松胜任数据海洋中的数据侦探!
1. 准备舞台:让文件比对更简单
在每一个冒险游戏中,角色准备是关键。在我们的比对工具中,第一步就是准备好两个 Excel 文件。点击“选择原始数据文件”和“选择比对数据文件”按钮,你就能轻松加载你要比对的两个文件。
def select_original_file():
global original_file_path
original_file_path = filedialog.askopenfilename(filetypes=[("Excel文件", "*.xlsx *.xls")])
result_text.insert(tk.END, f"原始数据文件: {original_file_path}\n")
def select_comparison_file():
global comparison_file_path
comparison_file_path = filedialog.askopenfilename(filetypes=[("Excel文件", "*.xlsx *.xls")])
result_text.insert(tk.END, f"比对数据文件: {comparison_file_path}\n")
这些按钮就像是你手中的魔法杖,指向哪里,数据就跟随到哪里!
2. 一键启动:比对结果瞬间呈现
按下“开始比对”按钮,工具就会自动在两个 Excel 文件中进行逐行逐列的比对,并把结果显示出来。差异项会被自动标记成黄色,像是被施了荧光魔法一样,显眼得不能再显眼!
def start_comparison():
if not original_file_path or not comparison_file_path:
messagebox.showwarning("警告", "请先选择原始数据和比对数据文件。")
return
if not output_excel_dir:
messagebox.showwarning("警告", "请选择输出文件夹。")
return
differences = compare_excel_sheets(original_file_path, comparison_file_path, output_excel_dir, output_report_path)
result_text.delete(1.0, tk.END)
result_text.insert(tk.END, "比对结果:\n")
if differences:
for difference in differences:
result_text.insert(tk.END, difference + "\n\n")
else:
result_text.insert(tk.END, "两个文件完全相同。\n")
这个功能有多强大?就像是拥有了一个不会疲倦、不会出错的数据魔法师,帮你在繁杂的数据中迅速找到所有不同。
3. 特定单元格比对:精准锁定目标
你是个追求细节的玩家?工具也为你准备了“查找特定单元格”功能。只需输入表名、行号和列号,工具就能为你精确找到该单元格在两个文件中的差异!
def search_specific_cell():
if not original_file_path or not comparison_file_path:
messagebox.showwarning("警告", "请先选择原始数据和比对数据文件。")
return
sheet_name = sheet_entry.get()
row = int(row_entry.get())
col = int(col_entry.get())
result_msg = specific_cell_comparison(original_file_path, comparison_file_path, sheet_name, row, col)
result_text.delete(1.0, tk.END)
result_text.insert(tk.END, result_msg + "\n")
这个功能就像是你手中的狙击枪,锁定目标,精准击中。再也不用担心在海量数据中迷失方向!
4. 列间比对:谁更出色一目了然
列间比对功能让你可以在同一表格中,直接比较两列的内容。这个功能简直就是为那些追求极致精准的玩家量身定制的,让你迅速找到表格中的每一个不同。
def compare_columns_in_sheet(file, sheet_name, col1_name, col2_name):
wb = load_workbook(file, data_only=False)
if sheet_name in wb.sheetnames:
sheet = wb[sheet_name]
# 获取标题行(假设标题在第一行)
header = [cell.value for cell in sheet[1]]
try:
col1_idx = header.index(col1_name) + 1 # 找到列的索引(从1开始)
col2_idx = header.index(col2_name) + 1
except ValueError:
return f"在工作表 '{sheet_name}' 中找不到列 '{col1_name}' 或 '{col2_name}'。"
col1_cells = [sheet.cell(row=row, column=col1_idx).value for row in range(2, sheet.max_row + 1)]
col2_cells = [sheet.cell(row=row, column=col2_idx).value for row in range(2, sheet.max_row + 1)]
differences = []
for row, (val1, val2) in enumerate(zip(col1_cells, col2_cells), start=2): # 从第2行开始
if val1 != val2:
diff_msg = f"工作表 '{sheet_name}' 的第 {row} 行, 列 '{col1_name}' 和 列 '{col2_name}' 存在差异: 值1='{val1}', 值2='{val2}'\n"
differences.append(diff_msg)
if not differences:
return f"工作表 '{sheet_name}' 的列 '{col1_name}' 和 列 '{col2_name}' 完全一致。"
else:
return "\n".join(differences)
else:
return f"工作表 '{sheet_name}' 不存在。"
整个项目完整代码如下:
import tkinter as tk
from tkinter import filedialog, messagebox
from openpyxl import load_workbook
from openpyxl.styles import PatternFill
import os
import docx
def compare_excel_sheets(file1, file2, output_excel_dir=None, output_report=None):
wb1 = load_workbook(file1, data_only=False)
wb2 = load_workbook(file2, data_only=False)
differences = []
fill = PatternFill(start_color="FFFF00", end_color="FFFF00", fill_type="solid")
output_file1 = os.path.join(output_excel_dir, f"标记_{os.path.basename(file1)}")
output_file2 = os.path.join(output_excel_dir, f"标记_{os.path.basename(file2)}")
for sheet_name in wb1.sheetnames:
if sheet_name in wb2.sheetnames:
sheet1 = wb1[sheet_name]
sheet2 = wb2[sheet_name]
max_row = max(sheet1.max_row, sheet2.max_row)
max_column = max(sheet1.max_column, sheet2.max_column)
for row in range(1, max_row + 1):
for col in range(1, max_column + 1):
cell1 = sheet1.cell(row=row, column=col)
cell2 = sheet2.cell(row=row, column=col)
val1 = cell1.value
val2 = cell2.value
formula1 = cell1.data_type == 'f'
formula2 = cell2.data_type == 'f'
if val1 != val2 or formula1 != formula2:
type1 = "公式" if formula1 else "数值"
type2 = "公式" if formula2 else "数值"
diff_msg = f"工作表 '{sheet_name}' 的第 {row} 行,第 {col} 列存在差异:\n"
diff_msg += f"原始数据: 类型='{type1}', 值='{val1}'\n"
diff_msg += f"比对数据: 类型='{type2}', 值='{val2}'\n"
if type1 != type2:
diff_msg += "(注意:一个是公式,另一个是数值)\n"
elif formula1 and formula2 and val1 != val2:
diff_msg += "(公式不同)\n"
elif not formula1 and not formula2 and val1 != val2:
diff_msg += "(数值不同)\n"
differences.append(diff_msg)
# 标记不同的单元格
cell1.fill = fill
cell2.fill = fill
else:
differences.append(f"工作表 '{sheet_name}' 在两个文件中不一致。")
# 保存标记后的Excel文件
wb1.save(output_file1)
wb2.save(output_file2)
# 生成报告并保存到Word文档
if output_report:
generate_report(differences, output_report)
return differences
def generate_report(differences, output_report):
doc = docx.Document()
doc.add_heading('Excel 文件比较报告', 0)
for diff in differences:
doc.add_paragraph(diff)
doc.save(output_report)
def specific_cell_comparison(file1, file2, sheet_name, row, col):
wb1 = load_workbook(file1, data_only=False)
wb2 = load_workbook(file2, data_only=False)
if sheet_name in wb1.sheetnames and sheet_name in wb2.sheetnames:
sheet1 = wb1[sheet_name]
sheet2 = wb2[sheet_name]
cell1 = sheet1.cell(row=row, column=col)
cell2 = sheet2.cell(row=row, column=col)
val1 = cell1.value
val2 = cell2.value
formula1 = cell1.data_type == 'f'
formula2 = cell2.data_type == 'f'
type1 = "公式" if formula1 else "数值"
type2 = "公式" if formula2 else "数值"
result_msg = f"工作表 '{sheet_name}' 的第 {row} 行,第 {col} 列比对结果:\n"
result_msg += f"原始数据: 类型='{type1}', 值='{val1}'\n"
result_msg += f"比对数据: 类型='{type2}', 值='{val2}'\n"
if type1 != type2:
result_msg += "(注意:一个是公式,另一个是数值)\n"
elif formula1 and formula2 and val1 != val2:
result_msg += "(公式不同)\n"
elif not formula1 and not formula2 and val1 != val2:
result_msg += "(数值不同)\n"
else:
result_msg += "(两者相同)\n"
return result_msg
else:
return f"工作表 '{sheet_name}' 在两个文件中不一致。"
def compare_columns_in_sheet(file, sheet_name, col1_name, col2_name):
wb = load_workbook(file, data_only=False)
if sheet_name in wb.sheetnames:
sheet = wb[sheet_name]
# 获取标题行(假设标题在第一行)
header = [cell.value for cell in sheet[1]]
try:
col1_idx = header.index(col1_name) + 1 # 找到列的索引(从1开始)
col2_idx = header.index(col2_name) + 1
except ValueError:
return f"在工作表 '{sheet_name}' 中找不到列 '{col1_name}' 或 '{col2_name}'。"
col1_cells = [sheet.cell(row=row, column=col1_idx).value for row in range(2, sheet.max_row + 1)]
col2_cells = [sheet.cell(row=row, column=col2_idx).value for row in range(2, sheet.max_row + 1)]
differences = []
for row, (val1, val2) in enumerate(zip(col1_cells, col2_cells), start=2): # 从第2行开始
if val1 != val2:
diff_msg = f"工作表 '{sheet_name}' 的第 {row} 行, 列 '{col1_name}' 和 列 '{col2_name}' 存在差异: 值1='{val1}', 值2='{val2}'\n"
differences.append(diff_msg)
if not differences:
return f"工作表 '{sheet_name}' 的列 '{col1_name}' 和 列 '{col2_name}' 完全一致。"
else:
return "\n".join(differences)
else:
return f"工作表 '{sheet_name}' 不存在。"
def select_original_file():
global original_file_path
original_file_path = filedialog.askopenfilename(filetypes=[("Excel文件", "*.xlsx *.xls")])
result_text.insert(tk.END, f"原始数据文件: {original_file_path}\n")
def select_comparison_file():
global comparison_file_path
comparison_file_path = filedialog.askopenfilename(filetypes=[("Excel文件", "*.xlsx *.xls")])
result_text.insert(tk.END, f"比对数据文件: {comparison_file_path}\n")
def select_output_directory():
global output_excel_dir
output_excel_dir = filedialog.askdirectory()
result_text.insert(tk.END, f"输出文件夹: {output_excel_dir}\n")
def select_output_report_file():
global output_report_path
output_report_path = filedialog.asksaveasfilename(defaultextension=".docx", filetypes=[("Word文档", "*.docx")])
result_text.insert(tk.END, f"输出报告文件: {output_report_path}\n")
def start_comparison():
if not original_file_path or not comparison_file_path:
messagebox.showwarning("警告", "请先选择原始数据和比对数据文件。")
return
if not output_excel_dir:
messagebox.showwarning("警告", "请选择输出文件夹。")
return
differences = compare_excel_sheets(original_file_path, comparison_file_path, output_excel_dir, output_report_path)
result_text.delete(1.0, tk.END)
result_text.insert(tk.END, "比对结果:\n")
if differences:
for difference in differences:
result_text.insert(tk.END, difference + "\n\n")
else:
result_text.insert(tk.END, "两个文件完全相同。\n")
def search_specific_cell():
if not original_file_path or not comparison_file_path:
messagebox.showwarning("警告", "请先选择原始数据和比对数据文件。")
return
sheet_name = sheet_entry.get()
row = int(row_entry.get())
col = int(col_entry.get())
result_msg = specific_cell_comparison(original_file_path, comparison_file_path, sheet_name, row, col)
result_text.delete(1.0, tk.END)
result_text.insert(tk.END, result_msg + "\n")
def compare_columns():
if not original_file_path:
messagebox.showwarning("警告", "请先选择原始数据文件。")
return
sheet_name = sheet_entry_col.get()
col1 = col1_entry.get()
col2 = col2_entry.get()
result_msg = compare_columns_in_sheet(original_file_path, sheet_name, col1, col2)
result_text.delete(1.0, tk.END)
result_text.insert(tk.END, result_msg + "\n")
def select_uploaded_file():
global uploaded_file_path
uploaded_file_path = filedialog.askopenfilename(filetypes=[("Excel文件", "*.xlsx *.xls")])
result_text.insert(tk.END, f"已选择数据文件: {uploaded_file_path}\n")
def compare_uploaded_columns():
if not uploaded_file_path:
messagebox.showwarning("警告", "请先选择数据文件。")
return
sheet_name = sheet_entry_col.get()
col1 = col1_entry.get()
col2 = col2_entry.get()
result_msg = compare_columns_in_sheet(uploaded_file_path, sheet_name, col1, col2)
result_text.delete(1.0, tk.END)
result_text.insert(tk.END, result_msg + "\n")
# 创建主窗口
root = tk.Tk()
root.title("Excel文件比对工具")
# 初始化全局变量
original_file_path = None
comparison_file_path = None
output_excel_dir = None
output_report_path = None
uploaded_file_path = None
# 上传文件选择部分
upload_frame = tk.LabelFrame(root, text="上传文件")
upload_frame.pack(pady=10, padx=10, fill="x")
# 文件选择按钮部分
file_select_frame = tk.LabelFrame(root, text="选择文件和输出选项")
file_select_frame.pack(pady=10, padx=10, fill="x")
original_button = tk.Button(file_select_frame, text="选择原始数据文件", command=select_original_file)
original_button.grid(row=0, column=0, padx=5, pady=5, sticky="ew")
comparison_button = tk.Button(file_select_frame, text="选择比对数据文件", command=select_comparison_file)
comparison_button.grid(row=0, column=1, padx=5, pady=5, sticky="ew")
output_excel_button = tk.Button(file_select_frame, text="选择输出文件夹", command=select_output_directory)
output_excel_button.grid(row=0, column=2, padx=5, pady=5, sticky="ew")
output_report_button = tk.Button(file_select_frame, text="选择输出报告文件", command=select_output_report_file)
output_report_button.grid(row=0, column=3, padx=5, pady=5, sticky="ew")
# 比对按钮
compare_button = tk.Button(root, text="开始比对", command=start_comparison)
compare_button.pack(pady=10)
# 查找特定单元格部分
specific_cell_frame = tk.LabelFrame(root, text="查找特定单元格")
specific_cell_frame.pack(pady=10, padx=10, fill="x")
sheet_label = tk.Label(specific_cell_frame, text="工作表名称:")
sheet_label.grid(row=0, column=0, padx=5, pady=5)
sheet_entry = tk.Entry(specific_cell_frame)
sheet_entry.grid(row=0, column=1, padx=5, pady=5)
row_label = tk.Label(specific_cell_frame, text="行号:")
row_label.grid(row=1, column=0, padx=5, pady=5)
row_entry = tk.Entry(specific_cell_frame)
row_entry.grid(row=1, column=1, padx=5, pady=5)
col_label = tk.Label(specific_cell_frame, text="列号:")
col_label.grid(row=2, column=0, padx=5, pady=5)
col_entry = tk.Entry(specific_cell_frame)
col_entry.grid(row=2, column=1, padx=5, pady=5)
search_button = tk.Button(specific_cell_frame, text="查找特定单元格", command=search_specific_cell)
search_button.grid(row=3, column=0, columnspan=2, pady=10)
upload_button = tk.Button(upload_frame, text="上传需要比对的数据文件", command=select_uploaded_file)
upload_button.pack(pady=5, padx=10)
# 比对同一表格中的两列
compare_col_frame = tk.LabelFrame(root, text="比对表格中的两列")
compare_col_frame.pack(pady=10, padx=10, fill="x")
sheet_label_col = tk.Label(compare_col_frame, text="工作表名称:")
sheet_label_col.grid(row=0, column=0, padx=5, pady=5)
sheet_entry_col = tk.Entry(compare_col_frame)
sheet_entry_col.grid(row=0, column=1, padx=5, pady=5)
col1_label = tk.Label(compare_col_frame, text="列1名称:")
col1_label.grid(row=1, column=0, padx=5, pady=5)
col1_entry = tk.Entry(compare_col_frame)
col1_entry.grid(row=1, column=1, padx=5, pady=5)
col2_label = tk.Label(compare_col_frame, text="列2名称:")
col2_label.grid(row=2, column=0, padx=5, pady=5)
col2_entry = tk.Entry(compare_col_frame)
col2_entry.grid(row=2, column=1, padx=5, pady=5)
compare_cols_button = tk.Button(compare_col_frame, text="比对两列", command=compare_uploaded_columns)
compare_cols_button.grid(row=3, column=0, columnspan=2, pady=10)
# 结果显示部分
result_text = tk.Text(root, wrap='word', height=20, width=100)
result_text.pack(pady=10, padx=10)
# 运行主循环
root.mainloop()
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)