如何用Python将数据库查询数据以表格格式发送邮件?
问题分析与解决方案
你遇到的核心问题是:你直接把带有Jinja2模板语法的字符串当作HTML内容发送了,但没有用Flask的模板引擎去渲染它,所以邮箱收到的是未解析的模板代码,而不是生成好的表格。
方案一:用Flask模板引擎渲染HTML(推荐,适配你的现有代码)
你已经导入了Flask的模板相关模块,直接用render_template_string就能解析模板语法并传入数据。修改后的关键代码如下:
# 替换原来的html字符串定义和part2的创建逻辑 html_template = """ <html> <head></head> <body> <table border="1"> {% for row in results %} <tr> <td>{{ row[0] }}</td> <td>{{ row[1] }}</td> <td>{{ row[2] }}</td> <td>{{ row[3] }}</td> <td>{{ row[4] }}</td> </tr> {% endfor %} </table> </body> </html> """ # 用模板引擎渲染,把results数据传入模板解析 rendered_html = render_template_string(html_template, results=results) part2 = MIMEText(rendered_html, 'html')
注意两个关键修正:
- 模板里的
{% for row in {results} %}要改成{% for row in results %},不需要额外加花括号 - 要把
<tr>标签放到循环内部,不然所有数据单元格都会挤在同一行,这是你原模板的布局错误
方案二:手动拼接HTML表格(不依赖Flask,轻量化方案)
如果你的场景不需要Flask框架,也可以直接遍历数据库结果手动拼接HTML字符串,避免模板依赖:
# 手动构建表格HTML html_parts = [ '<html><head></head><body><table border="1">', ] # 可选:添加表头(可以从cursor.description获取真实列名) html_parts.append('<tr><th>列1</th><th>列2</th><th>列3</th><th>列4</th><th>列5</th></tr>') # 遍历数据生成每行内容 for row in results: td_cells = ''.join([f'<td>{cell}</td>' for cell in row[:5]]) html_parts.append(f'<tr>{td_cells}</tr>') # 拼接完整HTML html_parts.append('</table></body></html>') final_html = ''.join(html_parts) part2 = MIMEText(final_html, 'html')
额外优化建议
- 关闭数据库连接:你的代码里没有关闭游标和连接,获取数据后记得添加:
cursor.close() db_conn.close() - 异常捕获:数据库操作和邮件发送都可能出现网络或权限错误,建议用
try...except块包裹核心逻辑,避免程序崩溃。 - 动态表头:如果想显示真实的数据库列名,可以从游标对象里获取:
column_names = [desc[0] for desc in cursor.description] # 然后把column_names渲染成表头行
内容的提问来源于stack exchange,提问作者Gandharv pathak
相关产品推荐
相关产品推荐

