创建 PDF 并使用烧瓶邮件作为附件发送
Posted
技术标签:
【中文标题】创建 PDF 并使用烧瓶邮件作为附件发送【英文标题】:Create a PDF and send as attachment with flask-mail 【发布时间】:2021-07-29 11:15:01 【问题描述】:我正在尝试使用 pdf-kit 从 html 页面创建 PDF,然后将该 pdf 作为电子邮件的附件发送。
这是我创建 pdf 的代码,这似乎有效:
html = render_template("office_report.html",role=role, name=name,owner=off,reps=reps,all_weekly=all_weekly,we=we,totals=totals,cog=cog,all_weekly_rpt=True,off_rpt=off_rpt,v=v,adonors=adonors,ae=ae,ov=ov,pay_total=pay_total)
options = "enable-local-file-access": None
try:
pdf=pdfkit.from_string(html,False,options=options)
files = pdf
except Exception as e:
print(e)
pdf='ERROR'
然后我尝试发送电子邮件,但不明白如何将 PDF 附加到电子邮件。
try:
msg = Message('Owner Report ', sender = ("Brand Drivers",BD), recipients = ['jesswholt@gmail.com',BD,comp])
msg.body = "Weekly Report" + str(we)
with app.open_resource(files) as fp:
msg.attach("Owner Report", "invoice/pdf", fp.read())
mail.mail.send(msg)
print('sent')
except Exception as e:
print(e)
这里是转换成 PDF 的 HTML
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<title>Childhelp</title>
<meta content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0' name='viewport' />
<meta name="viewport" content="width=device-width" />
</head>
<body>
<div class="header">
<h4 class="title">Office Report <br>owner.owner_name<br>owner.office_ID</h4>
<p>WeekEnding: we.strftime('%m-%d-%Y')</p>
</div>
<table id="office_weekly" class="table table-hover table-striped">
<thead>
<th>Ambassador</th>
<th>Transactions</th>
<th>Total Payments</th>
<th>Items Sold</th>
<th>Hotlines</th>
<th>Bonuses</th>
<!-- <th>Total</th>-->
</thead>
<tbody>
% for r in reps %
<tr>
<td>
<strong>r.rep_name</strong><br>
r.rep_ID
</td>
% for w in all_weekly if w.rep == r.rep_ID %
<td>w.transactions</td>
<td>
Cash: $w.cash/100<br>
Check: $w.check/100<br>
Card: $w.card/100<br>
<strong>Total: $w.total/100</strong>
</td>
<td>
Sold: w.tot_itm<br>
Refunded: w.refunds<br>
Amount Refunded: "$%.2f" % (w.amount_refunded/100)<br>
Refund Dates w.dates_refunded
</td>
<td>
Active: w.subs<br>
Cancels: w.can
</td>
<td>"$%.2f" % (w.bonus | float)</td>
% else %
<td></td>
<td></td>
<td></td>
<td></td>
<td>Report Incomplete</td>
</tr>
% endfor %
% endfor %
<tr>
<td><hr></td>
<td><hr></td>
<td><hr></td>
<td><hr></td>
<td><hr></td>
<td><hr></td>
</tr>
</tbody>
<tbody>
<tr>
<th></th>
</tr>
<td>Office Sub Total:</td>
<td>totals.transactions
</td>
<td>
Cash: totals.cash<br>
Check: totals.check<br>
Card: totals.card<br>
Total: totals.sales<br>
Overrides: "$%.2f" % (ov | float)
</td>
<td>
Items: totals.t_items<br>
COG: "$%.2f" % (cog) per piece<br>
Total COG: "$%.2f" % (totals.total_cog)
</td>
<td>
Total Hotlines for Office:<br>
Active: totals.hotlines<br>
Canceled: totals.cancels<br>
Total Pay Hotlines: "$%.2f" % (totals.hotlines | float * 15)
</td>
<td>
Total Bonuses Paid: totals.bonus<br>
Items Refunded: totals.items_refunded<br>
Amount Refunded: totals.amount_refunded / 100
</td>
</tbody>
<tbody>
<tr>
<th> Line Items</th>
</tr>
<td></td>
<td></td>
<td><strong>Balance Carry: off_rpt.balance_carry</strong></td>
</tbody>
<tbody>
<td></td>
<td></td>
<td><strong>Deposit: off_rpt.deposit</strong></td>
</tbody>
<tbody>
<td></td>
<td></td>
<td><strong>Events: totals.events</strong></td>
</tbody>
<tbody>
<td></td>
<td></td>
<td><strong>Line Items:</strong></td>
<td>
Name: v.li1_n<br>
Amount: $v.li1_p<br>
Name: v.li2_n<br>
Amount: $v.li2_p<br>
Name: v.li3_n<br>
Amount: $v.li3_p<br>
Name: v.li4_n<br>
Amount: $v.li4_p
</td>
</tbody>
<tbody>
<td></td>
<td></td>
<td></td>
<td></td>
% if pay_total %
<td><strong>Owner Payout:</strong></td>
<td><strong>"$%.2f" % (pay_total | float)</strong></td>
% else %
<td><strong>Card Sales:</strong></td>
<td><strong>totals.card</strong></td>
% endif %
</tbody>
<tbody>
<td>
<h3>Hotline Signups</h3>
</td>
</tbody>
<thead>
<th>Donor Name</th>
<th>Ambassador</th>
<th>Signup Date</th>
<th>Canceled</th>
<!-- <th>Total</th>-->
</thead>
<tbody>
% for d in adonors %
<tr>
<td>d.donor_name</td>
% for x in reps if x.rep_ID == d.rep_ID %
<td>x.rep_name<br>x.rep_ID</td>
% endfor %
<td>d.monthly_start_date</td>
% if d.donor_status == False %
<td>d.monthly_stop_date</td>
% else %
<td style="color:green">Active</td>
% endif %
</tr>
% endfor %
</tbody>
</table>
<div class="col-md-18">
</div>
</body>
</html>
【问题讨论】:
【参考方案1】:而不是这个:
with app.open_resource(files) as fp:
msg.attach("Owner Report", "invoice/pdf", fp.read())
这样做:
msg.attach("Owner Report", "invoice/pdf", pdf)
pdf
(或files
)包含您的文件作为字节类型对象。所以你不需要使用open_resource
来读取文件,因为你已经有了你需要的数据。
【讨论】:
当我尝试这种方式时,它会发送一个空白附件? 可以列出pdf
和html
的值吗?
是的,如果我返回 HTML,它会完美运行,如果我调用 print(pdf),它会在终端中打印
对不起,我的意思是如果您可以将这些变量的输出添加到问题中,以便可以重现空白附件问题。仅html
的输出可能就足够了。
我已将 HTML 添加到原始问题中以上是关于创建 PDF 并使用烧瓶邮件作为附件发送的主要内容,如果未能解决你的问题,请参考以下文章