如何无需指定路径调用Pandas .to_csv并直接作为Outlook附件发送?
问题:如何直接将Pandas生成的CSV作为Outlook附件发送(无需本地保存)
我写了一个脚本,能登录公司的SQL Server执行查询,用Pandas把结果读到变量里,之后调用.to_csv生成文件,再通过win32com.client把文件作为附件发给指定用户。现在脚本能正常运行,但调用.to_csv时必须指定本地路径保存文件,再通过路径引用添加为Outlook附件。我想省去本地保存这一步,直接生成CSV并添加为邮件附件,请问这可行吗?
现有示例代码:
import pyodbc import pandas as pd import os from datetime import date import win32com.client as win32 cnxn_str = () # 连接字符串细节 cnxn = pyodbc.connect(cnxn_str) query = ''' # 查询语句写在这里 ''' data = pd.read_sql(query, cnxn) del cnxn path = (文件路径) # <-- 这是我想去掉的部分 data.to_csv(os.path.join(path,f'{date.today()}_data.csv'),encoding='utf-8',index=False) # <-- 能不能不指定路径调用.to_csv?
outlook = win32.Dispatch('outlook.application') mail = outlook.CreateItem(0) mail.To = ''# 收件人 mail.Subject = '' mail.Body = 'Hey Matthew, attached is a current Open Orders query.' # 附加文件到邮件(可选): attachment = os.path.join(path,f'{date.today()}_data.csv') # <-- 怎么一步生成CSV并添加为附件,不用保存到本地? mail.Attachments.Add(attachment) mail.Send()
解决方案
完全可行,你可以借助内存流(io.BytesIO)存储CSV数据,再通过Win32COM的COM流接口将内存中的数据直接添加为Outlook附件,全程无需写入本地文件。
修改后的完整代码
import pyodbc import pandas as pd from datetime import date import win32com.client as win32 import io import pythoncom from win32com.client import constants # 数据库连接与查询 cnxn_str = "" # 填入你的数据库连接字符串 cnxn = pyodbc.connect(cnxn_str) query = ''' -- 填入你的SQL查询语句 ''' data = pd.read_sql(query, cnxn) cnxn.close() # 用close代替del,资源释放更规范 # 将CSV数据写入内存字节流 csv_buffer = io.BytesIO() data.to_csv(csv_buffer, encoding='utf-8', index=False) csv_buffer.seek(0) # 将指针移到流的起始位置 # 初始化Outlook邮件 outlook = win32.Dispatch('outlook.application') mail = outlook.CreateItem(0) mail.To = "" # 填入收件人邮箱 mail.Subject = f"[{date.today()}] 最新未结订单查询" mail.Body = 'Hey Matthew, attached is a current Open Orders query.' # 将内存流转换为Outlook可识别的COM流对象 istream = pythoncom.CreateStreamOnHGlobal(None, True) istream.Write(csv_buffer.getvalue()) istream.Seek(0, 0) # 定位到流的起始位置 # 添加内存中的CSV作为附件 mail.Attachments.Add( Source=istream, Type=constants.olByValue, FileName=f"{date.today()}_data.csv" ) mail.Send()
关键说明
io.BytesIO用于在内存中存储CSV的字节数据,替代本地文件的磁盘写入操作pythoncom.CreateStreamOnHGlobal创建符合COM标准的流对象,确保Outlook能识别并读取内存中的数据Type=constants.olByValue指定附件是直接嵌入邮件的(而非外部链接),收件人无需额外操作即可打开附件
内容的提问来源于stack exchange,提问作者matthewtmeloney
相关产品推荐
相关产品推荐

