Python从入门到实战 (13):自动化办公:用 Python 批量处理 Excel、Word 与 PDF
在日常工作中,我们经常要做重复的办公任务:批量处理几十份Excel表格、批量生成合同、从PDF中提取数据……这些工作耗时且容易出错。而Python能帮我们实现“自动化办公”——用代码批量处理Excel、Word和PDF,把1小时的工作缩短到1分钟。这篇我们就聚焦三个核心场景:批量处理Excel数据、自动生成Word文档、提取PDF内容并汇总,每个场景都提供可直接复用的代码,让你快速上手提升工作效率。
一、准备工作:安装办公自动化库
需要安装3类处理不同文件的库(打开终端/命令提示符执行):
# 处理Excel(pandas/openpyxl:读写.xlsx文件)
# 处理Word(python-docx:读写.docx文件)
# 处理PDF(PyPDF2:合并/分割PDF;pdfplumber:提取PDF文本和表格)
pip install pandas openpyxl python-docx PyPDF2 pdfplumber
二、场景1:批量处理Excel数据(最常用!)
Excel是办公高频工具,我们以“批量计算销售业绩+标记达标人员”为例,学习用pandas(数据处理)和openpyxl(写入Excel)处理表格。
需求说明
假设有“销售数据.xlsx”,包含3列:姓名、销售额、目标额,需要:
- 计算每个人的完成率(销售额/目标额);
- 标记完成率≥100%的人员为“达标”,否则为“未达标”;
- 按完成率从高到低排序;
- 保存到新文件“销售业绩分析.xlsx”。
示例数据(销售数据.xlsx)
| 姓名 | 销售额(元) | 目标额(元) |
|---|---|---|
| 张三 | 12000 | 10000 |
| 李四 | 8000 | 10000 |
| 王五 | 15000 | 12000 |
| 赵六 | 9500 | 9000 |
代码实现
import pandas as pd
import logging
from openpyxl.styles import Font, Alignment # 用于设置Excel单元格样式
# 配置日志
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s"
)
def process_sales_data(input_file, output_file):
"""
批量处理销售数据Excel,计算完成率并标记达标情况
参数:
input_file:输入Excel文件路径(如"销售数据.xlsx")
output_file:输出Excel文件路径(如"销售业绩分析.xlsx")
返回:处理成功返回True,失败返回False
"""
try:
logging.info(f"开始处理Excel文件:{input_file}")
# 1. 读取Excel数据(pandas的read_excel支持.xlsx格式)
# sheet_name:指定工作表名称(默认第一个);header=0:第一行为表头
df = pd.read_excel(input_file, sheet_name="Sheet1", header=0)
# 检查必要的列是否存在
required_columns = ["姓名", "销售额(元)", "目标额(元)"]
if not all(col in df.columns for col in required_columns):
logging.error(f"Excel文件缺少必要的列,需要:{required_columns}")
print(f"❌ 错误:Excel文件必须包含列:{required_columns}")
return False
# 2. 批量计算完成率(销售额/目标额,保留2位小数)
# 避免除以0错误:若目标额为0,完成率设为0
df["完成率(%)"] = df.apply(
lambda row: round(row["销售额(元)"] / row["目标额(元)"] * 100, 2)
if row["目标额(元)"] != 0 else 0,
axis=1 # axis=1表示按行处理
)
# 3. 标记达标情况(完成率≥100%为达标)
df["达标情况"] = df["完成率(%)"].apply(lambda x: "达标" if x >= 100 else "未达标")
# 4. 按完成率从高到低排序(降序)
df = df.sort_values(by="完成率(%)", ascending=False).reset_index(drop=True)
# 5. 保存到新Excel(用openpyxl引擎支持后续样式设置)
with pd.ExcelWriter(output_file, engine="openpyxl") as writer:
df.to_excel(writer, sheet_name="业绩分析", index=False) # index=False:不保存行索引
# 6. 美化表格(设置表头样式:加粗、居中)
worksheet = writer.sheets["业绩分析"] # 获取工作表对象
header_font = Font(bold=True, color="000000") # 表头字体:加粗、黑色
header_alignment = Alignment(horizontal="center", vertical="center") # 居中对齐
# 遍历表头单元格(第一行),应用样式
for cell in worksheet[1]: # worksheet[1]表示第一行(Excel行号从1开始)
cell.font = header_font
cell.alignment = header_alignment
# 调整列宽(根据内容自动调整)
for column in worksheet.columns:
max_length = 0
column_letter = column[0].column_letter # 获取列字母(如A、B)
for cell in column:
try:
if len(str(cell.value)) > max_length:
max_length = len(cell.value)
except:
pass
adjusted_width = (max_length + 2) * 1.2 # 适当加宽
worksheet.column_dimensions[column_letter].width = adjusted_width
logging.info(f"Excel处理完成,已保存到:{output_file}")
print(f"\n✅ 处理成功!生成文件:{output_file}")
print(f" 共处理{len(df)}条数据,达标{len(df[df['达标情况']=='达标'])}人,未达标{len(df[df['达标情况']=='未达标'])}人")
return True
except FileNotFoundError:
logging.error(f"输入文件不存在:{input_file}")
print(f"❌ 错误:文件{input_file}不存在,请检查路径!")
return False
except Exception as e:
logging.error(f"Excel处理错误:{e}", exc_info=True)
print(f"❌ 处理失败:{e},请查看日志获取详情")
return False
# 执行处理(替换为你的文件路径)
if __name__ == "__main__":
process_sales_data(
input_file="销售数据.xlsx",
output_file="销售业绩分析.xlsx"
)
运行效果
生成的“销售业绩分析.xlsx”会新增“完成率(%)”和“达标情况”列,表头加粗居中,列宽自动适配内容,无需手动调整格式。
三、场景2:自动生成Word文档(批量出合同/报告)
很多工作需要生成大量格式相同、内容略有差异的Word文档(如合同、通知书)。我们以“批量生成员工工资条”为例,用python-docx实现:先制作模板,再替换模板中的占位符,生成个性化文档。
步骤1:制作Word模板(工资条模板.docx)
新建一个Word文档,用{{占位符}}标记需要替换的内容,例如:
工资条
姓名:{{姓名}}
部门:{{部门}}
职位:{{职位}}
基本工资:{{基本工资}}元
绩效工资:{{绩效工资}}元
应发合计:{{应发合计}}元
发放日期:{{发放日期}}
—— 人力资源部 ——
保存为“工资条模板.docx”,放在项目文件夹中。
步骤2:准备数据(员工信息.xlsx)
用Excel存储需要替换的内容,格式如下:
| 姓名 | 部门 | 职位 | 基本工资 | 绩效工资 |
|---|---|---|---|---|
| 张三 | 技术部 | 开发工程师 | 8000 | 2000 |
| 李四 | 市场部 | 专员 | 6000 | 1500 |
| 王五 | 财务部 | 会计 | 7000 | 1000 |
步骤3:代码实现(批量生成工资条)
import docx
from docx.shared import Pt, RGBColor # 用于设置字体样式
from docx.enum.text import WD_ALIGN_PARAGRAPH # 用于设置段落对齐
import pandas as pd
import os
from datetime import datetime
def generate_word_from_template(template_path, data, output_dir="工资条"):
"""
根据Word模板和数据,批量生成个性化Word文档
参数:
template_path:模板文件路径(如"工资条模板.docx")
data:包含替换数据的列表(每个元素为字典,键是占位符,值是替换内容)
output_dir:生成文件的保存目录(默认"工资条")
"""
try:
# 创建输出目录(若不存在)
if not os.path.exists(output_dir):
os.makedirs(output_dir)
logging.info(f"创建输出目录:{output_dir}")
# 获取当前日期(作为发放日期)
pay_date = datetime.now().strftime("%Y年%m月%d日")
# 循环处理每条数据,生成对应的Word文档
for idx, item in enumerate(data, 1):
# 1. 打开模板文件
doc = docx.Document(template_path)
# 2. 替换所有占位符(遍历文档中的所有段落和表格)
# 2.1 处理段落中的占位符
for para in doc.paragraphs:
for run in para.runs: # run是段落中的文本片段
# 遍历所有需要替换的占位符
for key, value in item.items():
placeholder = f"{{{{{key}}}}}" # 构建占位符(如{{姓名}})
if placeholder in run.text:
# 替换文本
run.text = run.text.replace(placeholder, str(value))
# 设置字体样式(可选:统一字体为微软雅黑,大小10.5pt)
run.font.name = "微软雅黑"
run.font.size = Pt(10.5)
# 2.2 处理表格中的占位符(如果模板有表格)
for table in doc.tables:
for row in table.rows:
for cell in row.cells:
for para in cell.paragraphs:
for run in para.runs:
for key, value in item.items():
placeholder = f"{{{{{key}}}}}"
if placeholder in run.text:
run.text = run.text.replace(placeholder, str(value))
run.font.name = "微软雅黑"
run.font.size = Pt(10.5)
# 3. 替换发放日期(单独处理,所有文档日期相同)
for para in doc.paragraphs:
for run in para.runs:
if "{{发放日期}}" in run.text:
run.text = run.text.replace("{{发放日期}}", pay_date)
run.font.name = "微软雅黑"
# 4. 计算应发合计(基本工资+绩效工资)
for para in doc.paragraphs:
for run in para.runs:
if "{{应发合计}}" in run.text:
total = item["基本工资"] + item["绩效工资"]
run.text = run.text.replace("{{应发合计}}", str(total))
run.font.name = "微软雅黑"
run.font.bold = True # 应发合计加粗
run.font.color.rgb = RGBColor(192, 0, 0) # 红色
# 5. 设置标题居中(第一个段落是标题“工资条”)
doc.paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.CENTER
doc.paragraphs[0].runs[0].font.size = Pt(14) # 标题字号加大
doc.paragraphs[0].runs[0].font.bold = True # 标题加粗
# 6. 保存生成的文档(文件名:姓名_工资条.docx)
output_filename = f"{item['姓名']}_工资条.docx"
output_path = os.path.join(output_dir, output_filename)
doc.save(output_path)
logging.info(f"生成第{idx}个文档:{output_path}")
print(f"\n✅ 批量生成完成!共生成{len(data)}个Word文档")
print(f" 保存路径:{os.path.abspath(output_dir)}")
return True
except FileNotFoundError:
logging.error(f"模板文件不存在:{template_path}")
print(f"❌ 错误:模板文件{template_path}不存在!")
return False
except Exception as e:
logging.error(f"生成Word文档错误:{e}", exc_info=True)
print(f"❌ 生成失败:{e}")
return False
# 完整流程:读取Excel数据→生成工资条
if __name__ == "__main__":
# 1. 读取员工数据Excel
excel_path = "员工信息.xlsx"
try:
df = pd.read_excel(excel_path)
# 转换为字典列表(每个字典对应一条员工信息)
employee_data = df.to_dict("records")
logging.info(f"成功读取{len(employee_data)}条员工数据")
except Exception as e:
logging.error(f"读取员工数据失败:{e}")
print(f"❌ 读取员工数据失败:{e}")
exit(1)
# 2. 批量生成工资条
generate_word_from_template(
template_path="工资条模板.docx",
data=employee_data,
output_dir="2024年6月工资条"
)
运行效果
在“2024年6月工资条”文件夹中,会生成每个人的工资条文档,格式统一,姓名、部门等信息自动替换,应发合计自动计算并标红加粗,无需手动修改。
四、场景3:提取PDF内容(文字+表格)并汇总到Excel
PDF是办公中常用的格式,但直接编辑困难。我们以“提取多份PDF简历中的姓名、电话、工作经历”为例,用pdfplumber提取内容,再用pandas汇总到Excel。
代码实现(PDF内容提取)
import pdfplumber
import pandas as pd
import os
import re # 用于正则表达式匹配(提取电话等)
def extract_pdf_info(pdf_path):
"""
从单份PDF简历中提取关键信息
参数:pdf_path - PDF文件路径
返回:包含关键信息的字典
"""
info = {
"文件名": os.path.basename(pdf_path),
"姓名": "未找到",
"电话": "未找到",
"工作经历": "未找到"
}
try:
with pdfplumber.open(pdf_path) as pdf:
# 1. 提取所有页的文本(合并为一个字符串)
full_text = ""
for page in pdf.pages:
page_text = page.extract_text() # 提取单页文本
if page_text:
full_text += page_text + "\n" # 页间加换行
# 2. 提取姓名(假设姓名在"个人简历"或"简历"附近,且是2-4个汉字)
name_pattern = re.compile(r"[简历|个人简历]\s*([\u4e00-\u9fa5]{2,4})")
name_match = name_pattern.search(full_text)
if name_match:
info["姓名"] = name_match.group(1).strip()
# 3. 提取电话(11位手机号)
phone_pattern = re.compile(r"1[3-9]\d{9}")
phone_match = phone_pattern.search(full_text)
if phone_match:
info["电话"] = phone_match.group()
# 4. 提取工作经历(包含"工作经历"或"工作经验"后的内容,取前500字)
experience_pattern = re.compile(r"(工作经历|工作经验)\s*(.*?)(教育背景|项目经验|技能证书)", re.DOTALL)
experience_match = experience_pattern.search(full_text)
if experience_match:
experience = experience_match.group(2).strip()
info["工作经历"] = experience[:500] # 限制长度,避免内容过长
logging.info(f"成功提取PDF信息:{info['文件名']}(姓名:{info['姓名']})")
return info
except Exception as e:
logging.error(f"提取PDF {pdf_path} 失败:{e}")
print(f"⚠️ 提取{os.path.basename(pdf_path)}失败:{e}")
return info
def batch_extract_pdfs(pdf_dir, output_excel="简历信息汇总.xlsx"):
"""
批量提取指定目录下所有PDF的信息,汇总到Excel
参数:
pdf_dir:存放PDF的目录
output_excel:汇总结果的Excel路径
"""
# 1. 获取目录下所有PDF文件
pdf_files = []
for filename in os.listdir(pdf_dir):
if filename.lower().endswith(".pdf"):
pdf_path = os.path.join(pdf_dir, filename)
pdf_files.append(pdf_path)
if not pdf_files:
logging.warning(f"目录{pdf_dir}下未找到PDF文件")
print(f"⚠️ 未在{pdf_dir}找到任何PDF文件!")
return False
logging.info(f"发现{len(pdf_files)}个PDF文件,开始批量提取")
# 2. 批量提取每个PDF的信息
all_info = []
for pdf_path in pdf_files:
info = extract_pdf_info(pdf_path)
all_info.append(info)
# 3. 保存到Excel
df = pd.DataFrame(all_info)
df.to_excel(output_excel, index=False, engine="openpyxl")
logging.info(f"PDF信息汇总完成,保存到:{output_excel}")
print(f"\n✅ 批量提取完成!共处理{len(pdf_files)}个PDF")
print(f" 汇总结果:{output_excel}")
return True
# 执行批量提取(替换为你的PDF目录)
if __name__ == "__main__":
batch_extract_pdfs(
pdf_dir="简历文件夹", # 存放PDF简历的文件夹
output_excel="简历信息汇总.xlsx"
)
运行效果
程序会扫描“简历文件夹”中的所有PDF,提取姓名、电话、工作经历,汇总到“简历信息汇总.xlsx”,无需逐个打开PDF复制粘贴,尤其适合处理几十上百份简历的场景。
五、自动化办公实用技巧
- 文件路径处理:用
os.path模块处理路径(如os.path.join拼接路径、os.path.exists检查文件是否存在),避免因Windows/Linux路径格式差异导致错误。 - 异常处理:办公文件常出现格式错误(如损坏的Excel、加密的PDF),务必用
try-except捕获异常,避免程序崩溃。 - 批量操作逻辑:批量处理的核心是“循环+函数”——用函数封装单个文件的处理逻辑,用循环遍历所有文件,代码更清晰。
- 格式简化:复杂的Excel/Word格式(如宏、复杂图表)可能导致处理失败,尽量用简单格式(纯文本、基础表格)。
总结
这篇我们掌握了办公自动化的核心技能,覆盖Excel、Word、PDF三大场景:
- Excel处理:用
pandas批量计算、筛选、排序数据,openpyxl美化格式; - Word生成:通过“模板+占位符”模式,用
python-docx批量生成个性化文档; - PDF提取:用
pdfplumber提取文本和表格,正则表达式匹配关键信息。
这些技能能直接应用于实际工作,解决“重复劳动”痛点。下一篇我们将学习“Python小工具开发”,把这些功能打包成可双击运行的程序,甚至分享给不懂代码的同事使用!
更多推荐


所有评论(0)