You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python发票自动发送脚本故障排查求助

PDF邮件自动发送脚本错误排查与修复

问题描述

网络从业者修改Stack Exchange代码实现以下功能:遍历本地PDF文件夹(文件命名格式D1234-12345),通过Excel文件A列的经销商编号匹配C列邮箱,自动发送带PDF附件的邮件。运行时出现两个问题:

  • 开启错误检查时提示:Error: Dealer_Number .DS_Store dosnt exist
  • 关闭错误检查时触发IndexError: index 0 is out of bounds for axis 0 with size 0

错误原因分析

  1. .DS_Store文件干扰:Mac系统会在文件夹自动生成.DS_Store隐藏文件,os.listdir()会遍历到它,提取的前缀是.DS_Store,自然在Excel里找不到对应经销商编号。
  2. 索引越界错误:当找不到匹配的经销商编号时,row是空DataFrame,此时强行访问row['Email_Address'].values[0]会触发索引越界。
  3. Excel读取逻辑问题:原脚本用names参数指定列名,可能覆盖Excel原有表头,导致经销商编号匹配失败。
  4. Outlook对象重复初始化:每次循环都创建新的Outlook对象,效率低下且可能引发异常。

修复方案与修改后代码

import os
import pandas as pd
import win32com.client

# Excel文件路径
excel_path = 'C:\\invoices\\invoices.xlsx'
# PDF文件夹路径
pdf_folder = 'C:\\invoicesPDF'

# 读取Excel,保留原有表头,只取A、C列
try:
    df = pd.read_excel(excel_path, usecols="A,C")
    # 重命名列确保统一(如果Excel表头不是Dealer_Number/Email_Address,这里要对应修改)
    df.columns = ['Dealer_Number', 'Email_Address']
except Exception as e:
    print(f"读取Excel失败: {e}")
    exit()

# 检查Excel数据是否为空
if df.empty:
    print("Error: Excel文件无有效数据,请检查文件内容。")
    exit()

# 提前初始化Outlook对象,避免重复创建
try:
    outlook = win32com.client.Dispatch("Outlook.Application")
except Exception as e:
    print(f"初始化Outlook失败: {e}")
    exit()

# 遍历PDF文件夹,过滤非PDF和隐藏文件
for filename in os.listdir(pdf_folder):
    # 跳过隐藏文件(比如.DS_Store)和非PDF文件
    if filename.startswith('.') or not filename.lower().endswith('.pdf'):
        continue
    
    pdf_path = os.path.join(pdf_folder, filename)
    # 提取经销商编号(分割符'-'前的部分)
    try:
        dealer_num = filename.split('-')[0]
    except IndexError:
        print(f"文件名格式错误: {filename},跳过该文件")
        continue
    
    # 匹配对应的邮箱
    matched_row = df.loc[df['Dealer_Number'] == dealer_num]
    if matched_row.empty:
        print(f"警告: 经销商编号 {dealer_num} 在Excel中不存在,跳过文件 {filename}")
        continue
    
    # 获取邮箱地址(取第一个匹配结果)
    to_email = matched_row['Email_Address'].values[0]
    
    # 创建邮件
    try:
        mail = outlook.CreateItem(0)
        mail.To = to_email
        mail.Subject = 'Yeti Invoice'
        mail.body = 'Hello, please find the attached invoice for your records.\n\nThank you.'
        mail.Attachments.Add(pdf_path)
        mail.Send()
        print(f"邮件已成功发送至 {to_email},附件: {filename}")
    except Exception as e:
        print(f"发送邮件失败(收件人: {to_email},文件: {filename}): {e}")

关键修复点说明

  • 过滤无效文件:通过filename.startswith('.')跳过隐藏文件,filename.lower().endswith('.pdf')确保只处理PDF文件。
  • Excel读取优化:移除names参数,读取后重命名列,避免覆盖原有表头导致匹配失败。
  • 错误处理优化:遇到无效文件名或不匹配的经销商编号时,打印警告并跳过,而非直接退出程序。
  • Outlook对象复用:提前初始化一次Outlook,提升运行效率。

内容的提问来源于stack exchange,提问作者Luke Shacter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 11:27:36