python处理Excel单机小工具:匹数据,增强版VLookup
2025年9月22日
场景:
如果使用vlookup匹数据的话, 每次只能匹配一列, 并且关联的列只能有一列, 比如有同名同姓的数据, 在匹配时就会出现错误
实现目标:
1. 可以同时使用多列数据进行关联, 比如用 姓名和工号, 同时进行匹配
2. 可以同时匹配多列数据, 比如将匹配上的身份证号, 部门等多列数据一次性追加到前表后边
数据截图:
1. A表

2. B表

3. 追加信息后的表

交互截图:
1. 打开文件

2. 选择待追加信息的表(A表), 以及关联用的字段, 多选

3. 选择附加信息表(B表), 以及要追加的字段

工具下载
小工具只在本地运行, 不会上传数据, 有需要可加QQ群: 748194967 群名称: Excel便捷小工具. 也可以在评论区留言, 说出你想要的小工具需求.
源代码
1 #给某个表格追加编号,身份证号等信息 2 import sys 3 import tkinter as tk 4 from tkinter import filedialog, messagebox, scrolledtext 5 6 import openpyxl 7 from openpyxl import load_workbook 8 9 from utils import select_file, read_excel, tool, log, alert, style 10 11 excel_a = False 12 excel_b = False 13 14 file_titles_a = {} 15 file_titles_b = {} 16 17 def read_file_a(): 18 global excel_a 19 file_path = select_file.excel_one('选择A文件, 单选') 20 if file_path == False: 21 return 22 append_text(f"选择文件:{file_path}") 23 24 excel_a = read_excel.ExcelTool(file_path).excel 25 excel_a.sheet_data() 26 titles = ','.join(excel_a.title) 27 append_text(f"A文件表头:{titles}") 28 29 choice = tool.array_lpad_idx(excel_a.title) 30 selected = select_file.checkbox(choice, '选择字段(可以选择多个字段。B表也要存在同样的字段。)') 31 if selected == False: 32 return False 33 else: 34 for v in selected: 35 idx,t = v.split('-') 36 file_titles_a[idx] = t 37 38 str = ','.join(list(file_titles_a.values())) 39 label11.config(text=str) 40 append_text(f"A表选择了字段:{str}") 41 42 def read_file_b(): 43 global excel_b 44 file_path = select_file.excel_one('选择B文件, 单选') 45 if file_path == False: 46 return 47 append_text(f"选择文件:{file_path}") 48 49 excel_b = read_excel.ExcelTool(file_path).excel 50 excel_b.sheet_data() 51 titles = ','.join(excel_b.title) 52 append_text(f"B文件表头:{titles}") 53 54 choice = tool.array_lpad_idx(excel_b.title) 55 selected = select_file.checkbox(choice, '选择字段(这些数据将会补充到A表中)') 56 if selected == False: 57 return False 58 else: 59 for v in selected: 60 idx,t = v.split('-') 61 file_titles_b[idx] = t 62 63 str = ','.join(list(file_titles_b.values())) 64 label22.config(text=str) 65 append_text(f"B表, 选择了字段:{str}") 66 67 def append_data(): 68 global excel_a 69 global excel_b 70 global file_titles_a 71 global file_titles_b 72 73 append_text(f"开始查找并追加数据") 74 75 #检查依据字段是否存在 76 for k,v in file_titles_a.items(): 77 if v not in excel_b.title: 78 messagebox.showinfo("错误", f"此表中不存在字段: “{v}”, 请确认。") 79 return False 80 81 #新建标签存储数据 82 sheet_name = '补充数据' 83 new_sheet = read_excel.create_new_sheet(excel_a.wb, sheet_name, []) 84 85 need_append_match_titles = list(file_titles_a.values()) #参与匹配的字段 86 all_info_match_index = [] #完整数据表中对应字段的索引 87 for v in need_append_match_titles: #第一行是标题 88 i = excel_b.title_flip[v] 89 all_info_match_index.append(i) 90 91 all_info_map = {} 92 all_info_append_index = list(file_titles_b.keys()) #完整数据中补充字段的索引 93 for row in excel_b.file_data: 94 # 取出用来做键的字段 95 keys = tool.array_index_values(row, all_info_match_index) 96 str = ','.join(keys) 97 if str not in all_info_map: 98 all_info_map[str] = [] 99 100 # 取出用来做值的字段 101 values = tool.array_index_values(row, all_info_append_index) 102 103 all_info_map[str].append(values) 104 105 106 #开始映射 107 need_append_index = list(file_titles_a.keys()) 108 for row in excel_a.file_data: 109 keys = tool.array_index_values(row, need_append_index) 110 str = ','.join(keys) 111 112 if str in all_info_map: 113 for v in all_info_map[str]: 114 for vv in v: 115 keys.append(vv) 116 117 new_sheet.append(keys) 118 119 excel_a.save_file() 120 append_text(f"追加结束,写入到表格:{excel_a.file_path} 标签:{sheet_name}") 121 alert.success('结束') 122 tool.open_excel(excel_a.file_path) 123 #sys.exit() 124 125 126 def append_text(str): 127 str += "\n\n" 128 text_area.insert(tk.END, str) 129 130 def button_cancel(): 131 sys.exit() 132 133 #######################################主窗口 134 # 创建主窗口 135 root = tk.Tk() 136 root.title("Excel追加信息") 137 root.geometry("650x400") # 设置窗口大小 138 139 ########################################选择被追加表 140 frame1 = tk.Frame(root) 141 frame1.pack(anchor=tk.W) 142 143 # 创建一个标签 144 label1 = tk.Label(frame1, text="A表:") 145 label1.pack(side=tk.LEFT, pady=10, padx=5) 146 147 # 创建一个按钮 148 button1 = tk.Button(frame1, text="选择文件", command=read_file_a) 149 button1.pack(side=tk.LEFT, pady=10) 150 151 label11 = tk.Label(frame1, text="注意:第一行应是表头") 152 label11.pack(side=tk.LEFT, pady=10, padx=5) 153 154 ##########################################选择考核人员名单 155 frame2 = tk.Frame(root) 156 frame2.pack(anchor=tk.W) 157 158 # 创建一个标签 159 label2 = tk.Label(frame2, text="B表:") 160 label2.pack(side=tk.LEFT, pady=10, padx=5) 161 162 # 创建一个按钮 163 button2 = tk.Button(frame2, text="选择文件", command=read_file_b) 164 button2.pack(side=tk.LEFT, pady=10) 165 166 # 创建一个标签 167 label22 = tk.Label(frame2, text="注意:第一行应是表头") 168 label22.pack(side=tk.LEFT, pady=10, padx=5) 169 170 #########################################计算按钮 171 172 frame4 = tk.Frame(root) 173 frame4.pack(expand=True, fill=tk.X) 174 175 button41 = tk.Button(frame4, text=" 追加信息 ", command=append_data) 176 button41.pack(side=tk.LEFT, expand=True) 177 178 button42 = tk.Button(frame4, text=" 退出 ", command=button_cancel) 179 button42.pack(side=tk.LEFT, expand=True) 180 181 ########################################检查过程 182 # 创建一个可滚动的 Text 小部件 183 text_area = scrolledtext.ScrolledText(root, wrap=tk.WORD, width=40, height=60) 184 text_area.pack(padx=10, pady=10, fill=tk.BOTH, expand=True) 185 readme = '''使用说明: 186 187 1. 本程序会将B表的信息追加到A表对应行的后边. 188 比如两个表中都有"姓名", 把B表中有相同姓名的"部门", "身份证号" 等信息追加到A表中 189 190 2. 第一步: 选择A表中用于和B表关联用的列, 比如"姓名", 这一步要求两个表里都有"姓名"这一列 191 192 3. 第二步: 选择B表中需要追加到A表的列, 比如"部门", "身份证号"等 193 194 4. 如果B表中有多个"姓名"相同的数据, 追加时会同时显示在同一行 195 ''' 196 text_area.insert(tk.END, readme) 197 198 # 运行应用程序 199 root.mainloop()

浙公网安备 33010602011771号