Operations 12 min read

Automate Invitation Letters: Word‑to‑PDF and Bulk Email with Python

Learn how to automate the entire invitation workflow using Python—replace placeholders in Word templates, convert them to PDFs, extract recipient data from Excel, and send personalized emails with attachments—all with concise code snippets and step‑by‑step explanations.

Python Crawling & Data Mining
Python Crawling & Data Mining
Python Crawling & Data Mining
Automate Invitation Letters: Word‑to‑PDF and Bulk Email with Python

Preface

Based on the "Python Office Efficiency Manual", this article demonstrates a complete Python automation workflow that covers Word template replacement, Excel data extraction, PDF generation, and automatic email sending.

Background

Imagine you have a Word invitation template and a list of customers with names, contact details, and emails. Manually replacing each name, converting to PDF, writing email bodies, and sending attachments would take minutes for dozens of recipients and hours for hundreds or thousands.

Python automation can handle Word replacement, Excel reading, PDF creation, and email sending in a single pipeline.

Implementation Process

1) Replace Word template to generate invitation

Use the <name> placeholder in the template and the following function:

def get_invitation(name):
    doc = docx.Document("template.docx")
    for para in doc.paragraphs:
        if '<name>' in para.text:
            for run in para.runs:
                if '<name>' in run.text:
                    run.text = run.text.replace('<name>', name)
    doc.save(f'./邀请函/{name}.docx')

The code iterates over paragraphs and runs to replace the placeholder with the actual name.

2) Convert Word invitation to PDF

A single line using docx2pdf:

from docx2pdf import convert
convert(f"./邀请函/{name}.docx")

3) Read names and emails from Excel

Using openpyxl to load the workbook and iterate rows:

def get_username_email():
    workbook = openpyxl.load_workbook("names.xlsx")
    worksheet = workbook.active
    for index, row in enumerate(worksheet.rows):
        if index > 0:
            name = row[0].value  # first column
            email = row[3].value  # fourth column
            send_email(name, email)

4) Send emails automatically

SMTP login (using an authorization code) and email composition with HTML body and PDF attachment:

smtp = smtplib.SMTP(host="smtp.qq.com", port=587)
smtp.login('[email protected]', "ruybefkipoo")

def send_email(name, email):
    msg = MIMEMultipart()
    msg["subject"] = f"您好,{name},您的邀请函!"
    msg["from"] = "[email protected]"
    msg["to"] = email

    html_content = f"""<html><body><p>您好:{name}<br><b>欢迎加入Python进阶者学习交流群,请在附件中查收您的门票~</b><br>点击这里了解更多:<a href=\"https://www.pdcfighting.com\">演唱会主页</a></p></body></html>"""
    html_part = MIMEText(html_content, "html")
    msg.attach(html_part)
    with open(f"./邀请函/{name}.pdf", "rb") as f:
        doc_part = MIMEApplication(f.read())
        doc_part.add_header("Content-Disposition", "attachment", filename=name)
        msg.attach(doc_part)
        smtp.send_message(msg)

5) Full script

import docx
from docx2pdf import convert
import openpyxl
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication

def get_invitation(name):
    doc = docx.Document("template.docx")
    for para in doc.paragraphs:
        if '<name>' in para.text:
            for run in para.runs:
                if '<name>' in run.text:
                    run.text = run.text.replace('<name>', name)
    doc.save(f'./邀请函/{name}.docx')
    convert(f"./邀请函/{name}.docx")

smtp = smtplib.SMTP(host="smtp.qq.com", port=587)
smtp.login('[email protected]', "ruybefkipoo")

def send_email(name, email):
    msg = MIMEMultipart()
    msg["subject"] = f"您好,{name},您的邀请函!"
    msg["from"] = "[email protected]"
    msg["to"] = email
    html_content = f"""<html><body><p>您好:{name}<br><b>欢迎加入Python进阶者学习交流群,请在附件中查收您的门票~</b><br>点击这里了解更多:<a href=\"https://www.pdcfighting.com\">演唱会主页</a></p></body></html>"""
    html_part = MIMEText(html_content, "html")
    msg.attach(html_part)
    with open(f"./邀请函/{name}.pdf", "rb") as f:
        doc_part = MIMEApplication(f.read())
        doc_part.add_header("Content-Disposition", "attachment", filename=name)
        msg.attach(doc_part)
        smtp.send_message(msg)

def get_username_email():
    workbook = openpyxl.load_workbook("names.xlsx")
    worksheet = workbook.active
    for index, row in enumerate(worksheet.rows):
        if index > 0:
            name = row[0].value
            email = row[3].value
            send_email(name, email)

if __name__ == '__main__':
    get_username_email()

Conclusion

The script automates Word‑to‑PDF conversion and bulk personalized email sending, dramatically reducing manual effort for hundreds or thousands of recipients. For very large volumes, a third‑party email service may be needed due to provider sending limits.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

PDFExcelWordEmailOffice
Python Crawling & Data Mining
Written by

Python Crawling & Data Mining

Life's short, I code in Python. This channel shares Python web crawling, data mining, analysis, processing, visualization, automated testing, DevOps, big data, AI, cloud computing, machine learning tools, resources, news, technical articles, tutorial videos and learning materials. Join us!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.