python调企业微信机器人API_发送图片

一、接口说明

图片类型.png

二、企业机器人发送图片消息

1、设计excel模板,截图生成图片

代码:

# -*- coding: utf-8 -*-
import requests
import hashlib
import base64
import xlwings as xw
import time,os
import pandas as pd
from PIL import ImageGrab
from openpyxl import load_workbook

#发送图片_传入图片本地路径/文本
def post_image(url,image):
    with open(image, 'rb') as file:
    #转换图片成base64格式
        data = file.read()
        encodestr = base64.b64encode(data)
        image_data = str(encodestr, 'utf-8')
    #图片的MD5值
    with open(image, 'rb') as file:
        md = hashlib.md5()
        md.update(file.read())
        image_md5 = md.hexdigest()
    data = {"msgtype": "image",
            "image": {"base64": image_data,
                      "md5": image_md5
                     }
            }
    result = requests.post(url, json=data)
    return(result)

# excel截图并发送
def photo_post(excel_file,n,url):
    app = xw.App(visible=True, add_book=False)  # 使用xlwings的app启动
    # 截图
    wb = app.books.open(excel_file)  # 打开文件
    num = 0
    while num < n:  # 参数 excel sheet 是第几个
        sheet = wb.sheets[num]  # 选定sheet
        photo_range = sheet.used_range  # 获取有内容的range
        # print(photo_range.value)
        photo_range.api.CopyPicture()  # 复制图片区域
        sheet.api.Paste()  # 粘贴
        img_name = 'photo' + str(num)
        pic = sheet.pictures[0]  # 当前图片
        pic.api.Copy()  # 复制图片
        time.sleep(10)

        img = ImageGrab.grabclipboard()  # 获取剪贴板的图片数据
        img_name = img_name + ".png"
        img.save(img_name)  # 保存图片

        post_image(url, img_name) # 发送图片
        num = num + 1
        pic.delete()  # 删除sheet上的图片
    wb.close()  # 之前已经保存,直接关闭
    app.quit()

# 指定sheet写入df
def add_sheet(excel_0, df_name, excel_1):
    # 写入源数据,Sheet:data
    wb = load_workbook(excel_0)
    ws = wb.get_sheet_by_name('data')
    value = df_name.to_numpy()
    for i in range(len(value)):
        ws.append(list(value[i]))
    # 写入时间,Sheet:pic
    now_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
    txt = '截止时间:' + str(now_time)
    ws2 = wb.get_sheet_by_name('pic')
    ws2.cell(row=2, column=4).value = txt

    wb.save(excel_1)
    wb.close()

if __name__ == "__main__":
    path_0 = os.path.dirname(__file__)
    excel_0 = path_0 + '/mb_0.xlsx' # excel原始模板
    excel_1 = path_0 + '/mb_1.xlsx' # 数据处理后的目标文件

    # 获取源数据--示例数据
    data_fruit = pd.DataFrame({'type':['圣女果','车厘子','草莓','香蕉','苹果','芒果','葡萄','沙糖桔','丑橘','西瓜','哈密瓜','牛奶枣'],
                           'sales_num':[1200,500,800,790,470,390,250,2560,1040,880,2800,300],
                           'sales_amt':[2.2,2.3,4.2,1.1,0.8,1.4,2.6,6.3,1.8,0.9,7.2,2.5]
                           })
    data_fruit['rank'] = data_fruit['sales_num'].rank(ascending=False, method='first') # 销量排名
    data_fruit = data_fruit[['rank','type','sales_num','sales_amt']]

    all_num = data_fruit['sales_num'].sum() # 销量总计
    all_amt = data_fruit['sales_amt'].sum() # 销售额总计
    df1 = pd.DataFrame({'rank':'总计','type':['总计'],'sales_num':[all_num],'sales_amt':[all_amt]})
    data_fruit = data_fruit.append(df1, ignore_index=True) # 新增总计记录

    # 数据写入模板excel的data Sheet中
    add_sheet(excel_0, data_fruit, excel_1)
    time.sleep(10)

    # 截图发送
    urlme = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx'
    photo_post(excel_1, 1, urlme)

执行结果:

excel模板_生成截图.png

说明:

思路大致可分为3步:
1、数据源获取与处理
2、数据源写入模板excel中,根据事先设置好的公式样式,自动生成所需表格样式
3、打开excel指定sheet,按需截图发送

excel模板如下:


excel模板_数据源sheet.png
excel模板_目标图片sheet.png

2、设计底图,往底图中写入数据

代码:

# -*- coding:utf-8 -*-
# 水果销售额大PK
import pandas as pd
import os,time,xlrd
import matplotlib.pyplot as plt
from PIL import Image, ImageFont, ImageDraw
import base64,hashlib,requests

#发送图片_传入图片本地路径/文本
def post_image(url,image):
    with open(image, 'rb') as file:
    #转换图片成base64格式
        data = file.read()
        encodestr = base64.b64encode(data)
        image_data = str(encodestr, 'utf-8')
    #图片的MD5值
    with open(image, 'rb') as file:
        md = hashlib.md5()
        md.update(file.read())
        image_md5 = md.hexdigest()
    data = {"msgtype": "image",
            "image": {"base64": image_data,
                      "md5": image_md5
                     }
            }
    result = requests.post(url, json=data)
    return(result)

# 获取pk水果信息
def read_infos(path):
    f = open(path,"r",encoding='utf-8-sig')
    lines = f.readlines()
    fruit_infos = {}
    for line in lines:
        line = line.strip('\n')
        a = line.split(',')
        a0 = a[0]
        a1 = a[1:]
        fruit_infos[a0] = {'fruit_infos':a1}
    f.close()
    print(fruit_infos)
    return(fruit_infos)

# 批量绘制 折线图
def draw_jpg(path, list_x):
    f, ax = plt.subplots(figsize=(14, 14))
    # 设置横轴,31天/30天均可用
    # 攻守分别为 0 1
    y1 = list_x[0]
    y2 = list_x[1]
    x = [i + 1 for i in range(len(y1))]

    # 设置 X轴长短 15日 元素*2 15日以后为31
    if len(y1) <= 10:
        lenth = 2 * len(y1)
        y3 = [yi0 * 3 for yi0 in list_x[0]]
        y4 = [yi1 * 3 for yi1 in list_x[1]]
    elif len(y1) <= 20:
        lenth = 1.5 * len(y1)
        y3 = [yi0 * 2 for yi0 in list_x[0]]
        y4 = [yi1 * 2 for yi1 in list_x[1]]
    else:
        lenth = 31
        y3 = y1
        y4 = y2
    axes = plt.axes()
    axes.set_xlim([0, lenth])
    plt.plot(x, y1, label='xxx', c='Coral', lw=15)
    plt.plot(x, y2, label='yyy', c='slategray', lw=15)
    plt.plot(x, y3, label='xxx', c='white', lw=1)
    plt.plot(x, y4, label='yyy', c='white', lw=1)
    # plt.show()r blue
    # 去掉刻度 + 坐标轴的方法:
    # plt.xticks([]
    plt.axis('off')
    f.savefig(path)

# 本月每日累计(T+1),示例源数据
def req_data_daily(file,sheet):
    month_data = pd.read_excel(file,sheet_name=sheet)
    return month_data

# 今日实时,示例源数据
def req_data_today(file,sheet):
    day_data = pd.read_excel(file,sheet_name=sheet)
    return day_data

if __name__ == "__main__":
    path_0 = os.path.dirname(__file__)
    path_font = path_0 + '/ops/font/'
    path_txt = path_0 + '/ops/fruit_pk_infos.txt'
    path_xlsx = path_0 + '/ops/data.xlsx'  # 示例数据
    path_i = path_0 + '/ops/'

    fruit_items = read_infos(path_txt)
    # 水果明细(导入)
    fruit_list = [k for k, v in fruit_items.items()]
    print("合计水果:" + str(len(fruit_list)) + "种")

    # 获取每日累计(T+1)数据、今日实时数据
    daily_data = req_data_daily(path_xlsx, 'month')
    daily_data_dict = daily_data.T.to_dict()

    today_data = req_data_today(path_xlsx, 'today')
    today_data_dict1 = today_data.set_index('fruit_name').T.to_dict(orient="records")
    today_data_dict = today_data_dict1[0]

    # 读取每日累计数据
    for fruit_name in fruit_list:
        fruit_new_m_list = []
        for i in range(len(daily_data)):
            if daily_data_dict[i]['fruit_name'] == fruit_name:
                fruit_new_m_list.append(daily_data_dict[i]['sales'])
        # 默认  按日期排序
        fruit_items[fruit_name]['data_list'] = fruit_new_m_list

    # 转化为 配对组数据
    draw_dic = {}
    for ii in range(6):
        i = ii + 1
        dic_i = {}
        for fruit_name in fruit_list:
            fruit_sales = fruit_items[fruit_name]
            pk_no = int(fruit_sales['fruit_infos'][1])
            if pk_no == i:
                # 今日值 无则为0
                day_stu_cnt = today_data_dict.get(fruit_name, 0)
                fruit_sales = fruit_items[fruit_name]
                pk_no = int(fruit_sales['fruit_infos'][1]) # pk组号
                gs_no = int(fruit_sales['fruit_infos'][2]) # 攻方1 守方0
                rate_type = round(float(fruit_sales['fruit_infos'][0]), 1) # pk系数
                # 新生成一列:昨日原始数据+今日值,附加在月累计新签列表
                fruit_data = fruit_sales['data_list']
                xxx = fruit_data[-1]
                xxx += day_stu_cnt
                fruit_data.append(xxx)

                # 乘以系数后数据
                fruit_data_new = [round(x * rate_type, 1) for x in fruit_data]
                # 水果待写入图片数据
                fruit_w = fruit_name + '-' + str(rate_type) + ':  ' + str(fruit_data_new[-1])
                fruit_x = [fruit_name, fruit_data_new, fruit_data, rate_type, fruit_w, fruit_data[-1]]
                if pk_no == i and gs_no == 0:
                    dic_i[0] = fruit_x
                elif pk_no == i and gs_no == 1:
                    dic_i[1] = fruit_x

        draw_path = path_i + str(i) +'.jpg'
        draw_dic[i] = dic_i

        #传参画折线图
        draw_jpg(draw_path,[dic_i[0][1],dic_i[1][1]])
        #判定胜负当前胜负方
        win_type_now = ''
        fs = dic_i[0][1][-1]
        jg = dic_i[1][1][-1]
        if fs > jg:
            dic_i[2] = dic_i[0][0]
            dic_i[3] = (13,182,241)
            win_type_now = 'fs'
        elif fs < jg:
            dic_i[2] = dic_i[1][0]
            dic_i[3] = (81,86,102)
            win_type_now = 'jg'
        else:
            dic_i[2] = dic_i[0][0] + ' 平 ' + dic_i[1][0]
            dic_i[3] = (13,182,241)
            win_type_now = 'db'
        #判定早晨胜负方
        win_type_past = ''
        fs0 = dic_i[0][1][-2]
        jg0 = dic_i[1][1][-2]
        if fs0 > jg0:
            win_type_past = 'fs'
        elif fs0 < jg0:
            win_type_past = 'jg'
        else:
            win_type_past = 'db'
        #判断是否变化
        if win_type_past == win_type_now:
            dic_i[4] = 'change0'
        elif win_type_now != 'db':
            dic_i[4] = 'change1'
        else:
            dic_i[4] = 'change2'

    print('图完毕,传参完毕')

    #图中画入 折线图
    img_back = Image.open(path_i + 'month.jpg')
    for y in range(3):
        for x in range(2):
            n = x + 2*y + 1
            if n <= 12:
                jpg_path =path_i + str(n) +'.jpg'
                imgs = Image.open(jpg_path)
                imgs1 = imgs.resize((1770, 1460))
                img_back.paste(imgs1, (110 + x * 1800, 860 + 1500 * y))

    # 图中写入文字
    draw = ImageDraw.Draw(img_back)

    # 写入当前日期
    path_font0 = path_font + 'times new roman bold.ttf'
    Font = ImageFont.truetype(path_font0, 80)
    draw.text([2850, 500], time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), (0, 0, 0), font=Font)

    #写入赢家 以及 当前值
    #今日PK 战报
    comment_text = []
    path_font1 = path_font + 'msyhbd.ttf'
    Font1 = ImageFont.truetype(path_font1, 120)
    path_font2 = path_font + 'msyhbd.ttf'
    Font2 = ImageFont.truetype(path_font2, 200)
    for y in range(3):
        for x in range(2):
            n = x + 2*y + 1
            if n <= 12 :
                #print(draw_text_dic[n])
                txt_list = draw_dic[n]
                # 写入赢家
                draw.text([160 + x * 1800, 900 + 1600* y], txt_list[2], (81, 86, 102), font=Font2)
                # 写入防数据
                draw.text([160 + x * 1800, 1200 + 1600 * y], txt_list[0][4], (255, 127, 80), font=Font1)
                # 写入攻数据
                draw.text([160 + x * 1800, 1400 + 1600 * y], txt_list[1][4], (81, 86, 102), font=Font1)

                if txt_list[4] == 'change1':
                    t1 = txt_list[0][0]+'VS'+txt_list[1][0]
                    t2 = txt_list[2]+'反超成功'+',太棒啦!'+'\n\n'
                    comment_text.append([t1,t2])
                elif txt_list[4] == 'change2':
                    t1 = txt_list[0][0]+'VS'+txt_list[1][0]
                    t2 = txt_list[2]+',都加油噢!\n\n'
                    comment_text.append([t1,t2])

    path_local =path_i + 'month_all.jpg'
    img_back.save(path_local)

    #每日 日报 总结播报
    path_font7 = path_font + 'msyhbd.ttf'
    Font7 = ImageFont.truetype(path_font7, 160)
    Font8 = ImageFont.truetype(path_font7, 200)

    urlme = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx'

    if len(comment_text)>0:
        for txt_all in comment_text:
            img_back_daily = Image.open(path_i + 'daily.jpg')
            draw1 = ImageDraw.Draw(img_back_daily)
            draw1.text([2800,780],time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),(0,0,0), font=Font)

            t1,t2 = txt_all[0],txt_all[1]
            draw1.text([800,1400],'《'+t1+' pk简报》',(81,86,102), font=Font7)
            draw1.text([800,1800],'  '+t2,(255, 127, 80), font=Font8)
            path_local1 =path_i + 'last_daily.jpg'
            img_back_daily.save(path_local1)
            post_image(urlme, path_local1)

    post_image(urlme, path_local)

执行结果:

robot发送图片.png
month_all.jpg
last_daily.jpg

说明:

思路大致可分为3步:
1、数据源获取与处理
2、PS设计好底图
3、数据写入底图,并发送(涉及到坐标运算)

底图模板如下:


month.jpg
daily.jpg
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,013评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,205评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,370评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,168评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,153评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,954评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,271评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,916评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,382评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,877评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,989评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,624评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,209评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,199评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,418评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,401评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,700评论 2 345

推荐阅读更多精彩内容