python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Python邮件合并

Python实现邮件合并和批量生成个性化Word文档

作者:大丸子

本文将教你用FreeSpire.Doc for Python实现邮件合并,把模板和数据源分离,自动替换合并字段、处理IF条件字段判断、隐藏空段落,并批量生成多份文档,无论通知书还是合同,都能轻松搞定

邮件合并把文档模板和数据源分离:模板定义布局与固定文字,合并字段标记数据插入位置,运行时用数据源的值替换字段。一次合并产出一份文档,循环数据源即批量生成。Free Spire.Doc for Python 的 MailMerge 对象提供 Execute 方法做字段替换,配合 IF 条件字段和空区域处理,覆盖从简单替换到条件显示的常见需求。

pip install spire-doc

演示模板(template.docx)是一封客户通知信,包含 9 个合并字段(Contact Name、Company、Address、Fax、Date、OrderNumber、Product、Quantity、Amount)和 1 个 IF 条件字段(判断 Amount 是否超过 1000)。

邮件合并演示文档

简单字段合并

Execute 接收两个等长列表:字段名和字段值。模板中的合并字段(«Contact Name»、«Company» 等)被对应位置的值替换。

from spire.doc import *
from spire.doc.common import *
document = Document()
document.LoadFromFile("template.docx")
fieldNames = ["Contact Name", "Company", "Address", "Fax", "Date",
              "OrderNumber", "Product", "Quantity", "Amount"]
fieldValues = ["John Smith", "Acme Corporation", "123 Business Ave, New York, NY 10001",
               "+1 (555) 123-4567", "2026-10-19",
               "ORD-2026-0847", "Wireless Headset Model X200", "25", "1875"]
document.MailMerge.Execute(fieldNames, fieldValues)
document.IsUpdateFields = True
document.SaveToFile("output_simple_merge.docx", FileFormat.Docx)
document.Close()

IsUpdateFields 设为 True 让合并后文档中的所有字段重新计算并显示结果。不设置这一行,合并字段本身会被替换,但 IF 条件字段保持域代码状态,不显示判断结果。

所有字段已替换为实际值。

简单合并效果

条件字段

IF 字段在模板中定义条件判断,合并时根据数据值选择显示内容。模板中的 IF 字段判断 Amount 是否大于 1000:超过则显示 "You qualify for our premium discount program.",否则显示 "Standard rate applies."

同一模板用两组数据合并,观察条件字段的输出差异:

fieldNames = ["Contact Name", "Company", "Address", "Fax", "Date",
              "OrderNumber", "Product", "Quantity", "Amount"]

# Amount = 2400(超过 1000)
doc1 = Document()
doc1.LoadFromFile("template.docx")
fieldValues1 = ["Alice Brown", "TechGlobal Inc.", "456 Innovation Drive, San Jose, CA 95110",
                "+1 (555) 987-6543", "2026-10-19",
                "ORD-2026-0848", "Enterprise Server License", "3", "2400"]
doc1.MailMerge.Execute(fieldNames, fieldValues1)
doc1.IsUpdateFields = True
doc1.SaveToFile("output_conditional_premium.docx", FileFormat.Docx)
doc1.Close()

# Amount = 450(不超过 1000)
doc2 = Document()
doc2.LoadFromFile("template.docx")
fieldValues2 = ["Bob Wilson", "HomeOffice Solutions", "789 Residential St, Austin, TX 73301",
                "+1 (555) 456-7890", "2026-10-19",
                "ORD-2026-0849", "Desktop App Subscription", "1", "450"]
doc2.MailMerge.Execute(fieldNames, fieldValues2)
doc2.IsUpdateFields = True
doc2.SaveToFile("output_conditional_standard.docx", FileFormat.Docx)
doc2.Close()

两份输出分别显示 "You qualify for our premium discount program." 和 "Standard rate applies."。条件字段在模板中只定义一次,合并时自动按数据分流,不需要在代码里写 if-else 分支。

条件字段对比

空区域处理

当某些字段没有值时,合并后对应的段落变成空行。HideEmptyParagraphs 设为 True 会移除这些段落,使文档结构紧凑。

这里有一个需要留意的机制:HideEmptyParagraphs 判断的是整个段落是否为空,而非单个字段是否为空。如果段落中除合并字段外还有其他文字(例如 "VAT Number: «VATNumber»"),即使 VATNumber 的值为空,段落仍保留 "VAT Number: " 前缀,不会被移除。要让空区域被正确隐藏,可选字段应独占一个段落。

document = Document()
document.LoadFromFile("template_optional.docx")

document.MailMerge.HideEmptyParagraphs = True

fieldNames = ["Customer", "InvoiceNumber", "VATNumber", "DiscountCode", "Amount"]
fieldValues = ["Global Tech Ltd.", "INV-2026-3392", "", "", "3200"]

document.MailMerge.Execute(fieldNames, fieldValues)
document.IsUpdateFields = True
document.SaveToFile("output_empty_hidden.docx", FileFormat.Docx)
document.Close()

VATNumber 和 DiscountCode 的值为空字符串。不设置 HideEmptyParagraphs 时,文档保留 8 个段落(含 2 个空段落);设置后减为 6 个,空字段所在的段落被完整移除。

批量生成

邮件合并的典型场景是从数据列表一次性生成多份文档。每条记录重新加载模板、执行合并、保存为独立文件:

import os
fieldNames = ["Contact Name", "Company", "Address", "Fax", "Date",
              "OrderNumber", "Product", "Quantity", "Amount"]
batch_data = [
    {"Contact Name": "John Smith", "Company": "Acme Corporation",
     "Address": "123 Business Ave, New York, NY 10001",
     "Fax": "+1 (555) 123-4567", "Date": "2026-10-19",
     "OrderNumber": "ORD-2026-0847", "Product": "Wireless Headset Model X200",
     "Quantity": "25", "Amount": "1875"},
    {"Contact Name": "Alice Brown", "Company": "TechGlobal Inc.",
     "Address": "456 Innovation Drive, San Jose, CA 95110",
     "Fax": "+1 (555) 987-6543", "Date": "2026-10-19",
     "OrderNumber": "ORD-2026-0848", "Product": "Enterprise Server License",
     "Quantity": "3", "Amount": "2400"},
    # ... 更多记录
]
os.makedirs("batch_output", exist_ok=True)
for record in batch_data:
    doc = Document()
    doc.LoadFromFile("template.docx")
    fieldValues = [record[name] for name in fieldNames]
    doc.MailMerge.Execute(fieldNames, fieldValues)
    doc.IsUpdateFields = True
    doc.SaveToFile(f"batch_output/{record['OrderNumber']}.docx", FileFormat.Docx)
    doc.Close()

5 条记录全部生成成功,以订单号命名。模板在每次循环中重新加载——合并操作会修改文档对象,复用同一对象会导致字段已被替换、后续合并无字段可填。

数据源不限于代码内的列表。实际应用中,数据从 Excel、CSV、数据库查询结果读入,构造为 fieldNames 和 fieldValues 两个列表即可接入同一套合并流程。

适用场景与方案选择

三种方案按复杂度递进,按需组合:

批量生成是三种方案的共同出口:无论模板用了哪种字段类型,循环数据源、逐条合并、逐份保存的流程不变。数据源从业务系统读入,模板由业务人员维护,代码只负责把两者对接——这是邮件合并把模板和数据分离的设计意图。

以上就是Python实现邮件合并和批量生成个性化Word文档的详细内容,更多关于Python邮件合并的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文