Telegram机器人自动生成PDF报告完整教程:从数据采集到定时发送

手把手教你用Telegram机器人自动生成PDF报告,涵盖ReportLab、WeasyPrint和Playwright三种主流方案,并附定时发送与异常处理实战代码。

阅读提示建议先浏览小标题,再根据需要深入阅读具体段落。

在日常工作中,无论是运营日报、销售周报还是个人复盘,定期生成PDF报告都是一项重复且易出错的任务。通过Telegram机器人自动生成PDF报告,不仅能解放双手,还能确保报告按时送达、格式统一。本文将带你从零开始,掌握三种主流的PDF生成方案,并赋予机器人定时发送的能力。

一、方案总览:根据场景选择合适的技术

在动手之前,我们先明确三种方案各自的适用场景:

  • ReportLab:完全以编程方式描述文档布局,适合结构固定、数据量大的表格型报告,无需额外依赖。
  • WeasyPrint:将HTML+CSS渲染为PDF,适合熟悉前端样式的开发者,能快速生成美观的图文报告。
  • Playwright:通过无头浏览器加载网页并打印为PDF,适合需要JavaScript动态渲染、带有图表或复杂交互的页面。

如果报告内容简单且数据多为文本表格,推荐ReportLab;若追求视觉效果且掌握HTML/CSS,则选WeasyPrint;若报告依赖前端图表库(如ECharts),Playwright是唯一选择。

二、环境准备与机器人创建

工欲善其事,必先利其器。我们按以下步骤搭建基础环境:

  1. 在Telegram中向@BotFather发送/newbot,按提示创建机器人并获取API Token。
  2. 安装Python 3.8+,并创建虚拟环境(推荐)。
  3. 安装核心依赖:
pip install python-telegram-bot reportlab weasyprint playwright apscheduler

此外,Playwright还需要安装浏览器内核:

python -m playwright install chromium

三、方案一:使用ReportLab直接生成PDF

ReportLab是Python最成熟的PDF库之一,适合构建数据驱动的报表。以下示例展示如何生成包含标题和表格的PDF:

from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph
from reportlab.lib.styles import getSampleStyleSheet

# 数据准备
headers = ["日期", "新增用户", "活跃用户"]
data = [["2025-01-01", 120, 980], ["2025-01-02", 135, 1020]]
table_data = [headers] + data

# 创建PDF
doc = SimpleDocTemplate("report.pdf", pagesize=A4)
styles = getSampleStyleSheet()
title = Paragraph("用户增长日报", styles["Title"])
table = Table(table_data)
table.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), colors.grey),
    ("TEXTCOLOR", (0,0), (-1,0), colors.whitesmoke),
    ("GRID", (0,0), (-1,-1), 1, colors.black),
]))
doc.build([title, table])

此代码将生成名为report.pdf的本地文件,随后可通过Bot.send_document发送给用户。

四、方案二:使用HTML模板+WeasyPrint渲染

WeasyPrint能将HTML+CSS转换为精美的PDF,非常适合拥有前端功底的开发者。我们先生成HTML字符串,再调用API转换:

from weasyprint import HTML

html_content = """
<html>
<head>
<style>
body { font-family: "Microsoft YaHei"; }
h1 { color: #333; }
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ccc; padding: 8px; text-align: left; }
</style>
</head>
<body>
<h1>业务周报</h1>
<table>
  <tr><th>指标</th><th>数值</th></tr>
  <tr><td>营收(万)</td><td>128.6</td></tr>
</table>
</body>
</html>
"""
HTML(string=html_content).write_pdf("report.pdf")

注意:若报告包含中文字体,需在CSS中明确指定系统已安装的中文字体,否则会产生乱码。

五、方案三:使用Playwright渲染网页为PDF

当报告页面使用JavaScript动态渲染图表时,Playwright是最佳选择。它模拟真实浏览器,能够完整加载页面后再执行打印:

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch()
    page = browser.new_page()
    # 打开本地HTML或在线URL
    page.goto("https://example.com/report")
    # 等待图表加载(示例)
    page.wait_for_selector(".chart-container")
    page.pdf(path="report.pdf", format="A4")
    browser.close()

这种方法能够保持网页的动态效果和精确排版,但资源占用较高,适合对视觉质量有严格要求的报告。

六、定时发送报告:让机器人成为你的小助手

有了PDF生成能力,我们还需要让机器人按照预设时间自动发送。这里使用APScheduler的CronTrigger,实现每日上午9点发送到指定群组或频道:

from telegram import Bot
from telegram.ext import Updater
import asyncio
from apscheduler.schedulers.asyncio import AsyncIOScheduler

BOT_TOKEN = "你的TOKEN"
CHAT_ID = -100123456789  # 目标群组/频道ID

async def generate_and_send():
    # 假设已经存在生成PDF的函数 generate_pdf()
    await asyncio.to_thread(generate_pdf)
    bot = Bot(token=BOT_TOKEN)
    with open("report.pdf", "rb") as f:
        await bot.send_document(chat_id=CHAT_ID, document=f, filename="日报.pdf")

scheduler = AsyncIOScheduler()
scheduler.add_job(generate_and_send, trigger="cron", hour=9, minute=0, timezone="Asia/Shanghai")
scheduler.start()

# 启动机器人运行循环
updater = Updater(token=BOT_TOKEN, use_context=True)
updater.start_polling()
updater.idle()

如果不想启用额外的调度器,也可以使用Python标准库的time.sleep结合循环,但APScheduler更灵活、更稳健。

七、异常处理与日志记录

自动化脚本长期运行难免遇到网络波动、API限流等问题。务必添加异常捕获和日志记录,以便快速定位问题:

import logging
import traceback

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

async def safe_generate_and_send():
    try:
        await generate_and_send()
    except Exception as e:
        logger.error(f"发送失败:")
        # 可在此增加告警通知,例如发送错误消息给管理员
        await bot.send_message(chat_id=ADMIN_ID, text=f"报告生成失败:{traceback.format_exc()}")

八、总结

通过以上三种方案,你已经能够覆盖从简单表格到复杂可视化报告的所有场景。将PDF生成与Bot API结合,再配上定时任务,即可轻松打造一个自动化的报告分发系统。最后提醒两点:一是报告内容可能涉及用户隐私,务必脱敏处理;二是Telegram限制单文件最大50MB,输出前请检查文件大小。

现在就可以动手尝试,让你的Telegram机器人成为你的私人数据助理。

FAQ

安装与配置指南

常见问题

如何让机器人每天自动发送PDF报告?

可以使用APScheduler的CronTrigger为异步任务设置定时触发,例如每天上午9点执行生成和发送函数。注意设置正确的时区,并确保调度器与机器人运行在同一事件循环中。

生成的PDF报告中文字体乱码怎么办?

在ReportLab中,需要先注册中文字体,例如使用reportlab.pdfbase.pdfmetrics.registerFont并指定中文字体文件;在使用WeasyPrint时,需要在CSS中设置font-family为系统已安装的中文字体,如'Microsoft YaHei'或'Noto Sans CJK SC'。

Telegram机器人发送PDF文件的大小限制是多少?

Telegram Bot API限制单次发送文件最大50MB。如果生成的PDF超过该限制,建议压缩图片、优化嵌入字体或拆分报告为多个文件发送。