python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Python3 win32com Excel读取数据生成Word

Python3使用win32com从Excel读取数据生成Word格式报告批量发邮件的示例详解

作者:诸神缄默不语

win32com 是 Python 在 Windows 平台上一种用于访问 COM(Component Object Model) 对象的库/模块,它隶属于第三方扩展包 pywin32,本文给大家介绍了Python3使用win32com从Excel读取数据生成Word格式报告批量发邮件的示例,需要的朋友可以参考下

什么是 win32com

简言之,win32com 让 Python “变身”为 Windows 的自动化驱动 — 就像用 Python 写 VBA,但更灵活、功能更强大。

如何安装与导入

首先确保你的环境是 Windows + Python3。

使用 pip 安装 pywin32:

pip install pywin32

安装后,就包含了 win32com 模块。

在脚本中导入需要的模块/子模块,例如:

import win32com.client

如果你尝试 import win32com 后报错 “No module named ‘win32com’”,通常是因为没有正确安装 pywin32,或安装在与当前 Python 解释器不一致的环境里。

安装完成并正确导入后,你就可以使用 win32com 来创建/连接 COM 对象。

基本使用 — 操作 Excel、Word 等 Office 应用

下面是一些最常见、最基础的用法示例。假设你已经安装好 Microsoft Office(或兼容 Office 的软件,如 WPS),并在 Windows 系统上运行。

操作 Excel 示例

import win32com.client

excel = win32com.client.Dispatch("Excel.Application")
excel.Visible = True  # 可见 Excel 窗口(方便调试/查看效果)

workbook = excel.Workbooks.Add()
sheet = workbook.Worksheets(1)

sheet.Cells(1, 1).Value = "Hello"
sheet.Cells(1, 2).Value = "World"
sheet.Cells(2, 1).Value = "Python"
sheet.Cells(2, 2).Value = "win32com"

workbook.SaveAs(r"C:\path\to\your\file.xlsx")
workbook.Close(False)
excel.Quit()

这段代码会:

通过这种方式,你可以让 Python 完全代替人工在 Excel 中输入、保存、关闭操作。

操作 Word 示例

import win32com.client

word = win32com.client.Dispatch("Word.Application")
word.Visible = True

doc = word.Documents.Add()
rng = doc.Range(0, 0)
rng.Text = "这是由 python + win32com 自动生成的 Word 文档内容。\n"

doc.SaveAs(r"C:\path\to\your\file.docx")
doc.Close(False)
word.Quit()

这会:

相比于 Python 其他库(如专门操作 docx 的第三方库),使用 win32com 的优势在于可以直接操控完整的 Word 功能,包括对旧版 .doc、宏、样式、复杂格式的支持(前提是目标 Word 版本支持这些功能)。

win32com 的能力远不止基本读写 — 更多高级应用 & 注意事项

更强的自动化/扩展能力

除了读写 Excel、Word,还可以:

注意事项与局限

适合用 win32com 的场景 / 推荐理由

场景 / 需求为什么推荐 win32com
Excel/Word 等 Office 自动化(批量生成、报表、邮件合并等)可以通过脚本完全自动化操作 Office,效率高、功能强
老旧 Office 格式(.doc、.xls)或需要宏/VBA 支持支持 COM/VBA,比很多现代库兼容性更好
Windows 专用软件自动化/批处理(比如批量生成报告、仪器控制、与其他软件对接)只要软件支持 COM,就能用 Python 控制,灵活性强
不想手写 VBA/不熟悉 VBA,但熟悉 PythonPython 更易读写、更便于与其他 Python 模块整合

一个稍复杂的处理Excel的完整 Demo(Excel + VBA 宏 + 错误处理 + 清理)

import win32com.client
import pythoncom
import os
import sys

def main():
    try:
        excel = win32com.client.DispatchEx("Excel.Application")
        excel.Visible = False
        excel.DisplayAlerts = False

        wb = excel.Workbooks.Add()
        sheet = wb.Worksheets(1)
        sheet.Name = "Data"

        # 写一些示例数据
        for i in range(1, 6):
            sheet.Cells(i, 1).Value = f"Row {i}"
            sheet.Cells(i, 2).Value = i * 10

        # 假设你有一个 VBA 宏模块,想插入并运行
        # 例如,导出数据、生成图表、格式化等
        # wb.VBProject.VBComponents.Add(...)  # 插入模块
        # wb.Application.Run("YourMacroName")

        out_path = os.path.join(os.getcwd(), "output.xlsx")
        wb.SaveAs(out_path)
        print("Saved to", out_path)
    except Exception as e:
        print("Error:", e)
    finally:
        try:
            wb.Close(False)
        except Exception:
            pass
        try:
            excel.Quit()
        except Exception:
            pass

if __name__ == "__main__":
    # 在一些环境下,多线程或脚本打包需要初始化 COM
    pythoncom.CoInitialize()
    main()
    pythoncom.CoUninitialize()

这个脚本展示了如何:

示例:从Excel读取数据生成Word格式报告批量发邮件

结合 Microsoft Excel、Microsoft Word 和 Microsoft Outlook 来实现:从 Excel 读取数据 → 生成 Word 报告 → 附件 + 发邮件。适合用于“自动生成报告 + 邮件发送”的办公自动化流程。

准备条件

Windows 系统 + 本地安装 Office(Excel, Word, Outlook)

已安装 pywin32

pip install pywin32
```:contentReference[oaicite:5]{index=5}  

Excel 中有一个表格(比如 .xlsx),包含你希望写入 Word 报告并作为附件发送给某人的数据

示例脚本:从 Excel 到 Word,再通过 Outlook 发邮件

import os
import win32com.client
import pythoncom  # 如果在脚本 / 多线程 /定时任务中运行,推荐初始化 COM

def make_word_report(data_rows, output_docx_path):
    """
    data_rows: list of dict,每个 dict 对应一行,key 是列名
    output_docx_path: Word 文档保存路径
    """
    word = win32com.client.Dispatch("Word.Application")
    word.Visible = False
    doc = word.Documents.Add()

    # 写入标题
    doc.Content.InsertAfter("自动生成报告\n")
    doc.Content.InsertAfter("====================\n\n")

    # 写入表格/数据(简单示例)
    for row in data_rows:
        # 假设 row 是 dict,按顺序写
        line = ", ".join(f"{k}: {v}" for k, v in row.items())
        doc.Content.InsertAfter(line + "\n")

    doc.SaveAs(output_docx_path)
    doc.Close(False)
    word.Quit()


def read_excel_data(excel_path, sheet_name=None):
    """
    简单读取 Excel,通过 COM 控件,也可以用 pandas/openpyxl,再包装成 dict list
    这里假设你能用其他方式读取 Excel,示例用 pandas 更方便
    """
    import pandas as pd
    df = pd.read_excel(excel_path, sheet_name=sheet_name)
    df = df.fillna("")  # 可选:替换空值
    records = df.to_dict(orient="records")
    return records


def send_email_with_attachment(to_email, subject, body, attachment_paths=None):
    outlook = win32com.client.Dispatch("Outlook.Application")
    mail = outlook.CreateItem(0)  # 0 表示 olMailItem
    mail.To = to_email
    mail.Subject = subject
    mail.Body = body
    if attachment_paths:
        for path in attachment_paths:
            if os.path.exists(path):
                mail.Attachments.Add(path)
            else:
                print(f"[Warning] 附件文件不存在: {path}")
    mail.Send()


def main():
    pythoncom.CoInitialize()

    # --- 配置区 ---
    excel_path = r"C:\path\to\your\data.xlsx"
    word_report_path = r"C:\path\to\your\report.docx"
    recipient = "recipient@example.com"
    email_subject = "自动生成报告 - " + os.path.basename(word_report_path)
    email_body = "你好,\n\n请查收自动生成的报告。如有问题,请回复。\n\nRegards."

    # 1. 读取 Excel
    data = read_excel_data(excel_path)

    # 2. 生成 Word 报告
    make_word_report(data, word_report_path)

    # 3. 发送邮件(带上 Word 报告作为附件)
    send_email_with_attachment(
        to_email=recipient,
        subject=email_subject,
        body=email_body,
        attachment_paths=[word_report_path]
    )

    pythoncom.CoUninitialize()


if __name__ == "__main__":
    main()

说明与注意事项

进阶示例:支持 Excel 多行/多收件人+Word 报告个性化+邮件 HTML 格式+日志/异常处理 的脚本

实现以下功能 —— 从 Excel 读取多条记录 → 为每条记录生成特定附件 (Excel/Word) 或内容 → 通过 Microsoft Outlook 群发带附件/HTML 正文邮件 → 支持日志与异常处理。你可以直接拿来改造/运行。

import os
import traceback
import pandas as pd
import win32com.client
import pythoncom
from pathlib import Path

# --- 配置区 ---
EXCEL_DATA_FILE = r"C:\path\to\your\recipients_and_data.xlsx"
OUTPUT_DIR = r"C:\path\to\output"   # 存放生成的附件、报告等
LOG_FILE = os.path.join(OUTPUT_DIR, "send_mail.log")

EMAIL_COLUMN = "email"      # Excel 表格中收件人邮箱地址所在列名
CC_COLUMN = "cc"            # 可选:抄送人列名(若无,可设为 None)
SUBJECT_COLUMN = "subject"  # 邮件主题列名
BODY_COLUMN = "body_html"   # 邮件 HTML 正文列名(可设 body_text 替代纯文本)
ATTACHMENT_COLUMN = "attachment_path"  
# 如果每行有自己附件路径,可放在这一列;也可以留空,然后你自己动态生成

# --- 辅助函数 ---
def log(msg):
    with open(LOG_FILE, 'a', encoding='utf-8') as f:
        f.write(msg + "\n")
    print(msg)

def ensure_folder(path: str):
    if not os.path.isdir(path):
        os.makedirs(path, exist_ok=True)

def read_data():
    df = pd.read_excel(EXCEL_DATA_FILE, dtype=str)
    df = df.fillna("")  # 将 NaN 转为空字符串
    return df.to_dict(orient="records")

def create_custom_attachment(row: dict) -> str:
    """
    如果你希望根据每行数据生成自定义附件(Excel、Word、PDF...等),
    在这里实现生成逻辑,并返回文件路径;若已有附件路径,可直接返回 row[ATTACHMENT_COLUMN]
    """
    # 示例:假设已有附件路径
    path = row.get(ATTACHMENT_COLUMN, "").strip()
    if path and os.path.isfile(path):
        return path
    # 否则 —— 举例,生成一个简单 txt 报告
    fn = os.path.join(OUTPUT_DIR, f"report_for_{row.get('id', '')}.txt")
    with open(fn, 'w', encoding='utf-8') as f:
        f.write("Report for: " + row.get(EMAIL_COLUMN, "") + "\n")
        # 根据实际字段写内容
        for k, v in row.items():
            f.write(f"{k} = {v}\n")
    return fn

def send_mail_via_outlook(to_addr: str, subject: str, body_html: str,
                          cc_addr: str = None, attachments: list = None,
                          send_on_behalf: str = None):
    outlook = win32com.client.Dispatch("Outlook.Application")
    mail = outlook.CreateItem(0)  # 0 = olMailItem
    mail.To = to_addr
    if cc_addr:
        mail.CC = cc_addr
    if send_on_behalf:
        mail.SentOnBehalfOfName = send_on_behalf  # 使用指定发件邮箱(如有权限)
    mail.Subject = subject
    # 设置 html 正文
    mail.BodyFormat = 2  # 2 = HTML
    mail.HTMLBody = body_html
    # 添加附件
    if attachments:
        for fp in attachments:
            if os.path.isfile(fp):
                mail.Attachments.Add(fp)
            else:
                log(f"[WARN] 附件不存在: {fp}")
    mail.Send()

def main():
    pythoncom.CoInitialize()
    ensure_folder(OUTPUT_DIR)
    data_rows = read_data()
    log("开始处理,共 {} 行".format(len(data_rows)))

    success = 0
    fail = 0

    for idx, row in enumerate(data_rows, start=1):
        try:
            to_addr = row.get(EMAIL_COLUMN, "").strip()
            if not to_addr:
                log(f"[SKIP #{idx}] 收件人地址为空,跳过")
                continue

            subject = row.get(SUBJECT_COLUMN, "(无主题)")
            body_html = row.get(BODY_COLUMN, "")
            cc_addr = row.get(CC_COLUMN, "").strip() or None

            # 准备附件
            att = create_custom_attachment(row)
            attachments = [att] if att else None

            send_mail_via_outlook(to_addr=to_addr,
                                  subject=subject,
                                  body_html=body_html,
                                  cc_addr=cc_addr,
                                  attachments=attachments)

            log(f"[OK #{idx}] 发送邮件 到: {to_addr}, 附件: {attachments}")
            success += 1
        except Exception as e:
            log(f"[ERROR #{idx}] 收件人: {row.get(EMAIL_COLUMN)} 异常: {e}\n" + traceback.format_exc())
            fail += 1

    log(f"完成。成功: {success}, 失败: {fail}")
    pythoncom.CoUninitialize()

if __name__ == "__main__":
    main()

模板说明 & 你可以怎样扩展 / 改造

注意事项 / 限制 / 异常处理

总结

这个模板基本可以构成一个“通用的批量发邮件 + 附件 + 个性化内容 + 日志 + 错误处理”工具。你可以根据具体业务(比如日报、自动报表、客户通知、合同发送等)——把 Excel 作为“驱动表格”(包含收件人、内容、参数、附件路径/数据等),然后运行脚本自动完成所有工作。

以上就是Python3使用win32com从Excel读取数据生成Word格式报告批量发邮件的示例详解的详细内容,更多关于Python3 win32com Excel读取数据生成Word的资料请关注脚本之家其它相关文章!

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