使用Python和openpyxl结合Word模板域写入数据
在Python中,我们可以使用openpyxl处理Excel数据,然后结合Word模板中的域(书签或合并域)来生成定制化的Word文档。以下是几种实现方法:
方法一:使用书签(Bookmarks)
1. 准备Word模板
首先创建一个Word模板,在需要插入数据的位置添加书签。
2. Python实现代码
python
import openpyxl
from docx import Document
from docx.shared import Inches
def fill_word_template_from_excel(excel_file, word_template, output_file):
# 读取Excel数据
wb = openpyxl.load_workbook(excel_file)
ws = wb.active
# 读取Word模板
doc = Document(word_template)
# 假设Excel第一行是标题,第二行是数据
data = {}
for i, cell in enumerate(ws[1], 1):
data[cell.value] = ws[2][i-1].value
# 替换Word中的书签
for paragraph in doc.paragraphs:
for key, value in data.items():
if key in paragraph.text:
paragraph.text = paragraph.text.replace(f'[{key}]', str(value))
# 处理表格
for table in doc.tables:
for row in table.rows:
for cell in row.cells:
for key, value in data.items():
if key in cell.text:
cell.text = cell.text.replace(f'[{key}]', str(value))
# 保存文档
doc.save(output_file)
print(f"文档已生成: {output_file}")
# 使用示例
fill_word_template_from_excel('data.xlsx', 'template.docx', 'output.docx')
方法二:使用邮件合并域
1. 准备Word模板
在Word模板中使用<<字段名>>格式的合并域。
2. Python实现代码
python
import openpyxl
from docx import Document
import re
def mail_merge_from_excel(excel_file, word_template, output_file):
# 读取Excel数据
wb = openpyxl.load_workbook(excel_file)
ws = wb.active
# 读取Word模板
doc = Document(word_template)
# 获取数据(假设第一行是字段名)
headers = [cell.value for cell in ws[1]]
data_row = ws[2] # 假设使用第二行数据
# 创建数据字典
data = {headers[i]: data_row[i].value for i in range(len(headers))}
# 替换合并域
for paragraph in doc.paragraphs:
for key, value in data.items():
merge_field = f'<<{key}>>'
if merge_field in paragraph.text:
paragraph.text = paragraph.text.replace(merge_field, str(value))
# 处理表格中的合并域
for table in doc.tables:
for row in table.rows:
for cell in row.cells:
for key, value in data.items():
merge_field = f'<<{key}>>'
if merge_field in cell.text:
cell.text = cell.text.replace(merge_field, str(value))
# 保存文档
doc.save(output_file)
print(f"邮件合并完成: {output_file}")
# 使用示例
mail_merge_from_excel('employee_data.xlsx', 'offer_letter_template.docx', 'offer_letter.docx')
方法三:批量处理多条数据
python
import openpyxl
from docx import Document
import os
def batch_generate_documents(excel_file, word_template, output_folder):
# 创建输出文件夹
if not os.path.exists(output_folder):
os.makedirs(output_folder)
# 读取Excel数据
wb = openpyxl.load_workbook(excel_file)
ws = wb.active
# 获取标题行
headers = [cell.value for cell in ws[1]]
# 遍历每一行数据
for row_idx, row in enumerate(ws.iter_rows(min_row=2), 1):
# 读取Word模板
doc = Document(word_template)
# 创建数据字典
data = {headers[i]: row[i].value for i in range(len(headers))}
# 替换文档内容
for paragraph in doc.paragraphs:
for key, value in data.items():
placeholder = f'{{{key}}}'
if placeholder in paragraph.text:
paragraph.text = paragraph.text.replace(placeholder, str(value))
# 处理表格
for table in doc.tables:
for table_row in table.rows:
for cell in table_row.cells:
for key, value in data.items():
placeholder = f'{{{key}}}'
if placeholder in cell.text:
cell.text = cell.text.replace(placeholder, str(value))
# 保存文档
filename = f"{output_folder}/document_{row_idx}.docx"
doc.save(filename)
print(f"批量生成完成,共生成 {ws.max_row - 1} 个文档")
# 使用示例
batch_generate_documents('students.xlsx', 'certificate_template.docx', 'certificates')
方法四:使用python-docx-template(推荐)
首先安装:pip install docxtpl
python
import openpyxl
from docxtpl import DocxTemplate
import json
def advanced_template_filling(excel_file, word_template, output_file):
# 读取Excel数据
wb = openpyxl.load_workbook(excel_file)
ws = wb.active
# 准备数据
headers = [cell.value for cell in ws[1]]
data = {}
# 假设我们处理第一行数据
for i, header in enumerate(headers):
data[header] = ws[2][i].value
# 加载Word模板
doc = DocxTemplate(word_template)
# 渲染模板
doc.render(data)
# 保存文档
doc.save(output_file)
print(f"高级模板填充完成: {output_file}")
# 使用示例
advanced_template_filling('contract_data.xlsx', 'contract_template.docx', 'contract_final.docx')
完整案例:生成员工录用通知书
Excel数据 (employee_data.xlsx)
| 姓名 | 职位 | 部门 | 入职日期 | 薪资 |
|---|---|---|---|---|
| 张三 | 软件工程师 | 技术部 | 2024-01-15 | 15000 |
Word模板 (offer_letter_template.docx)
员工录用通知书
尊敬的<<姓名>>先生/女士:
我们很高兴通知您,您已被录用为<<部门>>的<<职位>>。
入职日期:<<入职日期>>
基本薪资:¥<<薪资>>元/月
请携带相关材料按时报到。
人力资源部
<<当前日期>>
Python代码
python
import openpyxl
from docxtpl import DocxTemplate
from datetime import datetime
def generate_offer_letters():
# 读取Excel数据
wb = openpyxl.load_workbook('employee_data.xlsx')
ws = wb.active
# 处理每一行数据
for row in ws.iter_rows(min_row=2, values_only=True):
name, position, department, start_date, salary = row
# 准备上下文数据
context = {
'姓名': name,
'职位': position,
'部门': department,
'入职日期': start_date.strftime('%Y年%m月%d日') if isinstance(start_date, datetime) else start_date,
'薪资': salary,
'当前日期': datetime.now().strftime('%Y年%m月%d日')
}
# 加载并渲染模板
doc = DocxTemplate('offer_letter_template.docx')
doc.render(context)
# 保存文档
output_file = f"offer_letter_{name}.docx"
doc.save(output_file)
print(f"已生成: {output_file}")
# 执行
generate_offer_letters()
总结
以上方法提供了不同复杂度的Word模板填充方案:
- 简单替换:使用字符串替换处理简单的占位符
- 邮件合并:处理标准的Word合并域格式
- 批量处理:一次性处理多条数据记录
- 高级模板:使用docxtpl库处理复杂的模板逻辑
选择哪种方法取决于你的具体需求:
- 简单需求:使用方法一或二
- 批量处理:使用方法三
- 复杂模板:推荐使用方法四(docxtpl)
记得安装所需库:
bash
pip install openpyxl python-docx docxtpl