Files
F6--/张阳脚本/工具/GUI文件/接车宝GUI.py
T
2026-01-30 11:28:35 +08:00

234 lines
9.9 KiB
Python

import os
import tkinter as tk
from tkinter import filedialog, messagebox, ttk
from openpyxl import Workbook, load_workbook
import requests
import json
from datetime import datetime
import sys # 导入sys模块
class ExcelSplitterApp:
def __init__(self, root):
self.root = root
self.root.title('接车宝项目数据拆分工具')
self.root.geometry('700x350')
self.create_widgets()
# 宜搭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 create_widgets(self):
self.file_label = tk.Label(self.root, text='选择Excel文件(只支持xlsx文件):')
self.file_label.grid(row=0, column=0, padx=10, pady=10)
self.file_path_entry = tk.Entry(self.root, width=50)
self.file_path_entry.grid(row=0, column=1, padx=10, pady=10)
self.file_button = tk.Button(self.root, text='浏览...', command=self.open_file)
self.file_button.grid(row=0, column=2, padx=10, pady=10)
self.sheet_name_label = tk.Label(self.root, text='工作表名称:')
self.sheet_name_label.grid(row=1, column=0, padx=10, pady=10)
self.sheet_name_combo = ttk.Combobox(self.root, state='readonly')
self.sheet_name_combo.grid(row=1, column=1, padx=10, pady=10)
self.id_label = tk.Label(self.root, text='要作为主键的字段:')
self.id_label.grid(row=2, column=0, padx=10, pady=10)
self.id_combo = ttk.Combobox(self.root, state='readonly')
self.id_combo.grid(row=2, column=1, padx=10, pady=10)
self.a_label = tk.Label(self.root, text='要拆分的内容a:')
self.a_label.grid(row=3, column=0, padx=10, pady=10)
self.a_combo = ttk.Combobox(self.root, state='readonly')
self.a_combo.grid(row=3, column=1, padx=10, pady=10)
self.b_label = tk.Label(self.root, text='要拆分的内容b:')
self.b_label.grid(row=4, column=0, padx=10, pady=10)
self.b_combo = ttk.Combobox(self.root, state='readonly')
self.b_combo.grid(row=4, column=1, padx=10, pady=10)
self.delimiter_label = tk.Label(self.root, text='切割字符(注意符号中英文):')
self.delimiter_label.grid(row=5, column=0, padx=10, pady=10)
self.delimiter_entry = tk.Entry(self.root)
self.delimiter_entry.grid(row=5, column=1, padx=10, pady=10)
self.split_button = tk.Button(self.root, text='开始拆分', command=self.split_data)
self.split_button.grid(row=6, column=1, padx=10, pady=10)
def open_file(self):
file_name = filedialog.askopenfilename(title="选择Excel文件", filetypes=[("Excel Files", "*.xlsx")])
if file_name:
self.file_path_entry.delete(0, tk.END)
self.file_path_entry.insert(0, file_name)
self.load_sheets_and_headers(file_name)
def load_sheets_and_headers(self, file_path):
try:
wb = load_workbook(file_path, read_only=True)
sheets = wb.sheetnames
self.sheet_name_combo['values'] = sheets
if sheets:
self.sheet_name_combo.current(0)
self.load_headers(file_path, sheets[0])
self.sheet_name_combo.bind('<<ComboboxSelected>>',
lambda event: self.load_headers(file_path, self.sheet_name_combo.get()))
except Exception as e:
messagebox.showerror("错误", str(e))
def load_headers(self, file_path, sheet_name):
try:
wb = load_workbook(file_path, read_only=True)
ws = wb[sheet_name]
headers = [cell.value for cell in next(ws.iter_rows(min_row=1, max_row=1))]
self.id_combo['values'] = headers
self.a_combo['values'] = headers
self.b_combo['values'] = headers
if headers:
self.id_combo.current(0)
self.a_combo.current(0)
self.b_combo.current(0)
except Exception as e:
messagebox.showerror("错误", str(e))
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 split_data(self):
file_path = self.file_path_entry.get()
sheet_name = self.sheet_name_combo.get()
delimiter_input = self.delimiter_entry.get()
id_input = self.id_combo.get()
a_input = self.a_combo.get()
b_input = self.b_combo.get()
start_time = datetime.now() # 记录处理开始时间
processing_info = {} # 用于存储处理信息的字典
try:
wb = load_workbook(file_path, data_only=True)
ws = wb[sheet_name]
headers = [cell.value for cell in next(ws.iter_rows(min_row=1, max_row=1))]
id_index = headers.index(id_input)
a_index = headers.index(a_input)
b_index = headers.index(b_input)
split_data = []
for row in ws.iter_rows(min_row=2, values_only=True):
projects = str(row[a_index]).split(delimiter_input) # 使用用户输入的字符切割项目
prices = str(row[b_index]).split(delimiter_input) # 使用用户输入的字符切割价格
for project, price in zip(projects, prices):
split_data.append((row[id_index], project, price))
# 创建新的工作簿来保存拆分后的数据
new_wb = Workbook()
new_ws = new_wb.active
new_ws.append([id_input, a_input, b_input])
for data in split_data:
new_ws.append(data)
# 保存拆分后的数据到新的Excel文件
file_dir = os.path.dirname(file_path)
file_name = os.path.basename(file_path)
output_path = os.path.join(file_dir, f"拆分_{file_name}")
new_wb.save(output_path)
# 收集处理信息
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(file_path), # 处理的文件绝对路径
'textField_m4glr9fp': os.path.abspath(output_path), # 新文件保存的绝对路径
'textField_m4gewm38': True, # 是否处理成功
}
except Exception as 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(file_path), # 处理的文件绝对路径
'textField_m4glr9fp': '', # 新文件保存的绝对路径
'textField_m4gewm38': f"处理失败:{str(e)}", # 是否处理成功
}
messagebox.showerror("失败", f"处理过程中发生了错误: {str(e)}")
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}")
messagebox.showinfo("成功",
f"数据已成功拆分并保存至 {output_path}\n表单提交状态: {processing_info['form_submission_status']}")
if __name__ == '__main__':
root = tk.Tk()
app = ExcelSplitterApp(root)
root.mainloop()