294 lines
12 KiB
Python
294 lines
12 KiB
Python
import tkinter as tk
|
|
from tkinter import filedialog, ttk, scrolledtext
|
|
import openpyxl
|
|
import xlrd
|
|
import requests
|
|
import json
|
|
from datetime import datetime
|
|
import sys # 导入sys模块
|
|
import os
|
|
|
|
"""
|
|
打包命令
|
|
"""
|
|
|
|
|
|
class ExcelMergerApp:
|
|
def __init__(self, root):
|
|
self.root = root
|
|
self.root.title("黑谷套餐卡手机号匹配工具")
|
|
|
|
# 创建文件选择按钮
|
|
self.file1_path = ""
|
|
self.file2_path = ""
|
|
tk.Button(root, text="选择套餐卡文件", command=self.select_file1).grid(row=0, column=0, padx=10, pady=5)
|
|
tk.Button(root, text="选择储值卡文件", command=self.select_file2).grid(row=0, column=1, padx=10, pady=5)
|
|
|
|
# 创建Sheet选择下拉框及其标签
|
|
tk.Label(root, text="套餐卡Sheet:").grid(row=1, column=0, padx=10, pady=5, sticky=tk.W)
|
|
self.sheet1_var = tk.StringVar()
|
|
self.sheet1_combo = ttk.Combobox(root, textvariable=self.sheet1_var)
|
|
self.sheet1_combo.grid(row=1, column=1, padx=10, pady=5, sticky=tk.W)
|
|
|
|
tk.Label(root, text="储值卡Sheet:").grid(row=2, column=0, padx=10, pady=5, sticky=tk.W)
|
|
self.sheet2_var = tk.StringVar()
|
|
self.sheet2_combo = ttk.Combobox(root, textvariable=self.sheet2_var)
|
|
self.sheet2_combo.grid(row=2, column=1, padx=10, pady=5, sticky=tk.W)
|
|
|
|
# 创建列选择下拉框及其标签
|
|
tk.Label(root, text="套餐卡卡号列:").grid(row=3, column=0, padx=10, pady=5, sticky=tk.W)
|
|
self.column1_var = tk.StringVar()
|
|
self.column1_combo = ttk.Combobox(root, textvariable=self.column1_var)
|
|
self.column1_combo.grid(row=3, column=1, padx=10, pady=5, sticky=tk.W)
|
|
|
|
tk.Label(root, text="储值卡卡号列:").grid(row=4, column=0, padx=10, pady=5, sticky=tk.W)
|
|
self.column2_var = tk.StringVar()
|
|
self.column2_combo = ttk.Combobox(root, textvariable=self.column2_var)
|
|
self.column2_combo.grid(row=4, column=1, padx=10, pady=5, sticky=tk.W)
|
|
|
|
tk.Label(root, text="储值卡手机号列:").grid(row=5, column=0, padx=10, pady=5, sticky=tk.W)
|
|
self.column3_var = tk.StringVar()
|
|
self.column3_combo = ttk.Combobox(root, textvariable=self.column3_var)
|
|
self.column3_combo.grid(row=5, column=1, padx=10, pady=5, sticky=tk.W)
|
|
|
|
# 创建合并按钮
|
|
tk.Button(root, text="合并文件", command=self.merge_files).grid(row=6, columnspan=2, padx=10, pady=5)
|
|
|
|
# 添加一个文本区域用于显示执行详情
|
|
self.log_text = scrolledtext.ScrolledText(root, wrap=tk.WORD, width=60, height=10)
|
|
self.log_text.grid(row=7, column=0, columnspan=2, padx=10, pady=5)
|
|
|
|
# 宜搭API配置
|
|
self.appKey = "ding5kqocon5s9oph5uq"
|
|
self.appSecret = "HL1jgsIIfLAC0eTH0A1m4mwxUDqbgsiPeCCGGE3ocM6qJBTIW7Ivt9drxF_Z4Kb_"
|
|
|
|
# 记录程序启动时的打开时间
|
|
self.processing_info = {} # 用于存储处理信息的字典
|
|
self.open_time = datetime.now()
|
|
self.processing_info['textField_m4gewm35'] = self.get_application_path() # 获取程序的绝对路径
|
|
self.processing_info['textField_m4gewm34'] = self.root.title() # 工具名称
|
|
self.processing_info['textField_m4gewm36'] = self.open_time.strftime('%Y-%m-%d %H:%M:%S') # 程序打开时间
|
|
|
|
def get_application_path(self):
|
|
"""根据是否为打包的exe文件,返回应用程序的绝对路径"""
|
|
if getattr(sys, 'frozen', False):
|
|
# 如果是打包的exe文件
|
|
return os.path.dirname(sys.executable)
|
|
else:
|
|
# 如果是普通的Python脚本
|
|
return os.path.dirname(os.path.abspath(__file__))
|
|
|
|
def generateToken(self) -> str:
|
|
"""生成访问令牌"""
|
|
token_api = 'https://api.dingtalk.com/v1.0/oauth2/accessToken'
|
|
data = {
|
|
"appKey": self.appKey,
|
|
"appSecret": self.appSecret
|
|
}
|
|
response = requests.post(token_api, json=data)
|
|
if response.status_code == 200:
|
|
return response.json().get('accessToken')
|
|
else:
|
|
raise Exception(f"Failed to get token: {response.text}")
|
|
|
|
def forms_instances(self, token, formDataJson):
|
|
"""新建表单内容"""
|
|
api = 'https://api.dingtalk.com/v1.0/yida/forms/instances'
|
|
headers = {
|
|
"Content-Type": "application/json",
|
|
"x-acs-dingtalk-access-token": token
|
|
}
|
|
payload = {
|
|
"appType": "APP_TNVBVZ3K8G56HG03Z45Q",
|
|
"systemToken": "CH7669818R0WN18TYTYJ42PE6GY22WZN0BYWKD1",
|
|
"userId": "yida_pub_account", # 曹伟 id
|
|
"formUuid": "FORM-D60584CCEBDB4CEF8AA1CF81D4E50770KEMY",
|
|
"formDataJson": json.dumps(formDataJson)
|
|
}
|
|
response = requests.post(api, headers=headers, json=payload)
|
|
return response
|
|
|
|
def select_file1(self):
|
|
path = filedialog.askopenfilename()
|
|
if path:
|
|
self.file1_path = path
|
|
self.update_sheet_combos(1, path)
|
|
self.update_log(f"选择了套餐卡文件: {path}\n")
|
|
|
|
def select_file2(self):
|
|
path = filedialog.askopenfilename()
|
|
if path:
|
|
self.file2_path = path
|
|
self.update_sheet_combos(2, path)
|
|
self.update_log(f"选择了储值卡文件: {path}\n")
|
|
|
|
def update_sheet_combos(self, file_num, path):
|
|
if path.endswith('.xlsx'):
|
|
workbook = openpyxl.load_workbook(path)
|
|
sheets = workbook.sheetnames
|
|
else:
|
|
workbook = xlrd.open_workbook(path)
|
|
sheets = workbook.sheet_names()
|
|
|
|
if file_num == 1:
|
|
self.sheet1_combo['values'] = sheets
|
|
self.sheet1_combo.current(0) # 默认选择第一个Sheet
|
|
self.update_column_combos(1, path, sheets[0])
|
|
else:
|
|
self.sheet2_combo['values'] = sheets
|
|
self.sheet2_combo.current(0) # 默认选择第一个Sheet
|
|
self.update_column_combos(2, path, sheets[0])
|
|
|
|
def update_column_combos(self, file_num, path, sheet):
|
|
if path.endswith('.xlsx'):
|
|
workbook = openpyxl.load_workbook(path)
|
|
ws = workbook[sheet]
|
|
columns = [cell.value for cell in ws[1]]
|
|
else:
|
|
workbook = xlrd.open_workbook(path)
|
|
ws = workbook.sheet_by_name(sheet)
|
|
columns = [ws.cell_value(0, col) for col in range(ws.ncols)]
|
|
|
|
if file_num == 1:
|
|
self.column1_combo['values'] = columns
|
|
self.column1_combo.current(0) # 默认选择第一列
|
|
elif file_num == 2:
|
|
self.column2_combo['values'] = columns
|
|
self.column2_combo.current(0) # 默认选择第一列
|
|
self.column3_combo['values'] = columns
|
|
self.column3_combo.current(0) # 默认选择第一列
|
|
|
|
def merge_files(self):
|
|
# 获取用户选择的信息
|
|
file1 = self.file1_path
|
|
file2 = self.file2_path
|
|
sheet1 = self.sheet1_var.get()
|
|
sheet2 = self.sheet2_var.get()
|
|
col1 = self.column1_var.get()
|
|
col2 = self.column2_var.get()
|
|
col3 = self.column3_var.get()
|
|
|
|
# 检查所有必要信息是否已选择
|
|
if not all([file1, file2, sheet1, sheet2, col1, col2, col3]):
|
|
self.update_log("请确保所有选项都已选择。\n")
|
|
return
|
|
|
|
start_time = datetime.now() # 记录处理开始时间
|
|
processing_info = {} # 用于存储处理信息的字典
|
|
|
|
try:
|
|
# 读取数据
|
|
if file1.endswith('.xlsx'):
|
|
workbook1 = openpyxl.load_workbook(file1)
|
|
ws1 = workbook1[sheet1]
|
|
rows1 = list(ws1.iter_rows(values_only=True))
|
|
else:
|
|
workbook1 = xlrd.open_workbook(file1)
|
|
ws1 = workbook1.sheet_by_name(sheet1)
|
|
rows1 = [[ws1.cell_value(row, col) for col in range(ws1.ncols)] for row in range(ws1.nrows)]
|
|
|
|
if file2.endswith('.xlsx'):
|
|
workbook2 = openpyxl.load_workbook(file2)
|
|
ws2 = workbook2[sheet2]
|
|
rows2 = list(ws2.iter_rows(values_only=True))
|
|
else:
|
|
workbook2 = xlrd.open_workbook(file2)
|
|
ws2 = workbook2.sheet_by_name(sheet2)
|
|
rows2 = [[ws2.cell_value(row, col) for col in range(ws2.ncols)] for row in range(ws2.nrows)]
|
|
|
|
# 获取列索引
|
|
col1_idx = None
|
|
col2_idx = None
|
|
col3_idx = None
|
|
for idx, value in enumerate(rows1[0]):
|
|
if value == col1:
|
|
col1_idx = idx
|
|
break
|
|
|
|
for idx, value in enumerate(rows2[0]):
|
|
if value == col2:
|
|
col2_idx = idx
|
|
if value == col3:
|
|
col3_idx = idx
|
|
|
|
if col1_idx is None or col2_idx is None or col3_idx is None:
|
|
self.update_log("无法找到指定的列,请检查列名是否正确。\n")
|
|
return
|
|
|
|
# 合并数据
|
|
merged_data = []
|
|
for row in rows1[1:]:
|
|
merged_data.append(list(row))
|
|
|
|
for row in rows2[1:]:
|
|
card_number = row[col2_idx]
|
|
phone_number = row[col3_idx]
|
|
for merged_row in merged_data:
|
|
if merged_row[col1_idx] == card_number:
|
|
merged_row.append(phone_number)
|
|
break
|
|
|
|
# 保存结果
|
|
output_path = filedialog.asksaveasfilename(defaultextension=".xlsx")
|
|
if output_path:
|
|
workbook_out = openpyxl.Workbook()
|
|
ws_out = workbook_out.active
|
|
headers = list(rows1[0]) + [rows2[0][col3_idx]]
|
|
ws_out.append(headers)
|
|
for row in merged_data:
|
|
ws_out.append(row)
|
|
workbook_out.save(output_path)
|
|
self.update_log(f"合并完成,结果已保存到 {output_path}\n")
|
|
|
|
# 收集处理信息
|
|
success = True
|
|
processing_info = {
|
|
'textField_m4gewm33': start_time.strftime('%Y-%m-%d %H:%M:%S'), # 处理开始时间
|
|
'textField_m4glr9fm': datetime.now().strftime('%Y-%m-%d %H:%M:%S'), # 处理结束时间
|
|
'textField_m4glr9fn': str(datetime.now() - start_time), # 处理时长
|
|
'textField_m4glr9fo': os.path.abspath(file1), # 处理的文件绝对路径
|
|
'textField_m4glr9fp': os.path.abspath(output_path), # 新文件保存的绝对路径
|
|
'textField_m4gewm38': success, # 是否处理成功
|
|
}
|
|
|
|
except Exception as e:
|
|
success = f"处理失败:{str(e)}"
|
|
processing_info = {
|
|
'textField_m4gewm33': start_time.strftime('%Y-%m-%d %H:%M:%S'), # 处理开始时间
|
|
'textField_m4glr9fm': datetime.now().strftime('%Y-%m-%d %H:%M:%S'), # 处理结束时间
|
|
'textField_m4glr9fn': str(datetime.now() - start_time), # 处理时长
|
|
'textField_m4glr9fo': os.path.abspath(file1), # 处理的文件绝对路径
|
|
'textField_m4glr9fp': '', # 新文件保存的绝对路径
|
|
'textField_m4gewm38': success, # 是否处理成功
|
|
}
|
|
self.update_log(f"处理过程中发生了错误: {str(e)}\n")
|
|
finally:
|
|
self.processing_info.update(processing_info)
|
|
# 生成令牌并提交表单
|
|
token = self.generateToken()
|
|
response = self.forms_instances(token, self.processing_info)
|
|
if response.status_code == 200:
|
|
processing_info['form_submission_status'] = "提交成功"
|
|
else:
|
|
processing_info['form_submission_status'] = f"提交失败:{response.text}"
|
|
|
|
# 打印处理信息
|
|
print("处理信息:")
|
|
for key, value in processing_info.items():
|
|
print(f"{key}: {value}")
|
|
|
|
if isinstance(success, bool) and success:
|
|
self.update_log(f"表单提交状态: {processing_info['form_submission_status']}\n")
|
|
elif isinstance(success, str) and "处理失败" in success:
|
|
self.update_log(f"处理过程中发生了错误: {success}\n")
|
|
|
|
def update_log(self, message):
|
|
self.log_text.insert(tk.END, message)
|
|
self.log_text.see(tk.END) # 自动滚动到底部
|
|
|
|
|
|
if __name__ == "__main__":
|
|
root = tk.Tk()
|
|
app = ExcelMergerApp(root)
|
|
root.mainloop()
|