有没有什么软件,能根据源数据表匹配填写另一张表,自由选择需要比较的列如A列或者A+B列比较,匹配成功则填写C列 类似于用excel的VLOOKUP+MATCH函数,还有方方格子的自动填表 以上二个用过感觉不够便携,有没有别的软件能平替下 表格, 用过
python跑的脚本 可以完美对数据进行匹配 [Python] 纯文本查看 复制代码import pandas as pd import tkinter as tk from tkinter import filedialog, ttk, messagebox import os class DataMatcherApp: def __init__(self, root): self.root = root self.root.title("数据表匹配填充工具") self.root.geometry("800x600") self.root.resizable(True, True) # 设置中文字体支持 self.style = ttk.Style() self.style.configure("TLabel", font=("SimHei", 10)) self.style.configure("TButton", font=("SimHei", 10)) self.style.configure("TCombobox", font=("SimHei", 10)) # 数据存储 self.source_df = None self.target_df = None self.source_path = "" self.target_path = "" # 创建界面 self.create_widgets() def create_widgets(self): # 创建主框架 main_frame = ttk.Frame(self.root, padding="10") main_frame.pack(fill=tk.BOTH, expand=True) # 文件选择区域 file_frame = ttk.LabelFrame(main_frame, text="文件选择", padding="10") file_frame.pack(fill=tk.X, pady=5) ttk.Label(file_frame, text="源数据表:").grid(row=0, column=0, sticky=tk.W, pady=5) self.source_entry = ttk.Entry(file_frame, width=50) self.source_entry.grid(row=0, column=1, sticky=tk.W, pady=5, padx=5) ttk.Button(file_frame, text="浏览", command=self.browse_source).grid(row=0, column=2, pady=5, padx=5) ttk.Label(file_frame, text="目标数据表:").grid(row=1, column=0, sticky=tk.W, pady=5) self.target_entry = ttk.Entry(file_frame, width=50) self.target_entry.grid(row=1, column=1, sticky=tk.W, pady=5, padx=5) ttk.Button(file_frame, text="浏览", command=self.browse_target).grid(row=1, column=2, pady=5, padx=5) # 匹配设置区域 match_frame = ttk.LabelFrame(main_frame, text="匹配设置", padding="10") match_frame.pack(fill=tk.X, pady=5) ttk.Label(match_frame, text="用于匹配的源表列:").grid(row=0, column=0, sticky=tk.W, pady=5) self.source_columns = ttk.Combobox(match_frame, width=47, state="readonly", values=[]) self.source_columns.grid(row=0, column=1, sticky=tk.W, pady=5, padx=5) self.source_columns.bind('>', lambda e: self.add_column("source")) ttk.Label(match_frame, text="用于匹配的目标表列:").grid(row=1, column=0, sticky=tk.W, pady=5) self.target_columns = ttk.Combobox(match_frame, width=47, state="readonly", values=[]) self.target_columns.grid(row=1, column=1, sticky=tk.W, pady=5, padx=5) self.target_columns.bind('>', lambda e: self.add_column("target")) # 已选匹配列 ttk.Label(match_frame, text="已选匹配列对:").grid(row=2, column=0, sticky=tk.NW, pady=5) self.match_pairs_frame = ttk.Frame(match_frame) self.match_pairs_frame.grid(row=2, column=1, sticky=tk.W, pady=5, padx=5) self.match_pairs = [] self.match_pairs_labels = [] # 填充设置 fill_frame = ttk.LabelFrame(main_frame, text="填充设置", padding="10") fill_frame.pack(fill=tk.X, pady=5) ttk.Label(fill_frame, text="源表中要填充的数据列:").grid(row=0, column=0, sticky=tk.W, pady=5) self.source_fill_column = ttk.Combobox(fill_frame, width=47, state="readonly", values=[]) self.source_fill_column.grid(row=0, column=1, sticky=tk.W, pady=5, padx=5) ttk.Label(fill_frame, text="目标表中接收数据的列:").grid(row=1, column=0, sticky=tk.W, pady=5) self.target_fill_column = ttk.Combobox(fill_frame, width=47, state="readonly", values=[]) self.target_fill_column.grid(row=1, column=1, sticky=tk.W, pady=5, padx=5) # 添加新列选项 self.new_column_var = tk.BooleanVar() ttk.Checkbutton(fill_frame, text="在目标表中创建新列", variable=self.new_column_var).grid(row=2, column=1, sticky=tk.W, pady=5) ttk.Label(fill_frame, text="新列名称:").grid(row=3, column=0, sticky=tk.W, pady=5) self.new_column_name = ttk.Entry(fill_frame, width=47) self.new_column_name.grid(row=3, column=1, sticky=tk.W, pady=5, padx=5) # 操作按钮 button_frame = ttk.Frame(main_frame, padding="10") button_frame.pack(fill=tk.X, pady=10) ttk.Button(button_frame, text="执行匹配填充", command=self.perform_matching).pack(side=tk.LEFT, padx=10) ttk.Button(button_frame, text="保存结果", command=self.save_result).pack(side=tk.LEFT, padx=10) ttk.Button(button_frame, text="清除设置", command=self.clear_settings).pack(side=tk.LEFT, padx=10) # 状态区域 status_frame = ttk.LabelFrame(main_frame, text="操作状态", padding="10") status_frame.pack(fill=tk.BOTH, expand=True, pady=5) self.status_text = tk.Text(status_frame, height=10, wrap=tk.WORD) self.status_text.pack(fill=tk.BOTH, expand=True) scroll = ttk.Scrollbar(self.status_text, command=self.status_text.yview) scroll.pack(side=tk.RIGHT, fill=tk.Y) self.status_text.config(yscrollcommand=scroll.set, state=tk.DISABLED) def browse_source(self): filename = filedialog.askopenfilename( filetypes=[("Excel files", "*.xlsx;*.xls"), ("CSV files", "*.csv"), ("All files", "*.*")] ) if filename: self.source_entry.delete(0, tk.END) self.source_entry.insert(0, filename) self.load_source_data(filename) def browse_target(self): filename = filedialog.askopenfilename( filetypes=[("Excel files", "*.xlsx;*.xls"), ("CSV files", "*.csv"), ("All files", "*.*")] ) if filename: self.target_entry.delete(0, tk.END) self.target_entry.insert(0, filename) self.load_target_data(filename) def load_source_data(self, filename): try: self.source_path = filename if filename.endswith('.csv'): self.source_df = pd.read_csv(filename) else: self.source_df = pd.read_excel(filename) # 确保所有列名都是字符串类型 self.source_df.columns = self.source_df.columns.astype(str) self.update_source_columns() self.log(f"成功加载源数据表,包含 {len(self.source_df)} 行,{len(self.source_df.columns)} 列") self.log(f"源数据表列名: {list(self.source_df.columns)}") self.log(f"源数据表前几行:\n{self.source_df.head()}") except Exception as e: messagebox.showerror("错误", f"加载源数据表失败: {str(e)}") self.log(f"加载源数据表失败: {str(e)}") def load_target_data(self, filename): try: self.target_path = filename if filename.endswith('.csv'): self.target_df = pd.read_csv(filename) else: self.target_df = pd.read_excel(filename) # 确保所有列名都是字符串类型 self.target_df.columns = self.target_df.columns.astype(str) self.update_target_columns() self.log(f"成功加载目标数据表,包含 {len(self.target_df)} 行,{len(self.target_df.columns)} 列") self.log(f"目标数据表列名: {list(self.target_df.columns)}") self.log(f"目标数据表前几行:\n{self.target_df.head()}") except Exception as e: messagebox.showerror("错误", f"加载目标数据表失败: {str(e)}") self.log(f"加载目标数据表失败: {str(e)}") def update_source_columns(self): if self.source_df is not None: columns = list(self.source_df.columns) self.source_columns['values'] = columns self.source_fill_column['values'] = columns def update_target_columns(self): if self.target_df is not None: columns = list(self.target_df.columns) self.target_columns['values'] = columns self.target_fill_column['values'] = columns def add_column(self, table_type): if table_type == "source" and self.source_columns.get(): self.match_pairs.append((self.source_columns.get(), "")) self.update_match_pairs_display() # 清空选择以便下次选择 self.source_columns.set('') elif table_type == "target" and self.target_columns.get(): # 找到最后一个没有目标列的配对 for i in range(len(self.match_pairs)): if not self.match_pairs[i][1]: self.match_pairs[i] = (self.match_pairs[i][0], self.target_columns.get()) self.update_match_pairs_display() # 清空选择以便下次选择 self.target_columns.set('') break else: # 如果没有找到未配对的目标列,提示用户先添加源列 messagebox.showwarning("警告", "请先添加源表列") def update_match_pairs_display(self): # 清除现有标签 for label in self.match_pairs_labels: label.destroy() self.match_pairs_labels = [] # 创建新标签 for i, (source_col, target_col) in enumerate(self.match_pairs): frame = ttk.Frame(self.match_pairs_frame) frame.pack(fill=tk.X, pady=2) label_text = f"{source_col} → {target_col}" if target_col else f"{source_col} → " label = ttk.Label(frame, text=label_text) label.pack(side=tk.LEFT) btn = ttk.Button(frame, text="删除", command=lambda idx=i: self.remove_pair(idx)) btn.pack(side=tk.RIGHT) self.match_pairs_labels.append(frame) def remove_pair(self, index): if 0 [i] [i]