影刀RPA进阶教程:Python自动生成数据可视化图表与飞书日报
影刀RPA进阶教程:Python自动生成数据可视化图表与飞书日报
痛点切入
我之前带的运营团队有个固定流程:每天早上9点,从各个平台导出前一天数据,手动粘到Excel里,再做成柱状图、折线图,截图发飞书群。一套流程下来至少40分钟。关键是图表长得还不统一——张三用蓝柱子、李四用红柱子,配色随心所欲,领导看起来很不专业。
后来我用影刀RPA搭了一套自动化方案:每天凌晨自动采集数据 → Python自动生成图表 → 飞书机器人推送日报。按这个方案跑了一年多,出错率为零,还省出了一个实习生的成本。这篇文章就把这个方案完整拆解给你。

核心方法
场景:电商多平台销售日报自动生成
某运营团队管理天猫、京东、拼多多三个平台,每天需要:
- 自动采集三个平台的昨日销售数据
- 生成销售额对比柱状图、品类占比饼图、7日趋势折线图
- 三张图自动拼成一张日报长图
- 通过飞书机器人推送到指定群聊
分步操作

第一步:数据采集与汇总
在影刀中搭建采集流程:
- 「打开网页」→ 登录各平台后台
- 「数据抓取」→ 抓取销售额、订单量、客单价、退货率
- 「Excel写入」→ 写入统一格式的汇总表
汇总表结构(D:\数据\日报数据源.xlsx):
| 日期 | 平台 | 销售额 | 订单量 | 客单价 | 退货率 |
|---|---|---|---|---|---|
| 2026-06-30 | 天猫 | 85000 | 1200 | 70.8 | 3.2% |
| 2026-06-30 | 京东 | 62000 | 850 | 72.9 | 2.1% |
![]() |
| 2026-06-30 | 拼多多 | 43000 | 950 | 45.3 | 4.5% |
第二步:Python生成图表
拖入「Python脚本」节点,核心代码:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
影刀RPA — 自动生成数据可视化日报图表
功能:读取Excel数据源 → 生成柱状图/饼图/趋势图 → 合成日报长图
作者:林焱
"""
import pandas as pd
import matplotlib
matplotlib.use('Agg') # 无GUI后端,影刀环境下必须设置
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
from matplotlib import font_manager
import os
from datetime import datetime, timedelta
# ========== 字体配置 ==========
# Windows环境指定中文字体,否则图表中文会显示为方框
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei', 'SimHei', 'Arial Unicode MS']
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
# ===============================
def create_daily_report():
"""
主函数:生成完整日报图表
数据来源:影刀前置流程写入的Excel
"""
# ========== 1. 读取数据 ==========
data_file = r"D:\数据\日报数据源.xlsx"
df = pd.read_excel(data_file, sheet_name="汇总")
# 获取昨日日期用于图表标题
yesterday = (datetime.now() - timedelta(days=1)).strftime("%Y-%m-%d")
# 输出目录
output_dir = r"D:\数据\日报图表"
os.makedirs(output_dir, exist_ok=True)
# ========== 2. 设置统一的视觉风格 ==========
# 公司配色方案(你可以改成自己公司的VI色)
COLORS = {
'天猫': '#FF6B6B', # 珊瑚红
'京东': '#4ECDC4', # 青绿色
'拼多多': '#FFE66D', # 明黄色
'正面': '#2ECC71',
'负面': '#E74C3C',
'中性': '#3498DB'
}
plt.style.use('seaborn-v0_8-whitegrid')
# ========== 3. 生成图表1:平台销售额对比柱状图 ==========
fig1, ax1 = plt.subplots(figsize=(10, 6))
today_data = df[df['日期'] == yesterday]
platforms = today_data['平台'].tolist()
sales = today_data['销售额'].tolist()
bars = ax1.bar(
platforms,
sales,
color=[COLORS.get(p, '#95A5A6') for p in platforms],
width=0.5,
edgecolor='white',
linewidth=0.8
)
# 在柱子上标注数值
for bar, val in zip(bars, sales):
ax1.text(
bar.get_x() + bar.get_width()/2,
bar.get_height() + 1000,
f'{val/10000:.1f}万',
ha='center', va='bottom',
fontsize=12, fontweight='bold'
)
ax1.set_title(f'{yesterday} 各平台销售额对比', fontsize=18, fontweight='bold', pad=15)
ax1.set_ylabel('销售额(元)', fontsize=12)
ax1.yaxis.set_major_formatter(ticker.FuncFormatter(lambda x, _: f'{x/10000:.0f}万'))
ax1.spines['top'].set_visible(False)
ax1.spines['right'].set_visible(False)
chart1_path = os.path.join(output_dir, f'chart1_sales_{yesterday}.png')
fig1.savefig(chart1_path, dpi=150, bbox_inches='tight', facecolor='white')
plt.close(fig1)
print(f"[√] 柱状图已保存: {chart1_path}")
# ========== 4. 生成图表2:品类销售额占比饼图 ==========
# 假设品类数据在另一个sheet
category_df = pd.read_excel(data_file, sheet_name="品类明细")
cat_today = category_df[category_df['日期'] == yesterday]
fig2, ax2 = plt.subplots(figsize=(8, 8))
labels = cat_today['品类'].tolist()
values = cat_today['销售额'].tolist()
explode = [0.03] * len(labels) # 所有扇区轻微分离
wedges, texts, autotexts = ax2.pie(
values,
labels=labels,
autopct='%1.1f%%',
startangle=90,
explode=explode,
colors=['#FF6B6B', '#4ECDC4', '#FFE66D', '#95A5A6', '#3498DB', '#9B59B6'],
textprops={'fontsize': 11}
)
# 百分比文字加粗
for at in autotexts:
at.set_fontweight('bold')
ax2.set_title(f'{yesterday} 品类销售额占比', fontsize=18, fontweight='bold', pad=20)
chart2_path = os.path.join(output_dir, f'chart2_category_{yesterday}.png')
fig2.savefig(chart2_path, dpi=150, bbox_inches='tight', facecolor='white')
plt.close(fig2)
print(f"[√] 饼图已保存: {chart2_path}")
# ========== 5. 生成图表3:7日销售额趋势折线图 ==========
last_7_days = []
for i in range(6, -1, -1):
last_7_days.append((datetime.now() - timedelta(days=i+1)).strftime("%Y-%m-%d"))
trend_df = df[df['日期'].isin(last_7_days)]
fig3, ax3 = plt.subplots(figsize=(12, 5))
for platform in ['天猫', '京东', '拼多多']:
p_data = trend_df[trend_df['平台'] == platform]
p_data = p_data.sort_values('日期')
ax3.plot(
p_data['日期'], p_data['销售额'],
marker='o', linewidth=2.5, markersize=8,
label=platform,
color=COLORS.get(platform)
)
# 标注数值点
for _, row in p_data.iterrows():
ax3.annotate(
f"{row['销售额']/10000:.1f}万",
(row['日期'], row['销售额']),
textcoords="offset points",
xytext=(0, 12),
ha='center', fontsize=9
)
ax3.set_title('近7日销售额趋势', fontsize=18, fontweight='bold', pad=15)
ax3.set_ylabel('销售额(元)', fontsize=12)
ax3.yaxis.set_major_formatter(ticker.FuncFormatter(lambda x, _: f'{x/10000:.0f}万'))
ax3.legend(loc='upper left', frameon=True, fontsize=11)
ax3.tick_params(axis='x', rotation=30)
ax3.spines['top'].set_visible(False)
ax3.spines['right'].set_visible(False)
ax3.grid(True, alpha=0.3)
chart3_path = os.path.join(output_dir, f'chart3_trend_{yesterday}.png')
fig3.savefig(chart3_path, dpi=150, bbox_inches='tight', facecolor='white')
plt.close(fig3)
print(f"[√] 趋势图已保存: {chart3_path}")
# ========== 6. 合成日报长图 ==========
from PIL import Image
img1 = Image.open(chart1_path)
img2 = Image.open(chart2_path)
img3 = Image.open(chart3_path)
# 统一宽度
target_width = 1200
img2_resized = img2.resize((target_width, int(img2.height * target_width / img2.width)))
img1_resized = img1.resize((target_width, int(img1.height * target_width / img1.width)))
img3_resized = img3.resize((target_width, int(img3.height * target_width / img3.width)))
# 垂直拼接 + 标题区域
title_height = 80
total_height = title_height + img1_resized.height + img2_resized.height + img3_resized.height + 60
report_img = Image.new('RGB', (target_width + 40, total_height), 'white')
# 这里可以用PIL绘制标题文字(略),实际项目中我用了影刀的截图拼接功能
# 简单拼接方式:
y_offset = 20
report_img.paste(img1_resized, (20, y_offset))
y_offset += img1_resized.height + 10
report_img.paste(img2_resized, (20, y_offset))
y_offset += img2_resized.height + 10
report_img.paste(img3_resized, (20, y_offset))
report_path = os.path.join(output_dir, f'日报_{yesterday}.png')
report_img.save(report_path, quality=95)
print(f"[√] 日报长图已合成: {report_path}")
# ========== 7. 返回文件路径给影刀变量 ==========
SetVariable("report_image_path", report_path)
SetVariable("chart1_path", chart1_path)
SetVariable("chart2_path", chart2_path)
SetVariable("chart3_path", chart3_path)
return report_path
# 执行
report_file = create_daily_report()
print(f"\n日报生成完成!文件路径: {report_file}")
第三步:飞书机器人推送
在影刀中接上一个「HTTP请求」节点,调用飞书机器人Webhook:

# 飞书消息推送 — Python节点
import requests
import json
report_path = GetVariable("report_image_path")
yesterday = GetVariable("yesterday_date") # 由前置流程计算好
# 飞书机器人Webhook地址(在飞书群设置→群机器人→添加自定义机器人获取)
WEBHOOK_URL = "https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxxxxxx"
# ========== 方案A:发送图片(需先上传获取image_key)==========
# 第一步:上传图片
upload_url = "https://open.feishu.cn/open-apis/im/v1/images"
# 详细上传逻辑参考飞书文档,这里用方案B更简单
# ========== 方案B:发送卡片消息(推荐)==========
card_msg = {
"msg_type": "interactive",
"card": {
"header": {
"title": {"tag": "plain_text", "content": f"📊 电商日报 - {yesterday}"},
"template": "red"
},
"elements": [
{
"tag": "markdown",
"content": f"**数据日期**:{yesterday}\n\n"
f"**天猫**:销售额8.5万 | 订单1200 | 退货率3.2%\n"
f"**京东**:销售额6.2万 | 订单850 | 退货率2.1%\n"
f"**拼多多**:销售额4.3万 | 订单950 | 退货率4.5%\n\n"
f"详细图表见下方图片 👇"
},
{
"tag": "img",
"img_key": "img_v2_xxxxxx", # 需先上传图片获取
"alt": {"tag": "plain_text", "content": "日报图表"}
},
{
"tag": "action",
"actions": [{
"tag": "button",
"text": {"tag": "plain_text", "content": "查看完整报表"},
"url": "https://你的BI看板地址",
"type": "default"
}]
}
]
}
}
resp = requests.post(WEBHOOK_URL, json=card_msg)
print(f"飞书推送结果: {resp.json()}")
第四步:影刀定时任务设置
在影刀应用列表中找到这个流程,点击「定时运行」:
- 触发方式:每天
- 执行时间:07:00(在运营上班前一小时跑完)
- 失败重试:3次,间隔5分钟
- 通知设置:失败时飞书通知你自己

注意点
- 中文字体问题:这绝对是最大的坑。Windows Server上经常没有中文字体,图表里的中文全部变方框。解决方法:
plt.rcParams['font.sans-serif']指定多个备选字体;或者在服务器上安装SimHei.ttf。 - matplotlib的Agg后端:影刀的Python节点没有GUI环境,必须设置
matplotlib.use('Agg'),否则报错TclError: no display name。 - 图片尺寸一致性:各平台数据量不同会导致图表大小不一致,合成时用PIL统一resize到固定宽度。
- 飞书图片上传:飞书卡片消息里的图片需要先上传获取image_key,不能直接传本地路径。可以先用HTTP请求上传,拿到key后再拼到卡片消息里。
常见问题速查
| 序号 | 现象 | 原因 | 解决方式 |
|---|---|---|---|
| 1 | 图表中文显示为方框□□□ | 系统缺少中文字体 | 安装SimHei.ttf到C:\Windows\Fonts;或下载字体文件后用font_manager指定路径 |
| 2 | Python节点报错TclError | 影刀Python环境无GUI | 在代码开头设置matplotlib.use('Agg') |
| 3 | 飞书图片推送失败 | 未上传获取image_key | 先用HTTP请求调用飞书上传图片接口,拿到image_key后再拼消息 |
| 4 | 柱状图颜色各不一样 | 未统一配色方案 | 在代码中定义COLORS字典,按平台名称映射固定颜色 |
![]() |
| 5 | 定时任务数据为空 | 采集流程在数据生成前就跑了 | 将定时执行时间设为平台数据更新之后再跑(一般上午8点后) |
| 6 | 图片清晰度不够 | 默认DPI=100太低 | savefig时设置dpi=150或更高 |
| 7 | 饼图标签重叠 | 分类太多或百分比太小 | 小于3%的合并为"其他";或用pctdistance参数调整位置 |
| 8 | excel读取报错No such file | 前置采集流程未完成 | 在Python节点前加一个「判断文件存在」节点,不存在则等待重试 |
推荐资源
内容标签:#RPA #数据可视化 #Python #matplotlib #飞书 #日报自动化 #电商运营

作者:林焱
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐




所有评论(0)