python处理Excel单机小工具:匹数据,增强版VLookup

2025年9月22日

场景:

如果使用vlookup匹数据的话, 每次只能匹配一列, 并且关联的列只能有一列, 比如有同名同姓的数据, 在匹配时就会出现错误

实现目标:

1. 可以同时使用多列数据进行关联, 比如用 姓名和工号, 同时进行匹配

2. 可以同时匹配多列数据, 比如将匹配上的身份证号, 部门等多列数据一次性追加到前表后边

数据截图:

1. A表

image

 2. B表

image

 3. 追加信息后的表

image

交互截图:

1. 打开文件

image

 

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

image

 

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

image

 

工具下载

小工具只在本地运行, 不会上传数据, 有需要可加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()
View Code

 

posted @ 2025-09-22 11:10  myD  阅读(20)  评论(0)    收藏  举报