【有趣的python项目】(三)Excel到期提醒
- 2026-11-10 16:22:20
【有趣的python项目】(三)Excel到期提醒一个python读取excel并自动提醒的小工具,比较符合打工人的使用场景:假设你有一些工作Excel,其中储存了带有截止时间的数据,比如项目进度表、工作流程表之内的,每一条都带有截止时间,需要你在截止时间之前作出处理。为避免超期,可以使用python设计一个开机自动后台运行的程序,来实时监测指定Excel中的截止时间,一旦逼近截止时间则强制弹窗提醒。 这个项目主要熟悉两方面操作: 1.python读取excel数据。我们这里使用的是第三方库openpyxl。 2.python对时间的处理及时间间隔计算。内置库datetime。 3.tkinter 简单界面编写。界面可以设置excel的路径,要监测的时间列,提醒提前时间等。 

代码:


# coding=utf-8import osimport randomimport threadingimport timeimport configparserimport tkinter.messageboximport datetimefrom tkinter import *from tkinter import filedialogfrom openpyxl import load_workbook# 全局变量config = configparser.ConfigParser()CONFIG_FILE = 'reminder_config.ini'excel_path = ''time_column = 'F'remind_minutes = 60running = Falsemonitor_thread = Nonedef load_config():"""加载配置"""global excel_path, time_column, remind_minutesif os.path.exists(CONFIG_FILE):config.read(CONFIG_FILE, encoding='utf-8')excel_path = config.get('SETTINGS', 'excel_path', fallback='')time_column = config.get('SETTINGS', 'time_column', fallback='F')remind_minutes = config.getint('SETTINGS', 'remind_minutes', fallback=60)def save_config():"""保存配置"""config['SETTINGS'] = {'excel_path': excel_path,'time_column': time_column,'remind_minutes': str(remind_minutes) # 确保保存为字符串}with open(CONFIG_FILE, 'w', encoding='utf-8') as f:config.write(f)def select_excel_path():"""选择Excel文件"""global excel_pathfile_path = filedialog.askopenfilename(title='选择Excel文件',filetypes=[('Excel文件', '*.xlsx'), ('所有文件', '*.*')])if file_path:excel_path = file_pathpath_entry.delete(0, END)path_entry.insert(0, excel_path)save_config() # 自动保存配置def update_config():"""更新配置"""global time_column, remind_minutescol_input = col_entry.get().strip().upper()if not col_input or not col_input.isalpha():tkinter.messagebox.showwarning('警告', '时间列必须是字母!')returntry:minutes = int(minute_entry.get().strip())if minutes < 1:raise ValueErrorexcept ValueError:tkinter.messagebox.showwarning('警告', '提醒时间必须是大于0的整数!')returntime_column = col_inputremind_minutes = minutessave_config()tkinter.messagebox.showinfo('成功', '配置已保存!')def col_letter_to_index(col_letter):"""列字母转数字索引"""col_letter = col_letter.upper()if len(col_letter) == 1 and col_letter.isalpha():return ord(col_letter) - ord('A') + 1return 6 # 默认F列def parse_date(date_str):"""解析日期字符串"""for fmt in ['%Y-%m-%d %H:%M:%S', '%Y.%m.%d %H:%M:%S', '%Y-%m-%d %H:%M:%S', '%Y/%m/%d %H:%M:%S']:try:return datetime.datetime.strptime(str(date_str).strip(), fmt)except ValueError:continuereturn Nonedef check_reminder():"""检查提醒"""if not excel_path or not os.path.exists(excel_path):returntry:wb = load_workbook(excel_path, data_only=True)#读取excelws = wb.activecol_idx = col_letter_to_index(time_column)#把输入的列号转换为数字(第几列)remind_seconds = remind_minutes * 60now = datetime.datetime.now()for row in range(2, ws.max_row + 1):try:cell_value = ws.cell(row=row, column=col_idx).value#读取设置列的内容if not cell_value:continueend_date = parse_date(cell_value)#解析时间if not end_date:continueremaining = (end_date - now).total_seconds()#时间的加减(计算时间间隔)print(remaining)if remaining <= remind_seconds:# 获取行数据row_data = []for col in range(1, ws.max_column + 1):val = ws.cell(row=row, column=col).valuerow_data.append(str(val) if val else "")# 显示提醒minutes_left = int(remaining / 60)msg = f'到期提醒!\n剩余时间:{minutes_left}分钟\n到期日期:{end_date.strftime("%Y-%m-%d")}\n数据:{"、".join(row_data)}'threading.Thread(target=show_popup, args=(msg,), daemon=True).start()#多线程,其实没必要。except Exception as e:print(f"行{row}处理错误:{e}")except Exception as e:print(f"Excel读取错误:{e}")def show_popup(message):"""显示弹窗"""time.sleep(random.randint(1, 3))win = Toplevel(bg='orange')win.title('到期提醒')win.geometry('600x400')win.attributes('-topmost', True)# 消息文本框text_box = Text(win, font=('微软雅黑', 14), wrap=WORD)text_box.pack(fill=BOTH, expand=True, padx=10, pady=10)text_box.insert('1.0', message)text_box.config(state=DISABLED)# 关闭按钮Button(win, text='关闭', bg='lightblue', font=('微软雅黑', 14),command=win.destroy).pack(pady=10)def monitor_loop():"""监测循环"""while running:check_reminder()time.sleep(20) # 不断循环,每20秒检查一次def toggle_monitor():"""启动/停止监测"""global running, monitor_threadif not excel_path or not os.path.exists(excel_path):tkinter.messagebox.showwarning('警告', '请先选择有效的Excel文件!')returnif not running:running = Truemonitor_btn.config(text='停止监测', bg='lightcoral')monitor_thread = threading.Thread(target=monitor_loop, daemon=True)monitor_thread.start()status_label.config(text='监测状态:运行中', fg='green')else:running = Falsemonitor_btn.config(text='启动监测', bg='lightblue')status_label.config(text='监测状态:已停止', fg='red')def auto_start_monitor():"""自动启动监测"""if excel_path and os.path.exists(excel_path):toggle_monitor()# 创建主界面root = Tk()root.title('到期提醒工具')root.geometry('500x400')root.resizable(False, False)# 加载配置load_config()# Excel路径Label(root, text='Excel文件:', font=('微软雅黑', 11)).place(x=20, y=30)path_entry = Entry(root, width=35, font=('微软雅黑', 11))path_entry.place(x=120, y=30)path_entry.insert(0, excel_path)Button(root, text='浏览', font=('微软雅黑', 10),command=select_excel_path).place(x=430, y=28)# 时间列Label(root, text='时间列:', font=('微软雅黑', 11)).place(x=20, y=80)col_entry = Entry(root, width=10, font=('微软雅黑', 11))col_entry.place(x=120, y=80)col_entry.insert(0, time_column)# 提醒时间Label(root, text='提前提醒(分钟):', font=('微软雅黑', 11)).place(x=20, y=130)minute_entry = Entry(root, width=10, font=('微软雅黑', 11))minute_entry.place(x=160, y=130)minute_entry.insert(0, str(remind_minutes))# 按钮框架frame = Frame(root)frame.place(x=20, y=180, width=460, height=50)Button(frame, text='保存配置', bg='lightgreen', font=('微软雅黑', 11),command=update_config).pack(side=LEFT, padx=5)monitor_btn = Button(frame, text='启动监测', bg='lightblue', font=('微软雅黑', 11),command=toggle_monitor)monitor_btn.pack(side=LEFT, padx=5)# 状态显示status_label = Label(root, text='监测状态:已停止', fg='red', font=('微软雅黑', 11))status_label.place(x=20, y=240)# 自动启动监测root.after(500, auto_start_monitor)root.mainloop()
本文来自网友投稿或网络内容,如有侵犯您的权益请联系我们删除,联系邮箱:wyl860211@qq.com 。