You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Python定时备份多用户Excel文件时的路径保存问题

实现多用户Excel文档的定时远程备份系统(Python版)

我来帮你完善这个多用户场景下的Excel定时备份方案,你的现有代码已经有了基础的读取和命名逻辑,但还需要解决非本地目录存储、定时任务触发、多用户访问时的文件冲突这几个关键问题,下面是具体的实现方案:

一、核心备份逻辑优化

首先要明确非本地目录的路径(比如网络共享盘、云存储挂载目录),直接在ExcelWriter中指定完整路径即可。另外,多用户访问的Excel容易被锁定,直接用pandas读取可能报错,建议搭配openpyxl引擎,并添加异常捕获处理文件占用的情况。

修改后的基础备份代码:

import pandas as pd
import datetime
from openpyxl import load_workbook

# 源Excel文件路径
source_file = r'Z:\new\Planner_New.xlsx'
# 非本地备份目录(替换成你的实际远程/共享路径)
backup_dir = r'\\backup-server\excel-backups\\'

# 生成带时间戳的备份文件名(替换空格为下划线,避免路径异常)
now = datetime.datetime.now()
time_suffix = now.strftime("%Y-%m-%d_%H.%M.%S")
backup_filename = f"Planner_{time_suffix}.xlsx"
backup_full_path = f"{backup_dir}{backup_filename}"

try:
    # 读取整个Excel文件(支持备份所有sheet)
    excel_file = pd.ExcelFile(source_file)
    # 使用openpyxl引擎保留原文件格式
    with pd.ExcelWriter(backup_full_path, engine='openpyxl') as writer:
        for sheet_name in excel_file.sheet_names:
            # 按需求读取指定列的内容
            df = excel_file.parse(
                sheet_name, 
                header=0, 
                index_col=0, 
                usecols="A:AY", 
                convert_float=True
            )
            df.to_excel(writer, sheet_name=sheet_name)
    print(f"备份成功:{backup_full_path}")
except PermissionError:
    print("错误:源文件正在被其他用户占用,无法读取")
except Exception as e:
    print(f"备份失败:{str(e)}")

二、添加定时任务功能

要实现自动定时备份,推荐用schedule库(简单易用),先通过pip install schedule安装。下面是整合了定时任务的代码:

import schedule
import time

def backup_excel():
    # 把上面的备份逻辑封装到这个函数里
    import pandas as pd
    import datetime
    from openpyxl import load_workbook

    source_file = r'Z:\new\Planner_New.xlsx'
    backup_dir = r'\\backup-server\excel-backups\\'
    now = datetime.datetime.now()
    time_suffix = now.strftime("%Y-%m-%d_%H.%M.%S")
    backup_filename = f"Planner_{time_suffix}.xlsx"
    backup_full_path = f"{backup_dir}{backup_filename}"

    try:
        excel_file = pd.ExcelFile(source_file)
        with pd.ExcelWriter(backup_full_path, engine='openpyxl') as writer:
            for sheet_name in excel_file.sheet_names:
                df = excel_file.parse(
                    sheet_name, 
                    header=0, 
                    index_col=0, 
                    usecols="A:AY", 
                    convert_float=True
                )
                df.to_excel(writer, sheet_name=sheet_name)
        print(f"[{now}] 备份成功:{backup_full_path}")
    except PermissionError:
        print(f"[{now}] 错误:源文件被占用,跳过本次备份")
    except Exception as e:
        print(f"[{now}] 备份失败:{str(e)}")

# 设置定时规则:比如每天上午9点和下午5点各备份一次
schedule.every().day.at("09:00").do(backup_excel)
schedule.every().day.at("17:00").do(backup_excel)

# 也可以设置每小时备份一次
# schedule.every(1).hours.do(backup_excel)

print("定时备份系统已启动,按Ctrl+C停止...")
while True:
    schedule.run_pending()
    time.sleep(60)  # 每分钟检查一次任务是否需要执行

三、多用户场景的额外优化建议

  • 文件占用重试机制:如果频繁遇到文件被占用的情况,可以添加重试逻辑:
    except PermissionError:
        print("源文件被占用,等待30秒后重试...")
        time.sleep(30)
        backup_excel()  # 重新执行备份
    
  • 旧备份清理:定期清理过期备份,避免非本地目录空间不足,可添加清理函数配合定时任务执行:
    def clean_old_backups(days_to_keep=30):
        import os
        cutoff_date = datetime.datetime.now() - datetime.timedelta(days=days_to_keep)
        for filename in os.listdir(backup_dir):
            file_path = os.path.join(backup_dir, filename)
            if os.path.isfile(file_path) and filename.startswith("Planner_"):
                try:
                    file_date = datetime.datetime.strptime(filename.split("_")[1], "%Y-%m-%d_%H.%M.%S")
                    if file_date < cutoff_date:
                        os.remove(file_path)
                        print(f"已清理旧备份:{file_path}")
                except Exception as e:
                    print(f"清理文件失败 {filename}:{str(e)}")
    
  • 日志记录:用logging模块替代print,把备份日志写入文件,方便后续排查问题。

完整可运行代码

import pandas as pd
import datetime
import schedule
import time
from openpyxl import load_workbook
import logging

# 配置日志记录(日志文件也存到非本地目录)
logging.basicConfig(
    filename=r'\\backup-server\excel-backups\backup_logs.log',
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s'
)

def backup_excel():
    source_file = r'Z:\new\Planner_New.xlsx'
    backup_dir = r'\\backup-server\excel-backups\\'
    now = datetime.datetime.now()
    time_suffix = now.strftime("%Y-%m-%d_%H.%M.%S")
    backup_filename = f"Planner_{time_suffix}.xlsx"
    backup_full_path = f"{backup_dir}{backup_filename}"

    try:
        excel_file = pd.ExcelFile(source_file)
        with pd.ExcelWriter(backup_full_path, engine='openpyxl') as writer:
            for sheet_name in excel_file.sheet_names:
                df = excel_file.parse(
                    sheet_name, 
                    header=0, 
                    index_col=0, 
                    usecols="A:AY", 
                    convert_float=True
                )
                df.to_excel(writer, sheet_name=sheet_name)
        logging.info(f"备份成功:{backup_full_path}")
        print(f"[{now}] 备份成功:{backup_full_path}")
    except PermissionError:
        error_msg = "源文件正在被其他用户占用,跳过本次备份"
        logging.warning(error_msg)
        print(f"[{now}] {error_msg}")
    except Exception as e:
        error_msg = f"备份失败:{str(e)}"
        logging.error(error_msg)
        print(f"[{now}] {error_msg}")

def clean_old_backups(days_to_keep=30):
    import os
    cutoff_date = datetime.datetime.now() - datetime.timedelta(days=days_to_keep)
    for filename in os.listdir(backup_dir):
        file_path = os.path.join(backup_dir, filename)
        if os.path.isfile(file_path) and filename.startswith("Planner_"):
            try:
                file_date_str = filename.split("_")[1]
                file_date = datetime.datetime.strptime(file_date_str, "%Y-%m-%d_%H.%M.%S")
                if file_date < cutoff_date:
                    os.remove(file_path)
                    logging.info(f"已清理旧备份:{file_path}")
            except Exception as e:
                logging.warning(f"清理文件失败 {filename}:{str(e)}")

# 配置定时任务
schedule.every().day.at("09:00").do(backup_excel)
schedule.every().day.at("17:00").do(backup_excel)
schedule.every().sunday.at("02:00").do(clean_old_backups, days_to_keep=30)

print("定时备份系统已启动,按Ctrl+C停止...")
try:
    while True:
        schedule.run_pending()
        time.sleep(60)
except KeyboardInterrupt:
    print("系统已停止")
    logging.info("用户手动停止备份系统")

内容的提问来源于stack exchange,提问作者T.Scanlon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:05:09