from turtle import pd
import pyscreenshot as ImageGrab
import pytesseract
import pygetwindow as gw
import pyautogui
import time
import pandas
import pyperclip
import openpyxl
import tkinter as tk
from tkinter import messagebox
import psutil
import pygetwindow as gw
# 创建主窗口
root = tk.Tk()
root.withdraw() # 隐藏主窗口,只显示对话框
# 创建进度窗口的函数
def create_progress_window():
progress_window = tk.Toplevel()
progress_window.title("程序进行中,请不要执行其他操作")
progress_window.geometry("800x400")
progress_window.attributes("-alpha", 0.7)
progress_window.wm_attributes("-topmost", 1) # 设置窗口始终置顶
# 创建文本框用于显示进度和打印结果
progress_text = tk.Text(progress_window)
progress_text.pack(fill="both", expand=True)
# 将窗口放置在左下角
screen_width = progress_window.winfo_screenwidth()
screen_height = progress_window.winfo_screenheight()
progress_window.geometry("600x400+{}+{}".format(0, screen_height - 400))
return progress_window, progress_text
# 隐藏进度窗口的函数
def hide_progress_window(progress_window):
progress_window.withdraw()
# 显示进度窗口的函数
def show_progress_window(progress_window):
progress_window.deiconify()
# 更新进度文本的函数
def update_progress_text(progress_text, text):
progress_text.insert(tk.END, text + "\n") # 在文本框中插入新文本
progress_text.see(tk.END) # 滚动文本框以查看新插入的文本
progress_text.update_idletasks() # 强制刷新界面
# 创建进度窗口
progress_window, progress_text = create_progress_window()
# 显示确认对话框
user_response = messagebox.askquestion("确认执行程序", "你正在执行自动下单程序,请打开EAS采购申请单序时簿,程序执行期间避免其他操作,你准备好了吗?")
# 根据用户的选择执行相应的操作
if user_response == "yes":
# 执行程序的主要逻辑
# 在这里放置你的程序代码
update_progress_text(progress_text, "用户已确认,执行程序...")
print("用户已确认,执行程序...")
# 打开 Excel 文件,获取执行次数的数值
workbook = openpyxl.load_workbook('基础表_执行次数.xlsx')
sheet = workbook.active
b1_value = int(sheet['B1'].value)
x1_value = int(sheet['B2'].value)
y1_value = int(sheet['C2'].value)
x2_value = int(sheet['D2'].value)
y2_value = int(sheet['E2'].value)
xx1_value = int(sheet['B3'].value)
yy1_value = int(sheet['C3'].value)
xx2_value = int(sheet['D3'].value)
yy2_value = int(sheet['E3'].value)
contact_file_path = "基础表_坐标.xlsx" # 从Excel文件中读取基础表_坐标数据
contacts_df = pandas.read_excel(contact_file_path)
material_file_path = "基础表_物料.xlsx" # 从Excel文件中读取基础表_物料数据
material_df = pandas.read_excel(material_file_path,dtype={'物料编码': str})
# 四个坐标点的值
x1, y1 = x1_value, y1_value
x2, y2 = x2_value, y2_value
y_offset = 20# 定义坐标增加的偏移量
# 定义一个计数器
consecutive_same_result_count = 0
max_consecutive_same_result_count = 20 # 或者 30,根据你的需求调整
previous_result = None # 用于存储上一次的 OCR 识别结果
# 定义一个点击行的函数
def click_row_by_value(df, column_name, target_value):
row = df[df[column_name] == target_value]
if not row.empty:
x_click = row.iloc[0]['X坐标']
y_click = row.iloc[0]['Y坐标']
wait_time = row.iloc[0]['等待时间'] if '等待时间' in df.columns else 2 # 获取等待时间,如果列不存在,默认为2秒
pyautogui.click(x=x_click, y=y_click)
#print(f"点击坐标:({x_click}, {y_click})")
#添加等待时间
time.sleep(wait_time)
else:
update_progress_text(progress_text, f"未找到名称为'{target_value}'的行")
print(f"未找到名称为'{target_value}'的行")
# 定义复制数据的函数
def copy_to_clipboard_and_paste(text,field_name):
# 清理OCR识别结果和物料表中的物料编码,移除多余的空格和换行符
ocr_result_cleaned = text.strip() # 移除开头和结尾的空格和换行符
material_df['物料编码'] = material_df['物料编码'].str.strip() # 移除物料表中物料编码列的空格和换行符
datacontent = material_df.loc[material_df['物料编码'] == ocr_result_cleaned, field_name].values[0]
pyperclip.copy(datacontent) # 将供应商的值复制到剪贴板
time.sleep(0.25) # 等待一段时间(例如2秒)
pyautogui.hotkey('ctrl', 'v') # 模拟按下Ctrl+V组合键来粘贴
time.sleep(0.25) # 等待一段时间(例如2秒)
pyautogui.press('enter') # 模拟按下回车键
# 定义一个获取窗口标题的函数
def get_window_titles(stop_char=None):
while True:
# 获取所有打开的窗口的标题
window_list = gw.getAllTitles()
# 打印窗口标题
for window_title in window_list:
#print(window_title)
# 检查是否出现了指定的停止字符
if stop_char and stop_char in window_title:
return # 如果出现指定字符,停止函数执行
time.sleep(1)# 等待一秒钟
# 定义OCR循环识别函数
def dynamic_ocr(stop_text):
while True:
screenshot = ImageGrab.grab(bbox=(xx1_value, yy1_value, xx2_value, yy2_value))# 获取屏幕截图
text = pytesseract.image_to_string(screenshot, lang='chi_sim')# 进行OCR识别
#print("识别结果:", text)
if stop_text in text: # 检查是否包含停止字符
break # 如果出现停止字符,终止循环
time.sleep(0.5)# 等待一段时间再进行下一次识别
# 添加检查是否出现"提交"的条件
#定义执行自动下单案件模拟函数
def process_order_from_ocr(x1, y1, x2, y2, material_df, contacts_df):
screenshot = ImageGrab.grab(bbox=(x1, y1, x2, y2))# 获取屏幕截图
text = pytesseract.image_to_string(screenshot)# 进行OCR识别
# 检查OCR识别结果是否为空
if not text:
update_progress_text(progress_text, f"OCR未识别到信息,请确认。继续请输入 'y',退出请输入回车:")
user_input = input("OCR未识别到信息,请确认。继续请输入 'y',退出请输入回车:")
if user_input.lower() != 'y':
return
invalid_supplier = None # 用于存储无效供应商的变量
material_code = text.strip() # 移除开头和结尾的空格和换行符
material_code_count = material_df['物料编码'].value_counts().get(material_code, 0) # 检查匹配的物料编码在Excel中出现的次数
#检查OCR识别结果是否在Excel文件的物料编码列中
if text.strip() in material_df['物料编码'].values:
# 如果匹配到的物料编码在Excel中出现了两次及以上,跳过处理
if material_code_count >= 2:
update_progress_text(progress_text, f"该物料编码存在多条信息: {material_code}")
print(f"该物料编码存在多条信息: {material_code}")
return
x_click = x1 + 50 # 1. 点击物料编码所在的行
y_click = y1 + 12
pyautogui.click(x=x_click, y=y_click)
update_progress_text(progress_text, f"正在生成订单:{text}")
print(f"正在生成订单:{text}",end='')
# 创建要点击的目标值列表
target_values = ["关联生成", "确认关联生成", "供应商", "输入供应商"]# 创建要点击的目标值列表
for target_value in target_values: # 遍历目标值列表,并依次调用函数
click_row_by_value(contacts_df, '击点名称', target_value)
if target_value == "关联生成":
get_window_titles(stop_char="单据转换")# 调用函数,并在出现指定字符时停止
# 添加延时/秒
time.sleep(0.5)
elif target_value == "确认关联生成":
get_window_titles(stop_char="采购订单")# 调用函数,并在出现指定字符时停止
# 添加延时/秒
time.sleep(1.5)
elif target_value == "供应商":
get_window_titles(stop_char="供应商")# 调用函数,并在出现指定字符时停止
# 添加延时/秒
time.sleep(1)
elif target_value == "输入供应商":
copy_to_clipboard_and_paste(text, '供应商')# 使用示例,传递字段名称作为参数
time.sleep(1)
target_values = ["确认供应商" ,"币别", "人民币", "确认人民币", "辅助属性", "辅助属性1","输入辅助属性" ]# 创建要点击的目标值列表
for target_value in target_values:# 遍历目标值列表,并依次调用函数
click_row_by_value(contacts_df, '击点名称', target_value)
if target_value == "币别":
get_window_titles(stop_char="币别")# 调用函数,并在出现指定字符时停止
# 添加延时/秒
time.sleep(1)
elif target_value == "辅助属性1":
get_window_titles(stop_char="辅助属性F7查询")# 调用函数,并在出现指定字符时停止
# 添加延时/秒
time.sleep(1)
elif target_value == "输入辅助属性":
# 添加延时/秒
copy_to_clipboard_and_paste(text, '辅助属性')# 使用示例,传递字段名称作为参数
time.sleep(1)
# 创建要点击的目标值列表
target_values = ["确认辅助属性" , "提交订单", "关闭订单界面"]
# 遍历目标值列表,并依次调用函数
for target_value in target_values:
click_row_by_value(contacts_df, '击点名称', target_value)
if target_value == "确认辅助属性":
time.sleep(1)
elif target_value == "提交订单":
# 添加延时/秒
time.sleep(0.5)
dynamic_ocr(stop_text="提")
else:
invalid_supplier = text.strip() # 存储无效供应商的文本
if invalid_supplier:
update_progress_text(progress_text, f"OCR识别结果中无有效供应商: {invalid_supplier}")
print(f"OCR识别结果中无有效供应商: {invalid_supplier}")
#主程序开始执行
update_progress_text(progress_text, "执行FOR函数")
print("执行FOR函数")
for _ in range(b1_value-1): # 这里的2表示执行两次,您可以根据需要更改次数
process_order_from_ocr(x1, y1, x2, y2, material_df, contacts_df)
# 增加坐标的y值偏移量,以便下次操作
y1 += y_offset
y2 += y_offset
update_progress_text(progress_text, "执行while函数")
print("执行while函数")
while consecutive_same_result_count < max_consecutive_same_result_count:
result = process_order_from_ocr(x1, y1, x2, y2, material_df, contacts_df)
click_row_by_value(contacts_df, '击点名称',"申请单序时簿点击↓" )
# 检查 OCR 识别结果是否与上一次相同
if result == previous_result:
consecutive_same_result_count += 1
else:
consecutive_same_result_count = 0 # 重置计数器
previous_result = result
# 在这里可以添加代码来结束执行或者执行其他操作
update_progress_text(progress_text, "达到最大连续相同结果次数,结束执行")
print("达到最大连续相同结果次数,结束执行")
else:
update_progress_text(progress_text, "用户取消了程序执行")
print("用户取消了程序执行")
# 关闭主窗口
root.destroy()
```****
```