会计档案数量太大?教你用Python批量整理归档实操指南
一、前期准备与环境搭建
面对海量的会计档案扫描件(如凭证、报表、合同等),手动重命名并按年份、月份归类不仅效率极低,而且极易出错。本方案将利用Python脚本,配合Excel清单,实现档案的批量重命名与自动化归档。在开始之前,请确保你的电脑已准备好以下环境。
1. 安装Python环境
前往Python官网下载最新版安装包。请务必下载 3.9及以上版本。
下载地址:https://www.python.org/downloads/
安装时,必须勾选界面底部的 "Add Python to PATH" 选项,这将允许你在命令行中直接运行Python命令。一路点击 "Install Now" 完成安装。
2. 安装必要的处理库
打开命令行工具(Win键+R,输入 cmd,回车),依次输入以下命令并回车,安装用于处理Excel和文件系统的库:
pip install pandas openpyxl
若安装速度过慢,可使用国内镜像源:
pip install pandas openpyxl -i https://pypi.tuna.tsinghua.edu.cn/simple
二、建立档案映射清单(Excel模板)
程序的核心逻辑是“按图索骥”。我们需要准备一个Excel文件作为“索引表”,告诉程序哪个旧文件名对应什么新名称,以及它应该归属到哪个文件夹。
在你的电脑上新建一个文件夹,命名为 Accounting_Archive_Tool。在此文件夹内新建一个Excel文件,命名为 file_mapping.xlsx。
Excel表格的表头(第一行)必须严格按照以下顺序设置三列:
- 列A(原文件名):扫描件目前的文件名(包含扩展名,如 .pdf 或 .jpg)。
- 列B(标准档案号):你希望重命名后的标准名称(不需要加扩展名,程序会自动识别)。
- 列C(归档目录):文件最终存放的子文件夹名称(例如:2023年/凭证/1月)。
Excel数据示例:
| 原文件名 | 标准档案号 | 归档目录 |
|---|---|---|
| IMG_20230101_001.jpg | 2023-记-1 | 2023年/凭证/1月 |
| scan002.pdf | 2023-资-固-05 | 2023年/资产卡片 |
| DSC0003.jpg | 2023-报-资-001 | 2023年/月度报表 |
将你所有的杂乱文件放入 Accounting_Archive_Tool 下的一个子文件夹中,命名为 raw_files。确保Excel第一列填写的文件名与 raw_files 文件夹内的真实文件名完全一致(注意大小写和空格)。
三、编写自动化整理脚本
在 Accounting_Archive_Tool 根目录下,新建一个文本文件,将其后缀名改为 .py,例如 auto_organize.py。使用记事本或VS Code打开它,粘贴以下完整代码。这段代码包含了异常处理和日志记录功能,确保即使个别文件出错也不会中断整个流程。
```python
import os
import shutil
import pandas as pd
from datetime import datetime
================= 配置区域 =================
Excel清单文件名
EXCEL_FILE = 'file_mapping.xlsx'
源文件所在文件夹
SOURCE_DIR = 'raw_files'
整理后输出的根文件夹
OUTPUT_DIR = 'organized_archives'
日志文件名
LOG_FILE = 'organize_log.txt'
===========================================
def log_message(message, is_error=False):
"""记录日志到屏幕和文件"""
timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
log_entry = f"[{timestamp}] {'[ERROR]' if is_error else '[INFO]'} {message}\n"
print(log_entry.strip())
with open(LOG_FILE, 'a', encoding='utf-8') as f:
f.write(log_entry)
def main():
初始化日志
if os.path.exists(LOG_FILE):
os.remove(LOG_FILE)
log_message("========== 开始执行档案整理任务 ==========")
检查Excel是否存在
if not os.path.exists(EXCEL_FILE):
log_message(f"错误:找不到Excel清单文件 '{EXCEL_FILE}',请确认文件名。", is_error=True)
return
检查源文件夹是否存在
if not os.path.exists(SOURCE_DIR):
log_message(f"错误:找不到源文件夹 '{SOURCE_DIR}'。", is_error=True)
return
try:
读取Excel
df = pd.read_excel(EXCEL_FILE)
检查必要的列是否存在
required_columns = ['原文件名', '标准档案号', '归档目录']
for col in required_columns:
if col not in df.columns:
log_message(f"错误:Excel中缺少必要的列:'{col}'。", is_error=True)
return
success_count = 0
fail_count = 0
遍历Excel每一行
for index, row in df.iterrows():
old_name = str(row['原文件名']).strip()
new_name_base = str(row['标准档案号']).strip()
target_folder_rel = str(row['归档目录']).strip()
源文件完整路径
src_path = os.path.join(SOURCE_DIR, old_name)

检查源文件是否存在
if not os.path.exists(src_path):
log_message(f"未找到文件:{old_name},跳过处理。", is_error=True)
fail_count += 1
continue
获取文件扩展名
_, file_extension = os.path.splitext(old_name)
构建新文件名
new_filename = f"{new_name_base}{file_extension}"
构建目标文件夹完整路径
将Excel中的 "/" 转换为操作系统对应的分隔符
target_folder_path = os.path.join(OUTPUT_DIR, target_folder_rel.replace('/', os.sep))
创建目标文件夹(如果不存在)
if not os.path.exists(target_folder_path):
try:
os.makedirs(target_folder_path)
log_message(f"创建目录:{target_folder_path}")
except OSError as e:
log_message(f"创建目录失败:{target_folder_path},原因:{e}", is_error=True)
fail_count += 1
continue
目标文件完整路径
dest_path = os.path.join(target_folder_path, new_filename)
处理文件重名覆盖问题
if os.path.exists(dest_path):
log_message(f"目标文件已存在,将被覆盖:{dest_path}", is_error=True)
移动并重命名文件
try:
shutil.move(src_path, dest_path)
log_message(f"成功:{old_name} -> {target_folder_rel}/{new_filename}")
success_count += 1
except Exception as e:
log_message(f"移动文件失败:{old_name},原因:{e}", is_error=True)
fail_count += 1
log_message("========== 任务执行完毕 ==========")
log_message(f"总计处理:成功 {success_count} 个,失败 {fail_count} 个。")
except Exception as e:
log_message(f"程序发生严重错误:{e}", is_error=True)
if __name__ == '__main__':
main()
```
四、执行脚本与结果验证
代码保存完毕后,请确保你的目录结构如下所示:
Accounting_Archive_Tool/auto_organize.py(脚本)file_mapping.xlsx(清单)raw_files/(存放杂乱文件的源文件夹)
1. 运行脚本
在 Accounting_Archive_Tool 文件夹内的空白处,按住 Shift键 + 鼠标右键,选择“在此处打开PowerShell窗口”或“在此处打开命令窗口”。输入以下命令并回车:
python auto_organize.py
2. 观察运行反馈
屏幕上会实时滚动显示处理进度。例如:
[2023-10-27 10:00:00] [INFO] 创建目录:organized_archives\2023年\凭证\1月
[2023-10-27 10:00:00] [INFO] 成功:IMG_20230101_001.jpg -> 2023年/凭证/1月/2023-记-1.jpg
3. 检查结果
任务完成后,文件夹内会自动生成一个 organized_archives 文件夹。打开它,你会发现所有文件已经按照Excel中定义的“归档目录”层级自动创建了文件夹,并且文件名已经全部修改为标准的“标准档案号”。
同时,根目录下会生成一个 organize_log.txt 文件,里面记录了每一项操作的成功或失败详情。如果有文件未处理成功,请打开此日志,根据 [ERROR] 标签排查原因(通常是源文件名拼写错误或文件被占用)。
五、常见报错处理与进阶技巧
1. 文件名编码报错
如果你的Excel中包含特殊字符,且报错提示编码问题,请确保 file_mapping.xlsx 文件保存时编码为UTF-8。通常Excel生成的xlsx不会出现此问题,但如果是CSV格式,必须在代码中指定 encoding='utf-8-sig'。
2. 扩展名大小写问题
Windows系统不区分文件扩展名大小写(.JPG 和 .jpg 视为相同),但Linux/Mac区分。本脚本使用了 os.path.splitext,会保留原文件的扩展名大小写格式。如果你的原始文件是 .JPG,生成的新文件也会是 .JPG。
3. 批量处理前的小规模测试
在处理几千个文件之前,强烈建议先在Excel中只保留前3行数据进行测试。确认文件夹结构和命名符合预期后,再放入全量数据运行。这样可以避免因逻辑错误导致大量文件被错误移动,难以还原。
4. 如何处理重复文件
当前脚本逻辑是覆盖目标文件夹中已存在的同名文件。如果你希望保留重复文件(例如自动重命名为 2023-记-1_副本.jpg),需要修改代码中 shutil.move 的部分,增加一个循环检测逻辑:
```python
替代代码片段
counter = 1
temp_dest_path = dest_path
while os.path.exists(temp_dest_path):
name, ext = os.path.splitext(new_filename)
temp_dest_path = os.path.join(target_folder_path, f"{name}_{counter}{ext}")
counter += 1
shutil.move(src_path, temp_dest_path)
```