我正在使用
smtplib
通过 python 发送一些自动报告。我正在使用 MIMEText
附加这些报告的 HTML 格式,但问题是,如果报告太长,Gmail 会像往常一样显示“查看整个邮件”链接来显示完整报告,但我的邮件却变得即使单击 View Entire Message 链接(在新窗口中打开剪辑的报告)后,它也会被剪辑,它会显示相同数量的报告/数据,并在报告底部添加“[消息剪辑]”注释也有新窗口。
请帮助我解决这个问题。
这是我用来获取自定义 html 格式的代码:
import pandas as pd
import re
from bs4 import BeautifulSoup
class GenerateHTMLReport:
def __init__(self, debug_logger):
self.debug_logger = debug_logger
def get_styled_html(self, origin_df, source_df, course_df, state_df, city_df):
origin_html = origin_df.to_html(index=False)
source_html = source_df.to_html(index=False)
course_html = course_df.to_html(index=False)
state_html = state_df.to_html(index=False)
city_html = city_df.to_html(index=False)
soup_origin = BeautifulSoup(origin_html, 'html.parser')
soup_source = BeautifulSoup(source_html, 'html.parser')
soup_course = BeautifulSoup(course_html, 'html.parser')
soup_state = BeautifulSoup(state_html, 'html.parser')
soup_city = BeautifulSoup(city_html, 'html.parser')
for table in soup_origin.find_all('table') + soup_source.find_all('table') + soup_course.find_all('table') + soup_state.find_all('table') + soup_city.find_all('table'):
table['style'] = "border:1px solid black;border-collapse:collapse"
for th in soup_origin.find_all('th') + soup_source.find_all('th') + soup_course.find_all('th') + soup_state.find_all('th') + soup_city.find_all('th'):
th['style'] = "border:1px solid black;border-collapse:collapse;padding:2px;background-color:yellow;text-align:center"
th['bgcolor'] = "yellow"
th['align'] = "center"
for table in soup_origin.find_all('table') + soup_source.find_all('table') + soup_course.find_all('table') + soup_state.find_all('table') + soup_city.find_all('table'):
rows = table.find_all('tr')
for row in rows:
cells = row.find_all('td')
if any(cell.text.strip() == 'Grand Total' for cell in cells):
for cell in cells:
cell['style'] = "border:1px solid black;border-collapse:collapse;padding:2px;background-color:#d7e4fb;text-align:center"
cell['bgcolor'] = "#d7e4fb"
cell['align'] = "center"
else:
for cell in cells:
cell['style'] = "border:1px solid black;border-collapse:collapse;padding:2px;background-color:white;text-align:center"
cell['bgcolor'] = "white"
cell['align'] = "center"
leave_line = """<div><br></div>"""
full_html = str(soup_origin) + leave_line + str(soup_source) + leave_line + str(soup_course) + leave_line + str(soup_state) + leave_line + str(soup_city)
return full_html
这是我用来发送电子邮件的:
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
from email.mime.text import MIMEText
import yaml
from pandas.io.formats.style import Styler
import pandas as pd
from reports_tohtml import GenerateHTMLReport
class Emailer:
def __init__(self, debug_logger) -> None:
self.debug_logger = debug_logger
self.html_rep = GenerateHTMLReport(self.debug_logger)
def sorting_emailer(self, originwise_report, sourcewise_report, coursewise_report, statewise_report, citywise_report ,college_name, college_id, end_date, subject_college_name, subject_college_id) -> None:
try:
self.originwise_report = originwise_report
self.sourcewise_report = sourcewise_report
self.coursewise_report = coursewise_report
self.statewise_report = statewise_report
self.citywise_report = citywise_report
# print(f" self.originwise_report ==> \n{self.originwise_report}")
# print(f"self.sourcewise_report ==> \n{self.sourcewise_report}")
self.college_name = college_name
self.college_id = college_id
self.end_date = end_date
self.subject_college_name = subject_college_name
self.subject_college_id = subject_college_id
# self.subject = f'({college_id}) | {college_name} | NPF Daily Leads Report'
self.subject = f'({self.subject_college_id}) | {self.subject_college_name} | NPF Daily Leads Report'
self.body = f'Hi, PFA the {self.college_name} Daily Report till {self.end_date}.'
except Exception as e:
self.debug_logger.error(f'Error in sorting_data_emailer: {e}')
def emailer(self, sender_email, receiver_email, athentication_file):
# with open('/home/npf_daily_report/pwd.yml', 'r') as file: #for hari sharma email
# with open('/home/npf_daily_report/pwd_ops.yml', 'r') as file: #for central operations email
with open(athentication_file, 'r') as file:
content = file.read()
creds = yaml.load(content, yaml.FullLoader)
user = creds['user']
password = creds['password']
smtp_server = 'smtp.gmail.com'
smtp_port = 587
smtp_username = user
smtp_password = password
# Create a multipart message object
msg = MIMEMultipart()
# Set email headers
msg['From'] = sender_email
msg['To'] = receiver_email
msg['Subject'] = self.subject
receiver_emails_li = [email.strip() for email in receiver_email.split(',')]
msg.attach(MIMEText(self.body, 'plain'))
html = self.html_rep.get_styled_html(self.originwise_report, self.sourcewise_report, self.coursewise_report, self.statewise_report, self.citywise_report)
msg.attach(MIMEText(html, 'html'))
# Attach the CSV file
# attachment = MIMEApplication(file.read(), _subtype="csv")
# attachment.add_header('Content-Disposition', 'attachment', filename='Ganga Group of Institutions.csv')
# msg.attach(attachment)
try:
#Connect to the SMTP server
server = smtplib.SMTP(smtp_server, smtp_port)
server.starttls()
#Log in to your email account
server.login(smtp_username, smtp_password)
#Send the email
server.sendmail(sender_email, receiver_emails_li, msg.as_string())
#Close the SMTP server connection
server.quit()
print('Email sent successfully.')
except Exception as e:
print('Email Error: ', str(e))
在GenerateHTMLReport类中添加save_html_report方法:
def save_html_report(自身,origin_df,source_df,course_df,state_df,city_df,文件名): html_content = self.get_styled_html(origin_df, source_df, course_df, state_df, city_df) 打开(文件名,'w',编码='utf-8')作为文件: 文件.write(html_content)
修改Emailer类中的emailer方法: 使用以下代码替换现有的电子邮件程序方法:
def emailer(self, sender_email,receiver_email,authentication_file):
with open(athentication_file, 'r') as file:
content = file.read()
creds = yaml.load(content, yaml.FullLoader)
user = creds['user']
password = creds['password']
smtp_server = 'smtp.gmail.com'
smtp_port = 587
smtp_username = user
smtp_password = password
# Create a multipart message object
msg = MIMEMultipart()
# Set email headers
msg['From'] = sender_email
msg['To'] = receiver_email
msg['Subject'] = self.subject
receiver_emails_li = [email.strip() for email in receiver_email.split(',')]
msg.attach(MIMEText(self.body, 'plain'))
# Generate and save the HTML report
html_report_file = 'report.html'
self.html_rep.save_html_report(self.originwise_report, self.sourcewise_report, self.coursewise_report, self.statewise_report, self.citywise_report, html_report_file)
# Attach the HTML file
with open(html_report_file, 'rb') as file:
attachment = MIMEApplication(file.read(), _subtype="html")
attachment.add_header('Content-Disposition', 'attachment', filename=html_report_file)
msg.attach(attachment)
try:
# Connect to the SMTP server
server = smtplib.SMTP(smtp_server, smtp_port)
server.starttls()
# Log in to your email account
server.login(smtp_username, smtp_password)
# Send the email
server.sendmail(sender_email, receiver_emails_li, msg.as_string())
# Close the SMTP server connection
server.quit()
print('Email sent successfully.')
except Exception as e:
print('Email Error: ', str(e))
您可以通过将报告作为附件发送来避免 gmail 对电子邮件正文内容的大小限制,收件人可以下载并查看完整的报告,而不会遇到剪切问题