手把手教你用Python实现自定义档案模板生成系统

前言

在企业的日常运营中,员工档案、合同、证件制作等需求通常需要将结构化数据填充到固定格式的文档中。市面上通用的OA系统往往难以满足灵活多变的排版需求。本文将提供一套完全开源、零成本的解决方案,利用Python的docxtpl库,基于Word模板实现高度自定义的档案批量生成。读者只需具备基础的计算机操作能力,即可按照本文步骤搭建一套专属的档案生成工具。

一、环境准备与依赖安装

本方案基于Python开发,首先需要配置运行环境。请严格按照以下步骤操作,确保环境一致性。

1. 安装Python环境

如果电脑中尚未安装Python,请访问Python官方发布页下载安装包。不要使用第三方打包版本,以免依赖库缺失。

下载地址: https://www.python.org/downloads/

下载对应操作系统的安装包(推荐Python 3.9及以上版本)。运行安装程序时,务必勾选底部的 "Add Python to PATH" 选项,这将允许我们在命令行中直接调用Python。安装模式选择 "Install Now" 即可。

2. 安装核心依赖库

打开终端(Windows下按Win+R,输入cmd回车),依次执行以下命令安装所需的第三方库。我们需要python-docx-template(用于处理Word模板)和Pillow(用于处理图片)。

在命令行中输入:

```bash pip install docxtpl pip install Pillow ```

如果下载速度较慢,建议使用国内镜像源:

```bash pip install docxtpl -i https://pypi.tuna.tsinghua.edu.cn/simple pip install Pillow -i https://pypi.tuna.tsinghua.edu.cn/simple ```

出现 "Successfully installed..." 提示即表示安装成功。

二、设计Word模板文件

这是本方案最核心的环节。我们使用Microsoft Word(或WPS)作为可视化设计器,通过特定的Jinja2语法标记动态内容区域。新建一个Word文档,命名为template.docx,保存在项目根目录下。

1. 基础文本变量替换

在文档中需要填充姓名、工号等单行文本的位置,使用双大括号标记变量名。例如:

  • 姓名:{{ name }}
  • 部门:{{ department }}
  • 入职日期:{{ hire_date }}

在Word中直接输入上述字符即可,无需特殊字体。

2. 动态表格数据填充

档案中通常包含“工作经历”或“家庭成员”等列表数据。在Word中插入一个表格,保留表头(如“时间段”、“职位”、“描述”),在第二行开始使用循环语法。

在表格的第一行数据单元格中输入:

```jinja {% for item in work_history %} ```

在表格的最后一行数据单元格中输入:

```jinja {% endfor %} ``>

中间的单元格使用{{ item.字段名 }}引用数据。例如,在“职位”列的单元格内输入{{ item.role }}注意:for和endfor语句必须分别位于表格行首尾独立的行中,不要合并单元格。

3. 图片动态插入

若需插入员工照片,需使用docxtpl提供的特定标签。在需要插入照片的位置输入:

```jinja {%p image src=user_photo width=3 cm height=4 cm %} ```

手把手教你用Python实现自定义档案模板生成系统

这里的widthheight用于控制图片尺寸,单位支持cm、mm、inches等。

4. 条件渲染逻辑

如果某些内容需要根据条件显示,例如“是否在职”。可以使用条件判断语法:

```jinja {% if status == '在职' %}

当前状态:正式员工

{% else %}

当前状态:已离职

{% endif %} ```

三、准备数据源

数据通常存储在Excel或数据库中,为了演示方便,我们构建一个Python字典结构来模拟数据。在后续开发中,你可以使用pandas库读取Excel替换此处的数据源。

新建一个文本文件,或者直接在后续的脚本中准备如下数据结构:

```python context = { "name": "张三", "department": "研发部", "hire_date": "2023-01-15", "status": "在职", 图片路径,必须是绝对路径或相对于脚本文件的正确路径 "user_photo": "photo.jpg", 表格数据列表 "work_history": [ {"role": "初级工程师", "desc": "负责后端接口开发"}, {"role": "高级工程师", "desc": "负责系统架构设计"} ] } ``>

四、编写自动化生成脚本

在项目目录下创建generate.py文件。该脚本将加载模板、注入数据并输出最终文档。以下是完整的代码实现,包含图片处理逻辑,可直接复制使用。

```python import os from docxtpl import DocxTemplate from docx.shared import Mm, Inches, Pt 定义图片处理类,用于动态调整图片大小 class UserProfileImage: def __init__(self, image_path): self.image_path = image_path def get_img(self, width_cm=None, height_cm=None): 检查文件是否存在 if not os.path.exists(self.image_path): print(f"警告:图片文件 {self.image_path} 不存在,跳过。") return None 转换厘米到Inches(docxtpl内部单位) if width_cm: width = Inches(width_cm / 2.54) else: width = None if height_cm: height = Inches(height_cm / 2.54) else: height = None return self.image_path, width, height def generate_archive(data, template_path, output_path): 加载Word模板 doc = DocxTemplate(template_path) 处理图片对象,将路径字符串转换为InlineImage对象 注意:这里为了简化,假设模板中直接使用了路径字符串 如果需要更复杂的控制,可以在context中预处理图片 if 'user_photo' in data and os.path.exists(data['user_photo']): from docxtpl import InlineImage tpl = DocxTemplate(template_path) 创建InlineImage对象,宽度4cm data['user_photo'] = InlineImage(tpl, data['user_photo'], width=Mm(40)) 渲染模板 doc.render(data) 保存生成的文档 doc.save(output_path) print(f"档案已生成:{output_path}") if __name__ == "__main__": 1. 准备数据 确保目录下有一张名为 photo.jpg 的图片,或者修改此处路径 data = { "name": "李四", "department": "市场部", "hire_date": "2022-05-20", "status": "在职", "user_photo": "photo.jpg", "work_history": [ {"role": "市场专员", "desc": "负责华东区推广"}, {"role": "区域经理", "desc": "负责华东区销售管理"} ] } 2. 设置文件路径 current_dir = os.path.dirname(os.path.abspath(__file__)) tpl_file = os.path.join(current_dir, "template.docx") output_file = os.path.join(current_dir, "李四_档案.docx") 3. 执行生成 try: generate_archive(data, tpl_file, output_file) except Exception as e: print(f"生成失败,错误信息:{e}") ```

五、运行与验证

确保项目目录下包含以下三个文件:

  1. template.docx:制作好的Word模板。
  2. photo.jpg:一张测试用的图片(若无图片,脚本会报错,可将代码中user_photo相关逻辑注释掉)。
  3. generate.py:上述Python脚本。

在命令行中进入项目目录,执行:

```bash python generate.py ``>

执行完毕后,目录下会新增李四_档案.docx文件。打开该文件,检查:

  • 姓名、部门是否已替换为“李四”、“市场部”。
  • 工作经历表格是否包含两行数据。
  • 照片是否已正确插入并调整了尺寸。

六、批量处理扩展

实际场景中通常需要批量生成。只需将上述脚本中的数据部分改为循环读取Excel即可。假设安装了openpyxl(命令:pip install openpyxl),以下是批量处理的核心逻辑代码片段:

```python import pandas as pd 读取Excel数据 df = pd.read_excel("employees.xlsx") 模板对象只需加载一次 tpl = DocxTemplate("template.docx") for index, row in df.iterrows(): context_data = { "name": row['姓名'], "department": row['部门'], "hire_date": str(row['入职日期']), "work_history": [] 这里可以根据Excel列或关联表填充 } 图片处理逻辑同上... 渲染并保存 tpl.render(context_data) tpl.save(f"output/{row['姓名']}_档案.docx") print(f"已生成:{row['姓名']}_档案.docx") ```

七、常见问题排查

1. 报错:KeyError: 'xxx'

这表示Word模板中使用了{{ xxx }}变量,但在Python的context字典中没有提供该键值。请检查模板中的变量名是否与代码中的Key完全一致(区分大小写)。

2. 表格生成后多了一行空行

这是Word表格的特性。确保{% for %}写在表格行的最左侧单元格,且{% endfor %}写在最右侧单元格或单独的一行。尝试将{% endfor %}放在表格外部的段落中,或调整其在表格行中的位置。

3. 图片无法显示

请检查图片路径是否正确。如果使用相对路径,请确保是基于当前工作目录(脚本运行目录)的路径。建议使用os.path.abspath获取绝对路径。图片格式建议使用jpg或png,避免使用webp等Word不原生支持的格式。

AI咨询
热线电话

028-85154420

15388110056

全国售前咨询电话

扫码咨询
安答联动微信公众号二维码

微信扫码关注安答联动

申请试用
热线电话
申请试用

安答联动档案管理系统