影刀RPA办公自动化实战:Word文档批量生成与智能处理

0 阅读11分钟

影刀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()
![在这里插入图片描述](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/33d71256c9dd42a092df1bd01df84943~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5p6X54SxUlBB:q75.awebp?rk3s=f64ab15b&x-expires=1786183887&x-signature=oEmZtSibnRx2t6j2ZxyQERj4y9s%3D)
![在这里插入图片描述](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/f9cfc863fb6146da8eaad6864c1d2d21~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5p6X54SxUlBB:q75.awebp?rk3s=f64ab15b&x-expires=1786183887&x-signature=DrVh10fDLDQ6Nwp6hXNUnXPPIiY%3D)


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技术专栏 | 如果本文对你有帮助,欢迎点赞收藏! 在这里插入图片描述