在日常工作中,无论是运营日报、销售周报还是个人复盘,定期生成PDF报告都是一项重复且易出错的任务。通过Telegram机器人自动生成PDF报告,不仅能解放双手,还能确保报告按时送达、格式统一。本文将带你从零开始,掌握三种主流的PDF生成方案,并赋予机器人定时发送的能力。
一、方案总览:根据场景选择合适的技术
在动手之前,我们先明确三种方案各自的适用场景:
- ReportLab:完全以编程方式描述文档布局,适合结构固定、数据量大的表格型报告,无需额外依赖。
- WeasyPrint:将HTML+CSS渲染为PDF,适合熟悉前端样式的开发者,能快速生成美观的图文报告。
- Playwright:通过无头浏览器加载网页并打印为PDF,适合需要JavaScript动态渲染、带有图表或复杂交互的页面。
如果报告内容简单且数据多为文本表格,推荐ReportLab;若追求视觉效果且掌握HTML/CSS,则选WeasyPrint;若报告依赖前端图表库(如ECharts),Playwright是唯一选择。
二、环境准备与机器人创建
工欲善其事,必先利其器。我们按以下步骤搭建基础环境:
- 在Telegram中向@BotFather发送
/newbot,按提示创建机器人并获取API Token。 - 安装Python 3.8+,并创建虚拟环境(推荐)。
- 安装核心依赖:
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机器人成为你的私人数据助理。