278 lines
12 KiB
Python
278 lines
12 KiB
Python
import json
|
||
import tkinter as tk
|
||
from tkinter import filedialog, messagebox
|
||
import tkinter.ttk as ttk
|
||
import xlrd
|
||
import openpyxl
|
||
import re
|
||
from zhon import hanzi
|
||
import string
|
||
import os
|
||
from datetime import datetime
|
||
import sys # 导入sys模块
|
||
import requests
|
||
|
||
|
||
def get_application_path():
|
||
"""根据是否为打包的exe文件,返回应用程序的绝对路径"""
|
||
if getattr(sys, 'frozen', False):
|
||
# 如果是打包的exe文件
|
||
return os.path.dirname(sys.executable)
|
||
else:
|
||
# 如果是普通的Python脚本
|
||
return os.path.dirname(os.path.abspath(__file__))
|
||
|
||
|
||
def filter_emoji(text):
|
||
"""过滤掉文本中的emoji表情和其他非预期字符"""
|
||
text = re.sub(':\\S+?:', '', text)
|
||
return re.sub(r'[^{}{}{} ]'.format(hanzi.characters, hanzi.punctuation, string.printable), '', text)
|
||
|
||
|
||
class EmojiCleanerApp:
|
||
def __init__(self, root):
|
||
self.root = root
|
||
self.root.title("Emoji清理工具")
|
||
self.appKey = "ding5kqocon5s9oph5uq"
|
||
self.appSecret = "HL1jgsIIfLAC0eTH0A1m4mwxUDqbgsiPeCCGGE3ocM6qJBTIW7Ivt9drxF_Z4Kb_"
|
||
|
||
# 加载Excel文件按钮
|
||
self.load_excel_button = tk.Button(root, text="加载Excel文件", command=self.load_excel)
|
||
self.load_excel_button.grid(row=0, column=0, padx=10, pady=10)
|
||
|
||
# 工作表选择标签和下拉菜单
|
||
self.worksheets_label = tk.Label(root, text="选择工作表:")
|
||
self.worksheets_label.grid(row=1, column=0, sticky='e')
|
||
|
||
self.worksheets_combobox = ttk.Combobox(root, state="readonly")
|
||
self.worksheets_combobox.grid(row=1, column=1, sticky='w')
|
||
self.worksheets_combobox.bind('<<ComboboxSelected>>', self.on_sheet_select)
|
||
|
||
# 列选择标签和下拉菜单
|
||
self.columns_label = tk.Label(root, text="选择列:")
|
||
self.columns_label.grid(row=2, column=0, sticky='e')
|
||
|
||
self.columns_combobox = ttk.Combobox(root, state="readonly")
|
||
self.columns_combobox.grid(row=2, column=1, sticky='w')
|
||
self.columns_combobox.bind('<<ComboboxSelected>>', self.on_column_select)
|
||
|
||
# 处理并保存Excel文件按钮
|
||
self.process_save_button = tk.Button(root, text="处理并显示结果", command=self.process_and_save_results)
|
||
self.process_save_button.grid(row=3, columnspan=2, pady=10)
|
||
|
||
# 结果输出区域
|
||
self.result_text = tk.Text(root, wrap='word', height=10, width=60)
|
||
self.result_text.grid(row=4, columnspan=2, pady=10)
|
||
|
||
# 初始化变量
|
||
self.excel_file_path = None
|
||
self.workbook = None
|
||
self.selected_worksheet = None
|
||
self.selected_column = None
|
||
self.processing_info = {} # 新增:用于存储处理信息的字典
|
||
|
||
# 记录程序启动时的打开时间
|
||
self.open_time = datetime.now()
|
||
self.processing_info['textField_m4gewm35'] = 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 load_excel(self):
|
||
"""打开文件对话框让用户选择要处理的Excel文件"""
|
||
self.excel_file_path = filedialog.askopenfilename(title="选择Excel文件", filetypes=(
|
||
("Excel files", "*.xls;*.xlsx"), ("All files", "*.*")))
|
||
if self.excel_file_path:
|
||
self.load_workbook()
|
||
|
||
def load_workbook(self):
|
||
"""根据文件类型加载Excel文件并填充工作表下拉菜单"""
|
||
file_extension = os.path.splitext(self.excel_file_path)[1]
|
||
if file_extension == '.xls':
|
||
self.workbook = xlrd.open_workbook(self.excel_file_path)
|
||
elif file_extension == '.xlsx':
|
||
self.workbook = openpyxl.load_workbook(self.excel_file_path)
|
||
else:
|
||
messagebox.showerror("错误", "不支持的文件格式")
|
||
return
|
||
|
||
sheets = self.workbook.sheet_names() if file_extension == '.xls' else self.workbook.sheetnames
|
||
self.worksheets_combobox['values'] = sheets
|
||
self.worksheets_combobox.set('') # 清空选项
|
||
|
||
def on_sheet_select(self, event):
|
||
"""当用户选择工作表时更新可用列的下拉菜单"""
|
||
sheet_name = self.worksheets_combobox.get()
|
||
if sheet_name:
|
||
self.load_columns(sheet_name)
|
||
|
||
def load_columns(self, sheet_name):
|
||
"""从所选工作表的第一行读取列名并填充到列选择下拉菜单中"""
|
||
file_extension = os.path.splitext(self.excel_file_path)[1]
|
||
if file_extension == '.xls':
|
||
worksheet = self.workbook.sheet_by_name(sheet_name)
|
||
columns = worksheet.row_values(0) if worksheet.nrows > 0 else []
|
||
elif file_extension == '.xlsx':
|
||
worksheet = self.workbook[sheet_name]
|
||
columns = [cell.value for cell in worksheet[1]] if worksheet.max_row > 0 else []
|
||
|
||
if not columns:
|
||
# 如果没有找到任何列,说明工作表可能是空白的
|
||
messagebox.showwarning("警告", "当前选择的工作表是空白的")
|
||
self.columns_combobox['values'] = [] # 清空选项
|
||
self.columns_combobox.set('') # 清空选项
|
||
else:
|
||
self.columns_combobox['values'] = columns
|
||
self.columns_combobox.set('') # 清空选项
|
||
|
||
def on_column_select(self, event):
|
||
"""存储用户选择的列"""
|
||
self.selected_column = self.columns_combobox.get()
|
||
|
||
def generateToken(self) -> str:
|
||
"""函数功能:生成访问令牌(token)"""
|
||
token_api = 'https://api.dingtalk.com/v1.0/oauth2/accessToken'
|
||
data = {
|
||
"appKey": f"{self.appKey}",
|
||
"appSecret": f'{self.appSecret}'
|
||
}
|
||
res = requests.post(token_api, json=data)
|
||
token = res.json().get('accessToken')
|
||
print(token)
|
||
return token
|
||
|
||
def forms_instances(self, token, formDataJson):
|
||
"""函数功能:新建表单内容"""
|
||
|
||
api = f'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)
|
||
}
|
||
"""
|
||
{"textField_jcpm6agt": "单行","employeeField_jcos0sar": ["workno"]}
|
||
"""
|
||
|
||
res = requests.post(api, headers=headers, json=payload)
|
||
return res
|
||
|
||
def process_and_save_results(self):
|
||
"""处理选定列的数据并保存到新的Excel文件中"""
|
||
start_time = datetime.now() # 记录处理开始时间
|
||
success = False
|
||
|
||
if not self.selected_column:
|
||
messagebox.showwarning("警告", "请选择要处理的列")
|
||
return
|
||
|
||
try:
|
||
file_extension = os.path.splitext(self.excel_file_path)[1]
|
||
sheet_name = self.worksheets_combobox.get()
|
||
worksheet = self.workbook.sheet_by_name(sheet_name) if file_extension == '.xls' else self.workbook[
|
||
sheet_name]
|
||
|
||
# 检查工作表是否为空
|
||
if (file_extension == '.xls' and worksheet.nrows == 0) or (
|
||
file_extension == '.xlsx' and worksheet.max_row <= 1):
|
||
raise ValueError("所选工作表是空白的")
|
||
|
||
column_index = worksheet.row_values(0).index(self.selected_column) if file_extension == '.xls' else next(
|
||
(i for i, cell in enumerate(worksheet[1]) if cell.value == self.selected_column), None)
|
||
|
||
if column_index is None:
|
||
raise ValueError("无法找到所选列")
|
||
|
||
# 创建一个新的工作簿和工作表
|
||
new_workbook = openpyxl.Workbook()
|
||
new_worksheet = new_workbook.active
|
||
new_worksheet.title = sheet_name
|
||
|
||
# 复制原始工作表的所有数据
|
||
for row_idx in range(1, worksheet.nrows + 1 if file_extension == '.xls' else worksheet.max_row + 1):
|
||
for col_idx in range(1, worksheet.ncols + 1 if file_extension == '.xls' else worksheet.max_column + 1):
|
||
cell_value = worksheet.cell(row_idx - 1,
|
||
col_idx - 1).value if file_extension == '.xls' else worksheet.cell(
|
||
row=row_idx, column=col_idx).value
|
||
new_worksheet.cell(row=row_idx, column=col_idx, value=cell_value)
|
||
|
||
# 处理选定列的数据
|
||
for row_idx in range(2,
|
||
worksheet.nrows + 1 if file_extension == '.xls' else worksheet.max_row + 1): # 从第二行开始,因为第一行是列名
|
||
cell_value = worksheet.cell(row_idx - 1,
|
||
column_index).value if file_extension == '.xls' else worksheet.cell(
|
||
row=row_idx, column=column_index + 1).value
|
||
if isinstance(cell_value, str):
|
||
filtered_value = filter_emoji(cell_value)
|
||
new_worksheet.cell(row=row_idx, column=column_index + 1, value=filtered_value)
|
||
self.result_text.insert(tk.END, f"处理前: {cell_value} -> 处理后: {filtered_value}\n")
|
||
|
||
# 保存新的Excel文件
|
||
base_name = os.path.basename(self.excel_file_path)
|
||
new_file_name = f"处理后_{base_name}"
|
||
new_file_path = os.path.join(os.path.dirname(self.excel_file_path), new_file_name)
|
||
abs_new_file_path = os.path.abspath(new_file_path) # 获取新文件的绝对路径
|
||
new_workbook.save(new_file_path)
|
||
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.excel_file_path), # 处理的文件绝对路径
|
||
'textField_m4glr9fp': abs_new_file_path, # 新文件保存的绝对路径
|
||
'textField_m4gewm38': success # 是否处理成功
|
||
}
|
||
print(processing_info)
|
||
|
||
except Exception as e:
|
||
messagebox.showerror("错误", str(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.excel_file_path), # 处理的文件绝对路径
|
||
'textField_m4glr9fp': '', # 新文件保存的绝对路径
|
||
'textField_m4gewm38': success, # 是否处理成功
|
||
}
|
||
|
||
finally:
|
||
end_time = datetime.now() # 记录处理结束时间
|
||
processing_duration = end_time - start_time # 计算处理时长
|
||
print(self.excel_file_path)
|
||
# 更新处理信息
|
||
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 self.processing_info.items():
|
||
print(f"{key}: {value}")
|
||
|
||
if isinstance(success, bool) and success:
|
||
messagebox.showinfo("成功",
|
||
f"文件已保存为: {abs_new_file_path}\n表单提交状态: {processing_info['form_submission_status']}")
|
||
elif isinstance(success, str) and "处理失败" in success:
|
||
messagebox.showerror("失败", f"处理过程中发生了错误: {success}")
|
||
|
||
|
||
if __name__ == "__main__":
|
||
root = tk.Tk()
|
||
app = EmojiCleanerApp(root)
|
||
root.mainloop()
|