最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python3使用win32com從Excel讀取數(shù)據(jù)生成Word格式報(bào)告批量發(fā)郵件的示例詳解

 更新時(shí)間:2025年12月01日 09:38:11   作者:諸神緘默不語(yǔ)  
win32com 是 Python 在 Windows 平臺(tái)上一種用于訪問 COM(Component Object Model) 對(duì)象的庫(kù)/模塊,它隸屬于第三方擴(kuò)展包 pywin32,本文給大家介紹了Python3使用win32com從Excel讀取數(shù)據(jù)生成Word格式報(bào)告批量發(fā)郵件的示例,需要的朋友可以參考下

什么是 win32com

  • win32com 是 Python 在 Windows 平臺(tái)上一種用于訪問 COM(Component Object Model) 對(duì)象的庫(kù)/模塊。它隸屬于第三方擴(kuò)展包 pywin32(也就是我們通常安裝的 “pywin32” 庫(kù))的一部分。
  • 借助 win32com,Python 腳本可以與 Windows 系統(tǒng)的底層組件或支持 COM 接口的應(yīng)用程序通信,并操控它們 —— 比如常見的辦公軟件(如 Excel、Word、Outlook)、以及其他支持 COM 的軟件。這樣就能通過 Python 自動(dòng)化許多原本依賴鼠標(biāo)/鍵盤/手動(dòng)操作的流程。

簡(jiǎn)言之,win32com 讓 Python “變身”為 Windows 的自動(dòng)化驅(qū)動(dòng) — 就像用 Python 寫 VBA,但更靈活、功能更強(qiáng)大。

如何安裝與導(dǎo)入

首先確保你的環(huán)境是 Windows + Python3。

使用 pip 安裝 pywin32:

pip install pywin32

安裝后,就包含了 win32com 模塊。

在腳本中導(dǎo)入需要的模塊/子模塊,例如:

import win32com.client

如果你嘗試 import win32com 后報(bào)錯(cuò) “No module named ‘win32com’”,通常是因?yàn)闆]有正確安裝 pywin32,或安裝在與當(dāng)前 Python 解釋器不一致的環(huán)境里。

安裝完成并正確導(dǎo)入后,你就可以使用 win32com 來(lái)創(chuàng)建/連接 COM 對(duì)象。

基本使用 — 操作 Excel、Word 等 Office 應(yīng)用

下面是一些最常見、最基礎(chǔ)的用法示例。假設(shè)你已經(jīng)安裝好 Microsoft Office(或兼容 Office 的軟件,如 WPS),并在 Windows 系統(tǒng)上運(yùn)行。

操作 Excel 示例

import win32com.client

excel = win32com.client.Dispatch("Excel.Application")
excel.Visible = True  # 可見 Excel 窗口(方便調(diào)試/查看效果)

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()

這段代碼會(huì):

  • 啟動(dòng) Excel(COM 自動(dòng)化方式)
  • 新建一個(gè)工作簿
  • 獲取第一個(gè)工作表
  • 向若干個(gè)單元格寫入數(shù)據(jù)
  • 保存為 .xlsx 文件
  • 關(guān)閉 workbook 和 Excel 應(yīng)用程序

通過這種方式,你可以讓 Python 完全代替人工在 Excel 中輸入、保存、關(guān)閉操作。

操作 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 自動(dòng)生成的 Word 文檔內(nèi)容。\n"

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

這會(huì):

  • 啟動(dòng) Word
  • 新建一個(gè)文檔
  • 在開頭插入一段文本
  • 保存為 .docx 文件
  • 關(guān)閉文檔和 Word

相比于 Python 其他庫(kù)(如專門操作 docx 的第三方庫(kù)),使用 win32com 的優(yōu)勢(shì)在于可以直接操控完整的 Word 功能,包括對(duì)舊版 .doc、宏、樣式、復(fù)雜格式的支持(前提是目標(biāo) Word 版本支持這些功能)。

win32com 的能力遠(yuǎn)不止基本讀寫 — 更多高級(jí)應(yīng)用 & 注意事項(xiàng)

更強(qiáng)的自動(dòng)化/擴(kuò)展能力

除了讀寫 Excel、Word,還可以:

  • 操控 PowerPoint、Outlook、甚至其他支持 COM 的軟件。理論上,只要目標(biāo)軟件注冊(cè)了 COM 接口,都可以通過 win32com.client.Dispatch("YourApp.ProgID") 來(lái)連接。
  • 對(duì) Excel 文檔進(jìn)行宏(VBA)操作 —— 通過 win32com 可以操控 VBA 模塊,讀寫/導(dǎo)入/導(dǎo)出/執(zhí)行宏腳本,這對(duì)于復(fù)雜自動(dòng)化任務(wù)非常有用。
  • 利用 COM 的事件機(jī)制 —— 通過 DispatchWithEvents 結(jié)合相應(yīng)的事件處理類,可以讓 Python 監(jiān)聽并處理某些應(yīng)用(如 Word/Excel)的事件(例如“新建文檔”“退出程序”等)。
  • 用于其他 Windows 應(yīng)用或第三方工具(只要其提供 COM 接口):例如科學(xué)儀器、工程軟件、老舊系統(tǒng)等,與其內(nèi)部 COM 接口對(duì)接,實(shí)現(xiàn)腳本自動(dòng)化/數(shù)據(jù)導(dǎo)出/批處理等功能。

注意事項(xiàng)與局限

  • 僅 Windows 有效。因?yàn)?COM 是 Windows 特有的組件模型,在 Linux / macOS 下 win32com 通常無(wú)法使用。
  • 依賴目標(biāo)軟件是否支持 COM 自動(dòng)化 —— 如果目標(biāo)程序沒有對(duì)外提供 COM 接口,就無(wú)法通過 win32com 控制它。
  • 多線程時(shí)要小心。如果在多線程環(huán)境中調(diào)用 COM 對(duì)象,需要為每個(gè)線程單獨(dú)初始化 COM 庫(kù),否則可能報(bào)錯(cuò)例如 “尚未調(diào)用 CoInitialize”。
  • COM 操作不當(dāng)可能導(dǎo)致程序掛起。比如啟動(dòng)了某個(gè)應(yīng)用后忘記 Quit(),可能會(huì)導(dǎo)致后臺(tái)進(jìn)程殘留。良好的資源管理和異常處理非常重要。

適合用 win32com 的場(chǎng)景 / 推薦理由

場(chǎng)景 / 需求為什么推薦 win32com
Excel/Word 等 Office 自動(dòng)化(批量生成、報(bào)表、郵件合并等)可以通過腳本完全自動(dòng)化操作 Office,效率高、功能強(qiáng)
老舊 Office 格式(.doc、.xls)或需要宏/VBA 支持支持 COM/VBA,比很多現(xiàn)代庫(kù)兼容性更好
Windows 專用軟件自動(dòng)化/批處理(比如批量生成報(bào)告、儀器控制、與其他軟件對(duì)接)只要軟件支持 COM,就能用 Python 控制,靈活性強(qiáng)
不想手寫 VBA/不熟悉 VBA,但熟悉 PythonPython 更易讀寫、更便于與其他 Python 模塊整合

一個(gè)稍復(fù)雜的處理Excel的完整 Demo(Excel + VBA 宏 + 錯(cuò)誤處理 + 清理)

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"

        # 寫一些示例數(shù)據(jù)
        for i in range(1, 6):
            sheet.Cells(i, 1).Value = f"Row {i}"
            sheet.Cells(i, 2).Value = i * 10

        # 假設(shè)你有一個(gè) VBA 宏模塊,想插入并運(yùn)行
        # 例如,導(dǎo)出數(shù)據(jù)、生成圖表、格式化等
        # 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__":
    # 在一些環(huán)境下,多線程或腳本打包需要初始化 COM
    pythoncom.CoInitialize()
    main()
    pythoncom.CoUninitialize()

這個(gè)腳本展示了如何:

  • 使用 DispatchEx 啟動(dòng) Excel(相比 Dispatch 更獨(dú)立,不會(huì)復(fù)用已有 Excel 進(jìn)程)
  • 寫入數(shù)據(jù)
  • (可選)插入/執(zhí)行 VBA 宏
  • 捕獲異常,保證出錯(cuò)后也能關(guān)閉/清理資源
  • 最終保存并退出

示例:從Excel讀取數(shù)據(jù)生成Word格式報(bào)告批量發(fā)郵件

結(jié)合 Microsoft Excel、Microsoft Word 和 Microsoft Outlook 來(lái)實(shí)現(xiàn):從 Excel 讀取數(shù)據(jù) → 生成 Word 報(bào)告 → 附件 + 發(fā)郵件。適合用于“自動(dòng)生成報(bào)告 + 郵件發(fā)送”的辦公自動(dòng)化流程。

準(zhǔn)備條件

Windows 系統(tǒng) + 本地安裝 Office(Excel, Word, Outlook)

已安裝 pywin32

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

Excel 中有一個(gè)表格(比如 .xlsx),包含你希望寫入 Word 報(bào)告并作為附件發(fā)送給某人的數(shù)據(jù)

示例腳本:從 Excel 到 Word,再通過 Outlook 發(fā)郵件

import os
import win32com.client
import pythoncom  # 如果在腳本 / 多線程 /定時(shí)任務(wù)中運(yùn)行,推薦初始化 COM

def make_word_report(data_rows, output_docx_path):
    """
    data_rows: list of dict,每個(gè) dict 對(duì)應(yīng)一行,key 是列名
    output_docx_path: Word 文檔保存路徑
    """
    word = win32com.client.Dispatch("Word.Application")
    word.Visible = False
    doc = word.Documents.Add()

    # 寫入標(biāo)題
    doc.Content.InsertAfter("自動(dòng)生成報(bào)告\n")
    doc.Content.InsertAfter("====================\n\n")

    # 寫入表格/數(shù)據(jù)(簡(jiǎn)單示例)
    for row in data_rows:
        # 假設(shè) row 是 dict,按順序?qū)?
        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):
    """
    簡(jiǎn)單讀取 Excel,通過 COM 控件,也可以用 pandas/openpyxl,再包裝成 dict list
    這里假設(shè)你能用其他方式讀取 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()

    # --- 配置區(qū) ---
    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 = "自動(dòng)生成報(bào)告 - " + os.path.basename(word_report_path)
    email_body = "你好,\n\n請(qǐng)查收自動(dòng)生成的報(bào)告。如有問題,請(qǐng)回復(fù)。\n\nRegards."

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

    # 2. 生成 Word 報(bào)告
    make_word_report(data, word_report_path)

    # 3. 發(fā)送郵件(帶上 Word 報(bào)告作為附件)
    send_email_with_attachment(
        to_email=recipient,
        subject=email_subject,
        body=email_body,
        attachment_paths=[word_report_path]
    )

    pythoncom.CoUninitialize()


if __name__ == "__main__":
    main()

說明與注意事項(xiàng)

  • 我用了 pythoncom.CoInitialize() / CoUninitialize() 來(lái)確保 COM 正確初始化/釋放 — 這是在腳本、服務(wù)、線程、定時(shí)任務(wù)里比較推薦的寫法。
  • Excel 數(shù)據(jù)讀取部分我用了 pandas + openpyxl,這樣比用 COM 操作 Excel 更簡(jiǎn)單可靠。你也可以根據(jù)需要改成 COM 方式。
  • Word 報(bào)告非?;A(chǔ):只是逐行插入文本。如果需要更復(fù)雜的格式、表格、樣式、圖片,你可以用 Word COM 對(duì)象模型進(jìn)一步擴(kuò)展。COM 操作 Word 的能力比較完整。
  • 發(fā)郵件部分通過 Outlook COM 自動(dòng)創(chuàng)建郵件、添加附件并發(fā)送。這樣一來(lái)你就實(shí)現(xiàn)了“讀取數(shù)據(jù) → 生成報(bào)告 → 郵件發(fā)送”的一條完整自動(dòng)化鏈。

進(jìn)階示例:支持 Excel 多行/多收件人+Word 報(bào)告?zhèn)€性化+郵件 HTML 格式+日志/異常處理 的腳本

實(shí)現(xiàn)以下功能 —— 從 Excel 讀取多條記錄 → 為每條記錄生成特定附件 (Excel/Word) 或內(nèi)容 → 通過 Microsoft Outlook 群發(fā)帶附件/HTML 正文郵件 → 支持日志與異常處理。你可以直接拿來(lái)改造/運(yùn)行。

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

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

EMAIL_COLUMN = "email"      # Excel 表格中收件人郵箱地址所在列名
CC_COLUMN = "cc"            # 可選:抄送人列名(若無(wú),可設(shè)為 None)
SUBJECT_COLUMN = "subject"  # 郵件主題列名
BODY_COLUMN = "body_html"   # 郵件 HTML 正文列名(可設(shè) body_text 替代純文本)
ATTACHMENT_COLUMN = "attachment_path"  
# 如果每行有自己附件路徑,可放在這一列;也可以留空,然后你自己動(dòng)態(tài)生成

# --- 輔助函數(shù) ---
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 轉(zhuǎn)為空字符串
    return df.to_dict(orient="records")

def create_custom_attachment(row: dict) -> str:
    """
    如果你希望根據(jù)每行數(shù)據(jù)生成自定義附件(Excel、Word、PDF...等),
    在這里實(shí)現(xiàn)生成邏輯,并返回文件路徑;若已有附件路徑,可直接返回 row[ATTACHMENT_COLUMN]
    """
    # 示例:假設(shè)已有附件路徑
    path = row.get(ATTACHMENT_COLUMN, "").strip()
    if path and os.path.isfile(path):
        return path
    # 否則 —— 舉例,生成一個(gè)簡(jiǎn)單 txt 報(bào)告
    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")
        # 根據(jù)實(shí)際字段寫內(nèi)容
        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  # 使用指定發(fā)件郵箱(如有權(quán)限)
    mail.Subject = subject
    # 設(shè)置 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, "(無(wú)主題)")
            body_html = row.get(BODY_COLUMN, "")
            cc_addr = row.get(CC_COLUMN, "").strip() or None

            # 準(zhǔn)備附件
            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}] 發(fā)送郵件 到: {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()

模板說明 & 你可以怎樣擴(kuò)展 / 改造

  • Excel 表格中每一行代表一封郵件:包含收件人、抄送(可選)、主題、HTML 正文、附件路徑/附件生成所需字段等。這樣適合“批量群發(fā) + 個(gè)性化內(nèi)容”。
  • 我把生成附件與郵件發(fā)送邏輯分離。create_custom_attachment(...) 用于生成或獲取附件 — 你可以改成生成 Word/Excel 報(bào)告、PDF、圖片、文本等。
  • 郵件正文支持 HTML。如果你希望插入圖片、表格、樣式、公司 logo、個(gè)性化布局,都可以通過 HTML 實(shí)現(xiàn)。很多人通過該方式,將公司模板/ html 模板 + Excel 數(shù)據(jù)融合后發(fā)送。關(guān)于這一點(diǎn),用 pandas 讀取數(shù)據(jù) + HTML 模板 + win32com 發(fā)郵件,是常見方案。
  • 腳本中包含 日志記錄 + 異常捕獲 + 附件存在性檢查。 如果你每天/定期運(yùn)行這個(gè)腳本(比如用 Windows 任務(wù)調(diào)度器),日志能幫你追蹤哪些郵件發(fā)失敗,哪些發(fā)成功。
  • 如果你需要針對(duì)不同收件人生成不同附件(例如針對(duì)每個(gè)客戶生成單獨(dú)報(bào)表/合同/發(fā)票),只需要把 create_custom_attachment(...) 改成你的生成邏輯 — 比如讀取數(shù)據(jù)行內(nèi)容,生成 Excel/Word 或 PDF,再返回其路徑。

注意事項(xiàng) / 限制 / 異常處理

  • 腳本依賴本地 Outlook 客戶端配置。如果沒有正確登錄或權(quán)限,可能拋出 COM 錯(cuò)誤。很多文章指出,當(dāng) Outlook 配置為現(xiàn)代安全模式、或組織策略限制自動(dòng)發(fā)送時(shí),腳本可能失敗。
  • 如果批量郵件數(shù)量較多,建議有適當(dāng)間隔、不要一次性發(fā)送過快 —— 避免被當(dāng)作垃圾郵件或觸發(fā) Outlook 安全提示。
  • 附件路徑/生成附件邏輯要保證正確,避免因路徑問題導(dǎo)致發(fā)送失敗。
  • HTML 正文如果包含圖片、內(nèi)嵌資源等,要注意附件與 HTML 的引用關(guān)系 —— 有時(shí)候直接附件 + HTML 不一定能保證收件人看到正確格式/嵌入圖片 (取決于 Outlook 客戶端設(shè)置)。

總結(jié)

這個(gè)模板基本可以構(gòu)成一個(gè)“通用的批量發(fā)郵件 + 附件 + 個(gè)性化內(nèi)容 + 日志 + 錯(cuò)誤處理”工具。你可以根據(jù)具體業(yè)務(wù)(比如日?qǐng)?bào)、自動(dòng)報(bào)表、客戶通知、合同發(fā)送等)——把 Excel 作為“驅(qū)動(dòng)表格”(包含收件人、內(nèi)容、參數(shù)、附件路徑/數(shù)據(jù)等),然后運(yùn)行腳本自動(dòng)完成所有工作。

以上就是Python3使用win32com從Excel讀取數(shù)據(jù)生成Word格式報(bào)告批量發(fā)郵件的示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Python3 win32com Excel讀取數(shù)據(jù)生成Word的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論

漳平市| 凯里市| 柳州市| 绩溪县| 平武县| 阳西县| 南阳市| 邵阳市| 龙川县| 句容市| 长春市| 西吉县| 郸城县| 乐清市| 绿春县| 黄平县| 明光市| 云霄县| 平远县| 济源市| 遂平县| 宾阳县| 澳门| 和平县| 贵州省| 太谷县| 射洪县| 金沙县| 乌审旗| 太原市| 汉川市| 玉龙| 滨州市| 墨竹工卡县| 深泽县| 昆明市| 钟山县| 区。| 广德县| 霞浦县| 淮北市|