影刀RPA办公自动化实战:Word文档批量生成与智能处理
作者:林焱
标签: 影刀RPA、Word自动化、文档批量生成、办公自动化、Python-docx
适合读者: HR、行政、销售等需要批量生成Word文档的职场人士
为什么你需要Word自动化?
每逢月末或季度末,很多职场人都要面对同一个噩梦:
- 为100+员工分别生成工资条(每人一个文档)
- 批量生成格式统一但内容各异的合同/协议
- 将Excel数据填入Word模板,生成100份报告
- 批量修改公司名称(因为公司改名了)
这些工作如果手工操作,一天都未必能做完,且极易出错。
影刀RPA + python-docx库可以将这些工作压缩到几分钟!
第一章:环境准备
安装python-docx
# 在影刀RPA的Python环境中安装
pip install python-docx
# 如果网速慢,使用国内镜像
[video(video-xF1OUb7c-1782425355929)(type-csdn)(url-https://live.csdn.net/v/embed/525010)(image-https://v-blog.csdnimg.cn/asset/f4faa587144cb7070f19e8b36813806b/cover/Cover0.jpg)(title-店群矩阵自动化突破运营极限!)]
pip install python-docx -i https://pypi.tuna.tsinghua.edu.cn/simple
快速验证安装
from docx import Document
from docx.shared import Pt, RGBColor, Inches, Cm
# 创建一个测试文档
doc = Document()


doc.add_paragraph("安装成功!影刀RPA + python-docx 已就绪")
doc.save("C:/test_word.docx")
print("✅ python-docx安装正常")
第二章:Word文档基础操作
2.1 创建文档与添加内容
from docx import Document
from docx.shared import Pt, RGBColor, Inches, Cm
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.enum.table import WD_TABLE_ALIGNMENT
from docx.oxml.ns import qn
def create_basic_document():
"""创建包含基本元素的Word文档"""
doc = Document()
# ① 设置页面边距(A4纸,上下左右2.5cm)
from docx.oxml import OxmlElement
section = doc.sections[0]
section.top_margin = Cm(2.5)
section.bottom_margin = Cm(2.5)
section.left_margin = Cm(2.5)
section.right_margin = Cm(2.5)
# ② 添加标题(使用内置样式)
doc.add_heading("员工绩效评估报告", level=1)
doc.add_heading("第一季度综合评估", level=2)
# ③ 添加正文段落
para = doc.add_paragraph()
para.add_run("评估期间:").bold = True
para.add_run("2024年1月1日 - 2024年3月31日")
# ④ 添加带格式的段落
para2 = doc.add_paragraph()
run = para2.add_run("本报告为机密文件,请妥善保管。")
run.font.color.rgb = RGBColor(0xFF, 0x00, 0x00) # 红色字体
run.font.size = Pt(10)
run.italic = True
para2.alignment = WD_ALIGN_PARAGRAPH.CENTER
# ⑤ 添加无序列表
doc.add_paragraph("工作饱和度", style="List Bullet")
doc.add_paragraph("工作质量", style="List Bullet")
doc.add_paragraph("团队协作", style="List Bullet")
# ⑥ 添加有序列表
doc.add_paragraph("收集数据", style="List Number")
doc.add_paragraph("分析评估", style="List Number")
doc.add_paragraph("提交报告", style="List Number")
return doc
2.2 插入表格
def add_performance_table(doc: Document, data: list) -> None:
"""
在文档中插入绩效数据表格
Args:
doc: Document对象
data: 员工绩效数据列表,每项为字典
"""
# 表头定义
headers = ["姓名", "部门", "岗位", "综合得分", "等级", "备注"]
# 创建表格(行数 = 标题行 + 数据行)
table = doc.add_table(rows=1 + len(data), cols=len(headers))
table.style = "Table Grid" # 使用带框线的样式
# ① 填写表头行
header_row = table.rows[0]
for i, header in enumerate(headers):
cell = header_row.cells[i]
cell.text = header
# 设置表头格式
run = cell.paragraphs[0].runs[0]
run.font.bold = True
run.font.size = Pt(11)
# 设置表头背景色(灰色)
set_cell_background(cell, "D3D3D3")
# ② 填写数据行
for row_idx, employee in enumerate(data, start=1):
row = table.rows[row_idx]
values = [
employee.get("name", ""),
employee.get("department", ""),
employee.get("position", ""),
str(employee.get("score", "")),
employee.get("grade", ""),
employee.get("remarks", "")
]
for col_idx, value in enumerate(values):
cell = row.cells[col_idx]
cell.text = value
# 根据等级设置行颜色
if employee.get("grade") == "优秀":
set_cell_background(cell, "E8F5E9") # 浅绿
elif employee.get("grade") == "不合格":
set_cell_background(cell, "FFEBEE") # 浅红
# ③ 设置列宽(单位:Cm)
col_widths = [2.5, 2.5, 2.5, 2.0, 1.5, 4.0]
for col_idx, width in enumerate(col_widths):
for row in table.rows:
row.cells[col_idx].width = Cm(width)
def set_cell_background(cell, color_hex: str):
"""设置单元格背景色"""
from docx.oxml import OxmlElement
from docx.oxml.ns import qn
tc_pr = cell._tc.get_or_add_tcPr()
shd = OxmlElement("w:shd")
shd.set(qn("w:fill"), color_hex)
shd.set(qn("w:val"), "clear")
tc_pr.append(shd)
2.3 插入图片与图表
def insert_chart_screenshot(doc: Document, chart_image_path: str,
caption: str, width_cm: float = 14):
"""插入图表截图(先用matplotlib生成图表,再插入Word)"""
# 添加图片
doc.add_picture(chart_image_path, width=Cm(width_cm))
# 居中图片
last_para = doc.paragraphs[-1]
last_para.alignment = WD_ALIGN_PARAGRAPH.CENTER
# 添加图注
caption_para = doc.add_paragraph(caption)
caption_para.alignment = WD_ALIGN_PARAGRAPH.CENTER
caption_run = caption_para.runs[0]
caption_run.font.size = Pt(10)
caption_run.font.color.rgb = RGBColor(0x66, 0x66, 0x66)
caption_run.italic = True
# 先用matplotlib生成图表,再插入Word
def generate_chart_and_insert(doc: Document, data: dict, title: str):
"""生成柱状图并插入文档"""
import matplotlib.pyplot as plt
import matplotlib
matplotlib.use("Agg") # 非交互模式
matplotlib.rcParams["font.family"] = ["SimHei"] # 中文字体
# 生成图表
fig, ax = plt.subplots(figsize=(10, 5))
ax.bar(data.keys(), data.values(), color="#4A90E2", alpha=0.8)
ax.set_title(title, fontsize=14, fontweight="bold")
ax.set_ylabel("金额(万元)")
plt.xticks(rotation=30)
plt.tight_layout()
# 保存为临时图片
temp_path = "C:/temp/chart_temp.png"
plt.savefig(temp_path, dpi=150, bbox_inches="tight")
plt.close()
# 插入到Word
insert_chart_screenshot(doc, temp_path, f"图:{title}")
# 清理临时文件
import os
os.remove(temp_path)
第三章:批量生成文档的核心技术
3.1 模板替换法(最实用)
先在Word中制作好模板,用{{变量名}}标记需要替换的位置,然后用代码批量填入数据。
模板示例内容(template.docx):
{{公司名称}} 劳动合同
甲方(用人单位):{{公司名称}}
法定代表人:{{法人姓名}}
乙方(劳动者):{{员工姓名}}
身份证号码:{{身份证号}}
岗位:{{岗位名称}}
月薪:{{月薪}}元
入职日期:{{入职日期}}
批量填充代码:
from docx import Document
import copy
import re
import os
def replace_in_paragraph(paragraph, replacements: dict):
"""在段落中替换占位符(保持原有格式)"""
# 先获取完整文本检查是否有占位符
full_text = "".join([run.text for run in paragraph.runs])
has_placeholder = any(f"{{{{{key}}}}}" in full_text for key in replacements)
if not has_placeholder:
return
# 重建run,将占位符替换
for run in paragraph.runs:
for key, value in replacements.items():
placeholder = f"{{{{{key}}}}}"
if placeholder in run.text:
run.text = run.text.replace(placeholder, str(value))
def replace_in_table(table, replacements: dict):
"""在表格中替换占位符"""
for row in table.rows:
for cell in row.cells:
for paragraph in cell.paragraphs:
replace_in_paragraph(paragraph, replacements)
def fill_template(template_path: str, output_path: str, data: dict) -> bool:
"""
用数据填充Word模板
Args:
template_path: 模板文件路径
output_path: 输出文件路径
data: 替换数据字典,key为占位符名(不含{}),value为替换值
Returns:
bool: 是否成功
"""
try:
doc = Document(template_path)
# 处理正文段落
for paragraph in doc.paragraphs:
replace_in_paragraph(paragraph, data)
# 处理表格中的内容
for table in doc.tables:
replace_in_table(table, data)
# 处理页眉页脚(如果有的话)
for section in doc.sections:
for paragraph in section.header.paragraphs:
replace_in_paragraph(paragraph, data)
for paragraph in section.footer.paragraphs:
replace_in_paragraph(paragraph, data)
# 保存输出文件
os.makedirs(os.path.dirname(output_path), exist_ok=True)
doc.save(output_path)
return True
except Exception as e:
print(f"❌ 生成文档失败:{output_path},错误:{e}")
return False
def batch_generate_contracts(template_path: str, employee_data: list, output_dir: str):
"""
批量生成员工劳动合同
Args:
template_path: 合同模板路径
employee_data: 员工数据列表(从Excel读取)
output_dir: 输出目录
"""
total = len(employee_data)
success_count = 0
fail_list = []
print(f"📄 开始批量生成合同,共 {total} 份...")
for i, emp in enumerate(employee_data, 1):
# 构建文件名(使用姓名+身份证后4位,避免重名)
id_suffix = str(emp.get("身份证号", "0000"))[-4:]
filename = f"{emp.get('员工姓名', f'员工{i}')}_{id_suffix}_劳动合同.docx"
output_path = os.path.join(output_dir, filename)
# 执行模板填充
success = fill_template(template_path, output_path, emp)
if success:
success_count += 1
print(f" [{i}/{total}] ✅ {filename}")
else:
fail_list.append(emp.get("员工姓名", f"第{i}位"))
# 打印摘要
print(f"\n📊 批量生成完成!")
print(f" ✅ 成功:{success_count} 份")
print(f" ❌ 失败:{len(fail_list)} 份")
if fail_list:
print(f" 失败员工:{', '.join(fail_list)}")
print(f" 📁 输出目录:{output_dir}")
第四章:从Excel读取数据批量生成
4.1 完整的Excel → Word流水线
import pandas as pd
from docx import Document
import os
def excel_to_word_reports(excel_path: str, template_path: str, output_dir: str):
"""
从Excel读取数据,批量生成Word报告
Excel格式要求(必须有以下列):
- 员工姓名 / 部门 / 岗位 / 入职日期
- Q1得分 / Q2得分 / Q3得分 / Q4得分
- 综合评级 / 评估人 / 评估日期
"""
# 读取Excel数据
df = pd.read_excel(excel_path, sheet_name="绩效数据")
print(f"📊 从Excel读取到 {len(df)} 条员工数据")
# 数据清洗
df = df.dropna(subset=["员工姓名"])
df["入职日期"] = pd.to_datetime(df["入职日期"]).dt.strftime("%Y年%m月%d日")
df["评估日期"] = pd.to_datetime(df["评估日期"]).dt.strftime("%Y年%m月%d日")
# 计算综合得分
score_cols = ["Q1得分", "Q2得分", "Q3得分", "Q4得分"]
df["综合得分"] = df[score_cols].mean(axis=1).round(1)
# 确定等级
def get_grade(score):
if score >= 90: return "优秀"
if score >= 75: return "良好"
if score >= 60: return "合格"
return "待改进"
df["等级"] = df["综合得分"].apply(get_grade)
# 批量生成
os.makedirs(output_dir, exist_ok=True)
results = []
for _, row in df.iterrows():
data = row.to_dict()
filename = f"{data['员工姓名']}_{data['部门']}_绩效报告.docx"
output_path = os.path.join(output_dir, filename)
success = fill_template(template_path, output_path, data)
results.append({
"员工姓名": data["员工姓名"],
"等级": data["等级"],
"文件": filename,
"状态": "✅成功" if success else "❌失败"
})
# 生成汇总报表
summary_df = pd.DataFrame(results)
summary_path = os.path.join(output_dir, "生成汇总.xlsx")
summary_df.to_excel(summary_path, index=False)
success_rate = sum(1 for r in results if "成功" in r["状态"]) / len(results)
print(f"\n🎉 全部完成!成功率:{success_rate:.1%}")
print(f" 汇总报表:{summary_path}")
return results
第五章:批量修改现有Word文档
[video(video-ahMCRalt-1782425362768)(type-csdn)(url-live.csdn.net/v/embed/524…)]
5.1 全局查找替换
def batch_replace_in_folder(folder_path: str, old_text: str, new_text: str):
"""
批量替换文件夹中所有Word文档的指定文字
适用场景:公司改名、地址变更等
"""
import glob
doc_files = glob.glob(os.path.join(folder_path, "**/*.docx"), recursive=True)
print(f"🔍 找到 {len(doc_files)} 个Word文档")
modified_count = 0
for doc_path in doc_files:
doc = Document(doc_path)
modified = False
# 替换段落中的文字
for para in doc.paragraphs:
for run in para.runs:
if old_text in run.text:
run.text = run.text.replace(old_text, new_text)
modified = True
# 替换表格中的文字
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:
if old_text in run.text:
run.text = run.text.replace(old_text, new_text)
modified = True
if modified:
doc.save(doc_path)
modified_count += 1
print(f" ✅ 已修改:{os.path.basename(doc_path)}")
print(f"\n完成!共修改 {modified_count} 个文档")
第六章:实战案例:HR薪资通知单批量生成系统
import pandas as pd
from docx import Document
from docx.shared import Pt, Cm
from docx.enum.text import WD_ALIGN_PARAGRAPH
import os
import datetime
def generate_salary_notice(emp_data: dict, output_dir: str) -> str:
"""
生成单份工资通知单
Returns:
str: 生成的文件路径
"""
doc = Document()
# 页面设置
section = doc.sections[0]
section.page_width = Cm(21)
section.page_height = Cm(29.7)
section.top_margin = Cm(2)
section.bottom_margin = Cm(2)
section.left_margin = Cm(2.5)
section.right_margin = Cm(2.5)
# 标题
title = doc.add_paragraph()
title.alignment = WD_ALIGN_PARAGRAPH.CENTER
title_run = title.add_run("薪资明细通知单")
title_run.font.size = Pt(16)
title_run.font.bold = True
# 基本信息
doc.add_paragraph() # 空行
info_table = doc.add_table(rows=2, cols=4)
info_data = [
["姓名", emp_data.get("姓名", ""), "部门", emp_data.get("部门", "")],
["岗位", emp_data.get("岗位", ""), "发薪月份", emp_data.get("月份", "")]
]
for row_idx, row_data in enumerate(info_data):
row = info_table.rows[row_idx]
for col_idx, value in enumerate(row_data):
cell = row.cells[col_idx]
cell.text = value
run = cell.paragraphs[0].runs[0] if cell.paragraphs[0].runs else cell.paragraphs[0].add_run(value)
if col_idx % 2 == 0: # 标签列加粗
run.font.bold = True
doc.add_paragraph()
# 薪资明细表
salary_items = [
("应发项目", ""),
("基本工资", emp_data.get("基本工资", 0)),
("绩效奖金", emp_data.get("绩效奖金", 0)),
("加班费", emp_data.get("加班费", 0)),
("补贴合计", emp_data.get("补贴", 0)),
("应发合计", sum([
emp_data.get("基本工资", 0),
emp_data.get("绩效奖金", 0),
emp_data.get("加班费", 0),
emp_data.get("补贴", 0)
])),
("扣除项目", ""),
("个人社保", emp_data.get("个人社保", 0)),
("个人公积金", emp_data.get("个人公积金", 0)),
("个税", emp_data.get("个税", 0)),
("其他扣除", emp_data.get("其他扣除", 0)),
("扣除合计", sum([
emp_data.get("个人社保", 0),
emp_data.get("个人公积金", 0),
emp_data.get("个税", 0),
emp_data.get("其他扣除", 0)
])),
("实发工资", ""),
]
# 计算实发工资
yingfa = sum([emp_data.get(k, 0) for k in ["基本工资", "绩效奖金", "加班费", "补贴"]])
koukong = sum([emp_data.get(k, 0) for k in ["个人社保", "个人公积金", "个税", "其他扣除"]])
shifa = yingfa - koukong
salary_items[-1] = ("实发工资", shifa)
salary_table = doc.add_table(rows=len(salary_items), cols=2)
salary_table.style = "Table Grid"
for row_idx, (item_name, item_value) in enumerate(salary_items):
row = salary_table.rows[row_idx]
# 项目名称
row.cells[0].text = item_name
name_run = row.cells[0].paragraphs[0].runs[0]
# 金额
if isinstance(item_value, (int, float)):
row.cells[1].text = f"¥{item_value:,.2f}"
else:
row.cells[1].text = str(item_value)
# 特殊行样式
if item_name in ["应发项目", "扣除项目"]:
name_run.font.bold = True
set_cell_background(row.cells[0], "E3F2FD")
set_cell_background(row.cells[1], "E3F2FD")
elif item_name in ["应发合计", "扣除合计"]:
name_run.font.bold = True
elif item_name == "实发工资":
name_run.font.bold = True
name_run.font.size = Pt(13)
amount_run = row.cells[1].paragraphs[0].runs[0]
amount_run.font.bold = True
amount_run.font.size = Pt(13)
set_cell_background(row.cells[0], "FFF9C4")
set_cell_background(row.cells[1], "FFF9C4")
# 签名区域
doc.add_paragraph()
sig_para = doc.add_paragraph(
f"员工签字:____________ 财务确认:____________ 日期:{datetime.date.today().strftime('%Y年%m月%d日')}"
)
# 保存
filename = f"{emp_data.get('姓名', '员工')}_{emp_data.get('月份', '2024-01')}_薪资通知.docx"
output_path = os.path.join(output_dir, filename)
doc.save(output_path)
return output_path
# 批量生成入口
def batch_generate_salary_notices(excel_path: str, output_dir: str):
"""从Excel批量生成薪资通知单"""
df = pd.read_excel(excel_path)
os.makedirs(output_dir, exist_ok=True)
print(f"📄 开始批量生成薪资通知单,共 {len(df)} 份...")
for i, row in df.iterrows():
emp_data = row.to_dict()
output_path = generate_salary_notice(emp_data, output_dir)
print(f" [{i+1}/{len(df)}] ✅ {os.path.basename(output_path)}")
print(f"\n🎉 全部完成!文件保存在:{output_dir}")
# 运行示例
batch_generate_salary_notices(
excel_path="C:/HR/薪资数据2024-01.xlsx",
output_dir="C:/HR/薪资通知单/2024-01/"
)
总结
本文介绍了影刀RPA结合python-docx进行Word自动化的完整方案:
| 场景 | 推荐方案 | 难度 |
|---|---|---|
| 批量生成合同/通知 | 模板+占位符替换 | ★★ |
| 从Excel生成报告 | pandas读取+模板填充 | ★★★ |
| 批量查找替换 | 遍历文档+run替换 | ★★ |
| 生成带图表的报告 | matplotlib+docx插图 | ★★★★ | | 薪资通知单生成 | 代码全自动生成 | ★★★ |
python-docx + 影刀RPA,让Word批量操作从"痛苦的重复劳动"变成"一键搞定"的自动化流程!
作者:林焱 | 影刀RPA技术专栏 | 如果本文对你有帮助,欢迎点赞收藏!