Python Telegram Bot中DataFrame表格格式化及远程存图问题
解决方案与代码示例
一、将DataFrame转为PNG并通过Paramiko直接上传到SSH服务器(无本地文件)
核心思路是用内存缓冲区(BytesIO)存储生成的图片数据,再通过Paramiko的SFTP直接上传,全程不落地本地文件。
依赖库安装
先确保安装所需包:
pip install pandas matplotlib paramiko
示例代码
import pandas as pd import matplotlib.pyplot as plt from io import BytesIO import paramiko # 1. 生成测试DataFrame data = { '列1': [1, 2, 3, 4, 5], '列2': ['A', 'B', 'C', 'D', 'E'], '列3': [10.5, 20.3, 15.7, 8.9, 25.1], '列4': [True, False, True, True, False], '列5': ['2024-01-01', '2024-01-02', '2024-01-03', '2024-01-04', '2024-01-05'] } df = pd.DataFrame(data) # 2. 将DataFrame绘制成图片并写入内存缓冲区 fig, ax = plt.subplots(figsize=(10, 3)) # 调整尺寸适配5列数据 ax.axis('tight') ax.axis('off') table = ax.table(cellText=df.values, colLabels=df.columns, loc='center') # 调整表格样式,避免内容拥挤 table.auto_set_font_size(False) table.set_fontsize(10) table.scale(1.2, 1.5) # 缩放表格,适配列宽 # 保存到内存缓冲区 buffer = BytesIO() plt.savefig(buffer, format='png', bbox_inches='tight', dpi=150) buffer.seek(0) # 重置缓冲区指针到开头 # 3. 通过Paramiko SFTP上传到远程服务器 ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 连接远程服务器(替换为你的服务器信息) ssh.connect( hostname='your-remote-host', username='your-username', password='your-password' # 或用密钥:key_filename='path/to/private/key' ) sftp = ssh.open_sftp() # 上传缓冲区内容到远程文件(替换为你的远程路径) with sftp.file('/remote/path/to/save/df_table.png', 'wb') as f: f.write(buffer.getvalue()) # 关闭连接 sftp.close() ssh.close() plt.close(fig) # 释放绘图资源
注意事项
- 调整
figsize和table.scale参数可以优化表格的显示效果,避免列内容重叠 - 如果服务器用密钥认证,替换
password参数为key_filename,指向你的私钥路径 - 若DataFrame行数较多,可调整
figsize的高度,或分页生成图片
二、Telegram聊天窗口的DataFrame格式化优化
如果直接格式化文本无效,大概率是Telegram的Markdown/HTML渲染限制导致的,试试以下方案:
方案1:使用HTML表格格式发送
Telegram支持HTML格式的消息,用<table>标签构建表格,强制设置列宽或使用等宽字体:
import telebot bot = telebot.TeleBot('your-bot-token') def df_to_html(df): # 生成HTML表格,添加样式适配Telegram html = '<pre><table border="1">' # 添加表头 html += '<tr>' for col in df.columns: html += f'<th>{col}</th>' html += '</tr>' # 添加行数据 for _, row in df.iterrows(): html += '<tr>' for val in row: html += f'<td>{val}</td>' html += '</tr>' html += '</table></pre>' return html # 发送消息 chat_id = 'your-chat-id' bot.send_message(chat_id, df_to_html(df), parse_mode='HTML')
方案2:拆分表格为多块
如果5列过宽导致换行错乱,可以将DataFrame拆分为左右两部分,分开发送:
# 拆分DataFrame为前3列和后2列 df_left = df.iloc[:, :3] df_right = df.iloc[:, 3:] # 分别转为格式化文本发送 bot.send_message(chat_id, str(df_left), parse_mode='MarkdownV2') bot.send_message(chat_id, str(df_right), parse_mode='MarkdownV2')
方案3:使用等宽字体包裹表格
Telegram的等宽字体(用<pre>标签)可以让表格对齐更准确:
def df_to_monospace(df): return f'<pre>{df.to_string(index=False)}</pre>' bot.send_message(chat_id, df_to_monospace(df), parse_mode='HTML')
内容的提问来源于stack exchange,提问作者Алексей Котов
相关产品推荐
相关产品推荐

