277 lines
12 KiB
Python
277 lines
12 KiB
Python
import tkinter as tk
|
|
from tkinter import filedialog, messagebox, ttk
|
|
import openpyxl
|
|
import xlrd
|
|
import os
|
|
import requests
|
|
import json
|
|
from datetime import datetime
|
|
import sys # 导入sys模块
|
|
|
|
|
|
class ExcelProcessorApp:
|
|
def __init__(self, root):
|
|
self.root = root
|
|
self.root.title("爱车店剩余项目拆分")
|
|
|
|
# 文件选择按钮
|
|
self.file_button = tk.Button(root, text="选择文件", command=self.select_file)
|
|
self.file_button.grid(row=0, column=0, padx=10, pady=10)
|
|
|
|
# 工作表选择下拉列表
|
|
self.sheet_label = tk.Label(root, text="选择工作表:")
|
|
self.sheet_label.grid(row=1, column=0, padx=10, pady=10)
|
|
self.sheet_combobox = ttk.Combobox(root, state="readonly")
|
|
self.sheet_combobox.grid(row=1, column=1, padx=10, pady=10)
|
|
self.sheet_combobox.bind("<<ComboboxSelected>>", self.update_columns)
|
|
|
|
# 列选择下拉列表
|
|
self.column_label = tk.Label(root, text="选择剩余项目列:")
|
|
self.column_label.grid(row=2, column=0, padx=10, pady=10)
|
|
self.column_combobox = ttk.Combobox(root, state="readonly")
|
|
self.column_combobox.grid(row=2, column=1, padx=10, pady=10)
|
|
|
|
# 执行按钮
|
|
self.process_button = tk.Button(root, text="执行处理", command=self.process_data)
|
|
self.process_button.grid(row=3, column=0, columnspan=2, padx=10, pady=10)
|
|
|
|
# 执行明细文本框
|
|
self.details_text = tk.Text(root, height=10, width=50)
|
|
self.details_text.grid(row=4, column=0, columnspan=2, padx=10, pady=10)
|
|
|
|
self.file_path = ""
|
|
self.sheets = []
|
|
self.columns = []
|
|
|
|
# 宜搭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_file(self):
|
|
self.file_path = filedialog.askopenfilename()
|
|
if self.file_path:
|
|
self.details_text.delete(1.0, tk.END)
|
|
self.details_text.insert(tk.END, f"文件路径: {self.file_path}\n")
|
|
self.load_sheets()
|
|
|
|
def load_sheets(self):
|
|
try:
|
|
if self.file_path.endswith('.xlsx'):
|
|
workbook = openpyxl.load_workbook(self.file_path)
|
|
self.sheets = workbook.sheetnames
|
|
elif self.file_path.endswith('.xls'):
|
|
workbook = xlrd.open_workbook(self.file_path)
|
|
self.sheets = workbook.sheet_names()
|
|
else:
|
|
raise ValueError("Unsupported file format")
|
|
|
|
self.sheet_combobox['values'] = self.sheets
|
|
self.sheet_combobox.current(0)
|
|
self.update_columns(None)
|
|
except Exception as e:
|
|
messagebox.showerror("Error", f"无法加载工作表: {e}")
|
|
|
|
def update_columns(self, event):
|
|
try:
|
|
sheet_name = self.sheet_combobox.get()
|
|
if self.file_path.endswith('.xlsx'):
|
|
workbook = openpyxl.load_workbook(self.file_path)
|
|
sheet = workbook[sheet_name]
|
|
self.columns = [cell.value for cell in sheet[1]]
|
|
elif self.file_path.endswith('.xls'):
|
|
workbook = xlrd.open_workbook(self.file_path)
|
|
sheet = workbook.sheet_by_name(sheet_name)
|
|
self.columns = [sheet.cell_value(0, col) for col in range(sheet.ncols)]
|
|
else:
|
|
raise ValueError("Unsupported file format")
|
|
|
|
self.column_combobox['values'] = self.columns
|
|
self.column_combobox.current(0)
|
|
except Exception as e:
|
|
messagebox.showerror("Error", f"无法加载列: {e}")
|
|
|
|
def process_data(self):
|
|
if not self.file_path:
|
|
messagebox.showerror("Error", "请先选择文件")
|
|
return
|
|
|
|
sheet_name = self.sheet_combobox.get()
|
|
remaining_column = self.column_combobox.get()
|
|
|
|
if not sheet_name or not remaining_column:
|
|
messagebox.showerror("Error", "请选择工作表和剩余项目列")
|
|
return
|
|
|
|
start_time = datetime.now() # 记录处理开始时间
|
|
processing_info = {} # 用于存储处理信息的字典
|
|
|
|
try:
|
|
if self.file_path.endswith('.xlsx'):
|
|
workbook = openpyxl.load_workbook(self.file_path)
|
|
sheet = workbook[sheet_name]
|
|
headers = [cell.value for cell in sheet[1]]
|
|
elif self.file_path.endswith('.xls'):
|
|
workbook = xlrd.open_workbook(self.file_path)
|
|
sheet = workbook.sheet_by_name(sheet_name)
|
|
headers = [sheet.cell_value(0, col) for col in range(sheet.ncols)]
|
|
else:
|
|
raise ValueError("Unsupported file format")
|
|
|
|
remaining_index = headers.index(remaining_column)
|
|
card_index = headers.index('卡号')
|
|
total_value_index = headers.index('剩余项目总价值') if '剩余项目总价值' in headers else -1
|
|
|
|
# 新建工作簿
|
|
new_workbook = openpyxl.Workbook()
|
|
new_sheet = new_workbook.active
|
|
new_sheet.append(headers + ['数量'])
|
|
|
|
# 处理每一行数据
|
|
card_seen = set()
|
|
if self.file_path.endswith('.xlsx'):
|
|
for row in sheet.iter_rows(min_row=2, values_only=True):
|
|
if row[remaining_index] and isinstance(row[remaining_index], str):
|
|
services = row[remaining_index].split("|")
|
|
for service in services:
|
|
parts = service.strip().split('x', 1)
|
|
new_row = list(row)
|
|
new_row[remaining_index] = parts[0].strip()
|
|
if len(parts) > 1:
|
|
new_row.append(int(parts[1].strip()))
|
|
else:
|
|
new_row.append(None)
|
|
|
|
# 处理“剩余项目总价值”
|
|
if card_index >= 0 and row[card_index] in card_seen:
|
|
new_row[total_value_index] = None
|
|
else:
|
|
card_seen.add(row[card_index])
|
|
|
|
new_sheet.append(new_row)
|
|
|
|
else:
|
|
new_sheet.append(list(row) + [None])
|
|
elif self.file_path.endswith('.xls'):
|
|
for row_idx in range(1, sheet.nrows):
|
|
row = [sheet.cell_value(row_idx, col) for col in range(sheet.ncols)]
|
|
if row[remaining_index] and isinstance(row[remaining_index], str):
|
|
services = row[remaining_index].split("|")
|
|
for service in services:
|
|
parts = service.strip().split('x', 1)
|
|
new_row = list(row)
|
|
new_row[remaining_index] = parts[0].strip()
|
|
if len(parts) > 1:
|
|
new_row.append(int(parts[1].strip()))
|
|
else:
|
|
new_row.append(None)
|
|
|
|
# 处理“剩余项目总价值”
|
|
if card_index >= 0 and row[card_index] in card_seen:
|
|
new_row[total_value_index] = None
|
|
else:
|
|
card_seen.add(row[card_index])
|
|
|
|
new_sheet.append(new_row)
|
|
|
|
else:
|
|
new_sheet.append(list(row) + [None])
|
|
|
|
# 保存新文件
|
|
output_file = os.path.join(os.path.dirname(self.file_path), "拆分后_爱车店剩余项目.xlsx")
|
|
new_workbook.save(output_file)
|
|
|
|
# 收集处理信息
|
|
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(self.file_path), # 处理的文件绝对路径
|
|
'textField_m4glr9fp': os.path.abspath(output_file), # 新文件保存的绝对路径
|
|
'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(self.file_path), # 处理的文件绝对路径
|
|
'textField_m4glr9fp': '', # 新文件保存的绝对路径
|
|
'textField_m4gewm38': success, # 是否处理成功
|
|
}
|
|
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}")
|
|
|
|
if isinstance(success, bool) and success:
|
|
messagebox.showinfo("成功",
|
|
f"数据已成功写入 {output_file}\n表单提交状态: {processing_info['form_submission_status']}")
|
|
elif isinstance(success, str) and "处理失败" in success:
|
|
messagebox.showerror("失败", f"处理过程中发生了错误: {success}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
root = tk.Tk()
|
|
app = ExcelProcessorApp(root)
|
|
root.mainloop()
|