You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,提问作者Алексей Котов

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 09:35:24