夜雨聆风学习资料网

ARTICLE · 1081405

别再手动填 Excel 了!用 Python 自动填充模板,1 分钟搞定 100 份

别再手动填 Excel 了!用 Python 自动填充模板,1 分钟搞定 100 份

工资条、合同、报表、通知书……只要模板固定,Python 就能帮你批量生成。

今天分享一个非常实用的办公自动化技巧:用 Python 自动填充 Excel 模板,批量生成文件。

如果你经常遇到这些场景:

  • 每月给 100 个员工发工资条,一个个复制粘贴;

  • 给客户批量生成合同,只改姓名、金额、日期;

  • 给每个班级生成成绩单,模板一样,数据不同;

  • 手动改完还要另存为,文件名还不能错。

那这篇文章,建议你收藏。


一、整体思路

其实就三步:

  1. 准备一个 Excel 模板:固定不变的内容写好,变化的地方用占位符,比如 {{姓名}}、{{月份}}。

  2. 准备一个数据源 Excel:第一行是字段名,下面每行是一条数据。

  3. 用 Python 读取数据,替换占位符,批量保存。

我们需要的库只有一个:openpyxl。

安装命令:

pip install openpyxl

二、准备模板和数据

1. 模板文件:template.xlsx

比如工资条模板,内容如下:

单元格内容
B2工资条
B3姓名:{{姓名}}
D3月份:{{月份}}
B4部门:{{部门}}
B6基本工资:{{基本工资}}
D6奖金:{{奖金}}
F6合计:=C6+E6

其中 {{姓名}}、{{月份}} 这些就是占位符。

2. 数据源:data.xlsx

第一行是字段名,必须和占位符里的名字一致:

姓名部门月份基本工资奖金
张三技术部2025-0680002000
李四市场部2025-0670001500
王五财务部2025-0675001800

三、完整 Python 代码

新建一个 auto_fill.py,复制下面代码:

from pathlib import Pathimport openpyxlTEMPLATE = Path("template.xlsx")   # 模板文件DATA_FILE = Path("data.xlsx")      # 数据源OUTPUT_DIR = Path("output")        # 输出文件夹def replace_in_sheet(ws, data: dict):    """遍历工作表,替换所有 {{字段名}} 占位符"""    for row in ws.iter_rows():        for cell in row:            if not isinstance(cell.value, str):                continue            # 情况1:单元格内容就是一个占位符,直接赋值,保留数字/日期类型            if (                cell.value.startswith("{{")                and cell.value.endswith("}}")                and cell.value.count("{{") == 1            ):                key = cell.value[2:-2].strip()                if key in data:                    cell.value = data[key]                    continue            # 情况2:占位符混在文本里,做字符串替换            new_value = cell.value            for key, value in data.items():                placeholder = "{{" + key + "}}"                if placeholder in new_value:                    new_value = new_value.replace(placeholder, str(value))            cell.value = new_valuedef read_data():    """读取数据源,返回字典列表"""    wb = openpyxl.load_workbook(DATA_FILE, data_only=True)    ws = wb.active    rows = list(ws.iter_rows(values_only=True))    if not rows:        return []    headers = rows[0]    data_list = []    for row in rows[1:]:        if all(v is None for v in row):            continue        data_list.append(dict(zip(headers, row)))    return data_listdef safe_filename(name: str) -> str:    """去掉文件名中的非法字符"""    for ch in ['\\', '/', ':', '*', '?', '"', '<', '>', '|']:        name = name.replace(ch, "-")    return name.strip()def main():    OUTPUT_DIR.mkdir(exist_ok=True)    data_list = read_data()    for i, data in enumerate(data_list, start=1):        wb = openpyxl.load_workbook(TEMPLATE)        # 如果模板有多个工作表,全部替换        for ws in wb.worksheets:            replace_in_sheet(ws, data)        # 生成文件名,例如:张三_2025-06.xlsx        name = str(data.get("姓名", f"第{i}份"))        month = str(data.get("月份", ""))        filename = safe_filename(f"{name}_{month}.xlsx")        wb.save(OUTPUT_DIR / filename)        print(f"已生成:{filename}")if __name__ == "__main__":    main()
运行:
python auto_fill.py
运行后,output 文件夹里就会自动生成:
张三_2025-06.xlsx李四_2025-06.xlsx王五_2025-06.xlsx

每个文件都保留了你模板里的格式、公式、颜色、边框。


四、几个关键点

1. 占位符命名要统一

模板里写 {{姓名}},数据源表头也必须是 姓名。

建议不要带空格,比如 {{ 姓名 }} 容易匹配失败。

2. 数字类型会保留

代码里做了一个判断:

如果单元格内容只有一个占位符,比如 {{基本工资}},就直接把 Python 里的数字赋进去,不会变成文本。

如果占位符混在文本里,比如 姓名:{{姓名}},那结果就是字符串,这是正常的。

3. 公式不会被 openpyxl 计算

模板里的公式,比如 =C6+E6,openpyxl 保存后公式还在,但不会自动算出结果。

用 Excel 打开文件时,它会自动计算。

如果你希望生成后立即有值,可以用 xlwings 调用 Excel 计算。

4. 复杂模板建议用 xlwings

openpyxl 适合大多数普通表格,但它对图片、图表、宏、透视表的支持有限。

如果你的模板里有:

  • 公司 Logo 图片

  • 图表

  • 宏

  • 复杂条件格式

建议用 xlwings:

import xlwings as xwapp = xw.App(visible=False, add_book=False)wb = app.books.open("template.xlsx")sht = wb.sheets["工资条"]sht.range("B3").value = "张三"sht.range("D3").value = "2025-06"wb.save("output/张三.xlsx")wb.close()app.quit()

xlwings 会真正调用 Excel,所以格式、图片、公式都能保留,但电脑上必须安装 Excel。


五、还能怎么升级?

学会这个脚本后,你可以继续扩展:

  • 用 schedule 每天定时生成日报;

  • 用 PyQt 做一个简单界面,让同事自己点按钮;

  • 用 PyInstaller 打包成 .exe,发给不会 Python 的同事;

  • 把数据源换成数据库,每天自动拉取;

  • 生成 PDF:用 xlwings 打开后另存为 PDF。


六、总结

核心就一句话:

模板里放占位符,数据源里放数据,Python 负责批量替换和保存。

以前手动改 100 份需要一上午,现在代码跑一遍,几十秒搞定,还不容易出错。

相关学习资料