将pyecharts生成的html转为图片的一些问题

最近在写一个用python自动生成周报,并用outlook自动完成发送的程序,其中一些问题记录如下。

1、版本问题

  1. pyecharts1.8.1
  2. matplotlib3.1.1高版本不能打包
  3. 谷歌驱动 谷歌驱动84.0版本注意谷歌浏览器的版本经常升级 注意谷歌驱动要放在生成图片文件的目录下而不是python程序的目录下

2、如何将python程序打包

  1. 将08_AutoEmail_HZ.py文件放在"C:\Users\HZhan100"路径下
  2. 执行语句cmd命令进入(user前面只有一个杠) pyinstaller -D C:\Users\HZhan100\08_AutoEmail_HZ.py --hidden-import matplotlib
    将会在dist文件夹下生成对应的文件夹08_AutoEmail_HZ,里面有一系列文件
  3. 在文件夹08_AutoEmail_HZ下拷贝pyecharts文件夹
    原因是,在执行生成的exe文件的时候,会发生找不到pyecharts的报错。
    解决方案:网上找的方法大都云里雾里的,大概意思就是pyecharts涉及到一些js,json文件没有打包,使得整个打包软件找不到相关文件,所以报错。
    我的方法是pyinstaller-D文件名后,会有一系列的文件生成在08_AutoEmail_HZ文件夹中,然后我们另外从python的site_package中找到pyecharts文件夹
    (C:\Users\HZhan100\AppData\Local\Programs\Python\Python37\Lib\site-packages)
    并把这整个文件夹都放到08_AutoEmail_HZ文件夹中,这样在运行打包的软件就不会报错了
  4. 如果没有生成exe文件,可能是文件被Windows defender或者Trend 趋势杀毒软件给杀毒删除了,关闭即可
    参见链接 http://www.orcy.net.cn/771.html
    a.win+r调出运行窗口,在其中输入cmd 回车
    b. cd进入officescan的实际安装目录
    c. 输入VSEncode.exe /U 回车
    d. 选择你要恢复的文件,点Restore
  5. 如果有时候在html 生成图片的时候 报错,不能生成,怀疑是公司的内网有拦截,请采用ping id的链接方式,进行发送

3、其他问题

目前puecharts的官方网站:https://pyecharts.org/#/zh-cn/render_images?id=make_snapshot,给处了3种方式,我觉得都不是很好用。
具体在当前的程序当中,主要是在html转换为图片的时候,比较耗时,大约2分钟,导致程序运行比较慢,所以目前正在寻找更快的方式,也请大家给些参考建议,非常感谢。
最后是程序代码,仅供参考

import pandas as pd
import xlrd
import xlwt
from openpyxl import Workbook
from openpyxl import load_workbook
import datetime
import openpyxl
import win32com.client as win32
import os

# 01读取数据
path = r"\\ap.jnj.com\jancnxndfsroot\Common\BU\MRC\MRC_CHANGE MANAGEMENT LOG\MRC_CHANGE MANAGEMENT LOG_1.xlsx"
data = pd.read_excel(path)
# cd1=((data['Change ID'].notnull() & data['Date of Initiation'].notnull())&(data['AIL/MD']=='AIL'))& (data['Date of Initiation']<=pd.to_datetime('2020-07-25'))
print('log文件读取已完成')

# 02统计数据
'''1. 设置路径'''
os.chdir(r"\\ap.jnj.com\jancnxndfsroot\Common\BU\MRC\MRC_CHANGE MANAGEMENT LOG\Weekly Report")
path = os.getcwd()
wb = load_workbook(path + r"\CR Status.xlsx")
ws1 = wb["MRC- total No"]
ws2 = wb["MRC-TYPE"]
ws3 = wb['MRC-STATUS']
'''表格1'''
for i in range(2, 14):
    if (ws1['A' + str(i)]) != None:
        cd1 = ((data['Change ID'].notnull() & data['Date of Initiation'].notnull()) &
               (data['Date of Initiation'] <= pd.to_datetime(str(ws1['A' + str(i)].value)[:10]))) & (
                          data["Current\nStatus"] != "Discarded")
        cd2 = (data['AIL/MD'] == 'AIL') & cd1
        cd3 = (data['AIL/MD'] == 'MD') & cd1
        ws1['B' + str(i)] = len(data[cd1])
        ws1['C' + str(i)] = len(data[cd2])
        ws1['D' + str(i)] = len(data[cd3])
        ws1['E' + str(i)] = ws1['B' + str(i)].value - ws1['C' + str(i)].value - ws1['D' + str(i)].value
'''表格2'''
ws2["C1"] = "New MRC Initiated on " + str(ws1['A13'].value)[11:19]


def pd_in(str1, str2):
    for ele in str2.split(','):
        if str1.upper() == (ele.upper()).strip():
            return True
    return False


fields = []
for i in range(2, 20):
    fields.append(ws2['B' + str(i)].value)
for i in range(2, 20):
    a = []
    for k in range(len(data)):
        a.append(pd_in(str(fields[i - 2]), str(data['DATA TYPE'][k])))
    cd = ((data['Change ID'].notnull() & data['Date of Initiation'].notnull()) &
          (data['Date of Initiation'] <= pd.to_datetime((ws1['A13'].value)[:10]))) & (
                     data["Current\nStatus"] != "Discarded")
    cd1 = (cd & a) & (data['Date of Initiation'] > pd.to_datetime((ws1['A12'].value)[:10]))
    cd2 = ((data['Change ID'].notnull() & data['Date of Initiation'].notnull()) & a) & (
                data["Current\nStatus"] != "Discarded")
    ws2['C' + str(i)] = len(data[cd1])
    ws2['D' + str(i)] = len(data[cd2])

'''表格3'''
ws3 = wb['MRC-STATUS']
ws3['B2'] = len(data[data['Current\nStatus'] == "Discarded"])
ws3['B3'] = len(data[data['Current\nStatus'] == "Open"])
ws3['B4'] = len(data[data['Current\nStatus'] == "Closed"])
wb.save("CR Status.xlsx")
print('数据统计完毕')

from openpyxl import Workbook
from openpyxl import load_workbook
import datetime
import openpyxl


# 定义函数来显示柱状上的数值
def autolabel_a(rects):
    for rect in rects:
        height = rect.get_height()
        plt.text(rect.get_x() + rect.get_width() - 0.05, 1.01 * height, '%s' % int(height), fontsize=15,
                 horizontalalignment='right')


def autolabel_b(rects):
    for rect in rects:
        height = rect.get_height()
        plt.text(rect.get_x() + rect.get_width() / 2, 1.01 * height, '%s' % int(height), fontsize=15,
                 horizontalalignment='center')


def autolabel_c(rects):
    for rect in rects:
        height = rect.get_height()
        plt.text(rect.get_x() + 0.05, 1.01 * height, '%s' % int(height), fontsize=15, horizontalalignment='left')


L_Total = []
L_AIL = []
L_MD = []
L_Other = []
name_1 = []
name_2 = []
for i in range(2, 14):
    name_1.append((ws1['A' + str(i)].value)[:10] + "\n" + (ws1['A' + str(i)].value)[10:])
    L_Total.append(ws1['B' + str(i)].value)
    L_AIL.append(ws1['C' + str(i)].value)
    L_MD.append(ws1['D' + str(i)].value)
    L_Other.append(ws1['E' + str(i)].value)

x = list(range(1, 37, 3))

import matplotlib.pyplot as plt

fig = plt.figure(dpi=800, figsize=(16, 11))  # 分辨率参数-dpi,画布大小参数-figsize
ax1 = fig.add_subplot(111)
plt.axis([0, 36, 0, int(ws1['B13'].value * 1.1)])
plt.tick_params(labelsize=20)
# 柱状图
import matplotlib as mpl

mpl.rcParams["font.sans-serif"] = ["SimHei"]

width = 0.5
a = plt.bar(x, L_AIL, width=width, label=' Total MRC  for AIL', fc='y')

for i in range(len(x)):
    x[i] = x[i] + 0.5
b = plt.bar(x, L_MD, width=width, label=' Total MRC  for MD', fc='r')

for i in range(len(x)):
    x[i] = x[i] + 0.5
c = plt.bar(x, L_Other, width=width, label=' Total other  MRC', fc='b')

x_aiss = [0] * 12
plt.bar(x, x_aiss, width=width, label=' No. Of Accumulated Total MRC ', fc='g')

plt.xticks(x, name_1, rotation=-70, fontsize=15)

autolabel_a(a)
autolabel_b(b)
autolabel_c(c)

plt.title('MRC Summary', fontsize=20)
plt.legend(loc=2, fontsize=15)

# 折线图
# ax2 = ax1.twinx() # this is the important function
# plt.axis([0,36,0,int(ws1['B13'].value*1.1)])
x = list(range(1, 37, 3))
for i in range(len(x)):
    x[i] = x[i] + 0.5
d = plt.plot(x, L_Total, color='g')

# 散点图
ax3 = ax1.twinx()
plt.axis([0, 36, 0, int(ws1['B13'].value * 1.1)])
plt.tick_params(labelsize=20)
d = plt.scatter(x, L_Total, color='g', marker='.', s=L_Total, label='No. Of Accumulated Total MRC ')
for k in range(12):
    plt.text(x[k], L_Total[k] - 30, '%s' % (L_Total[k]), horizontalalignment='center', fontsize=20)
plt.savefig('./01_line.jpg')

# 04 Pie 02
from pyecharts import options as opts
from snapshot_selenium import snapshot
from pyecharts.render import make_snapshot
from pyecharts import options as opts
from pyecharts.charts import Pie

x1 = []
x2 = []
for i in range(2, 20):
    if ws2["C" + str(i)].value != 0:
        x1.append([ws2["B" + str(i)].value, ws2["C" + str(i)].value])
    if ws2["D" + str(i)].value != 0:
        x2.append([ws2["B" + str(i)].value, ws2["D" + str(i)].value])

if len(x1) != 0:
    c = (
        Pie(init_opts=opts.InitOpts(width='1200px'))
            .add(
            "",
            x1,
            radius=["20%", "45%"],
            center=["31%", "45%"],
            label_opts=opts.LabelOpts(is_show=True),
        )
            .add(
            "",
            x2,
            radius=["20%", "45%"],
            center=["73%", "45%"],
            label_opts=opts.LabelOpts(is_show=True)
        )
            .set_global_opts(
            title_opts=opts.TitleOpts(title=' ' * 10 + ws2['C1'].value + " " * 55 + "Total MRC by type",
                                      pos_left="10%", pos_top="5%"),
            legend_opts=opts.LegendOpts(pos_left="10%", pos_top='85%', align='left'),
        )
            .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}:{d}%"))
    )
    # c.render('02_Pie.html')
    make_snapshot(snapshot, c.render('02_Pie.html'), "02_Pie.png")
else:
    c = (
        Pie(init_opts=opts.InitOpts(width='1200px'))
            .add(
            "",
            x2,
            radius=["20%", "45%"],
            center=["50%", "45%"],
            label_opts=opts.LabelOpts(is_show=True)
        )
            .set_global_opts(
            title_opts=opts.TitleOpts(title="Total MRC by type",
                                      pos_left="43%", pos_top="5%"),
            legend_opts=opts.LegendOpts(pos_left="10%", pos_top='85%', align='left'),
        )
            .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}:{d}%"))
    )
    # c.render('02_Pie.html')
    make_snapshot(snapshot, c.render('02_Pie.html'), "02_Pie.png")

# 05 Pie 03
from pyecharts import options as opts
from pyecharts.charts import Pie

x3 = [[ws3["A4"].value, ws3["B4"].value, ], [ws3["A3"].value, ws3["B3"].value, ]]
c = (
    Pie()
        .add(
        "",
        x3,
        radius=["30%", "55%"],
        label_opts=opts.LabelOpts(is_show=True),
    )
        .set_colors(['#33CC66', '#CCFF33'])
        .set_global_opts(title_opts=opts.TitleOpts(title="The Closure rate of MRC(except discard)",
                                                   pos_left="30%"),
                         legend_opts=opts.LegendOpts(is_show=True, pos_left="43%", pos_top='90%',
                                                     align='left'))
        .set_series_opts(label_opts=opts.LabelOpts(font_weight='bolder', font_size='15', formatter="{b}:{d}%"))
    # .render('03_Pie.html')
)
make_snapshot(snapshot, c.render("03_Pie.html"), "03_Pie.png")
print('绘图完毕')

# 05 发邮件
name = 'Wang Jun'
outlook = win32.Dispatch('Outlook.Application')
Mail_Item = outlook.CreateItem(0)
to = 'HZhan100@its.jnj.com;' \
     '1426146826@qq.com;'
Mail_Item.To = to
cc = 'HZhan100@its.jnj.com;' \
     '1426146826@qq.com;'
Mail_Item.CC = cc

subject = 'Summary of Master Recipe MRC on ' + ws1['A13'].value[11:-1]
Mail_Item.Subject = subject
Mail_Item.BodyFormat = 2

# 先把要插入的图片当作一个附件添加
Mail_Item.Attachments.Add(path + r'\01_line.jpg')
Mail_Item.Attachments.Add(path + r'\02_Pie.png')
Mail_Item.Attachments.Add(path + r'\03_Pie.png')

''' 然后在htmlbody里面调用这个图片,就可以进入到正文里面了
    注意这里有两个坑:1、文件名千万别用中文,否则会出错'''

Mail_Item.HTMLBody = f'''
    <p><font size="3" color="black" >Dears,</font></p>
    <p><font size="3" color="black" >Master Recipe MRC summary on {ws1['A13'].value[11:-1]} as the following table shows:</font></p>
    <strong><font size="3" color="black" face="Arial" >Part 1: MRC trend</font></strong>
    <table>
		<tr>
			<td>
				<table border="2">	
				    <tr><td>{ws1["A1"].value}</td><td>No. Of Accumulated<br />Total MRC</td><td>{ws1["C1"].value}</td><td>{ws1["D1"].value}</td><td>{ws1["E1"].value}</td></tr>
				    <tr><td>{ws1["A2"].value}</td><td>{ws1["B2"].value}</td><td>{ws1["C2"].value}</td><td>{ws1["D2"].value}</td><td>{ws1["E2"].value}</td></tr>
				    <tr><td>{ws1["A3"].value}</td><td>{ws1["B3"].value}</td><td>{ws1["C3"].value}</td><td>{ws1["D3"].value}</td><td>{ws1["E3"].value}</td></tr>
				    <tr><td>{ws1["A4"].value}</td><td>{ws1["B4"].value}</td><td>{ws1["C4"].value}</td><td>{ws1["D4"].value}</td><td>{ws1["E4"].value}</td></tr>
				    <tr><td>{ws1["A5"].value}</td><td>{ws1["B5"].value}</td><td>{ws1["C5"].value}</td><td>{ws1["D5"].value}</td><td>{ws1["E5"].value}</td></tr>
				    <tr><td>{ws1["A6"].value}</td><td>{ws1["B6"].value}</td><td>{ws1["C6"].value}</td><td>{ws1["D6"].value}</td><td>{ws1["E6"].value}</td></tr>
				    <tr><td>{ws1["A7"].value}</td><td>{ws1["B7"].value}</td><td>{ws1["C7"].value}</td><td>{ws1["D7"].value}</td><td>{ws1["E7"].value}</td></tr>
				    <tr><td>{ws1["A8"].value}</td><td>{ws1["B8"].value}</td><td>{ws1["C8"].value}</td><td>{ws1["D8"].value}</td><td>{ws1["E8"].value}</td></tr>
				    <tr><td>{ws1["A9"].value}</td><td>{ws1["B9"].value}</td><td>{ws1["C9"].value}</td><td>{ws1["D9"].value}</td><td>{ws1["E9"].value}</td></tr>
				    <tr><td>{ws1["A10"].value}</td><td>{ws1["B10"].value}</td><td>{ws1["C10"].value}</td><td>{ws1["D10"].value}</td><td>{ws1["E10"].value}</td></tr>
				    <tr><td>{ws1["A11"].value}</td><td>{ws1["B11"].value}</td><td>{ws1["C11"].value}</td><td>{ws1["D11"].value}</td><td>{ws1["E11"].value}</td></tr>
				    <tr><td>{ws1["A12"].value}</td><td>{ws1["B12"].value}</td><td>{ws1["C12"].value}</td><td>{ws1["D12"].value}</td><td>{ws1["E12"].value}</td></tr>
				    <tr><td>{ws1["A13"].value}</td><td>{ws1["B13"].value}</td><td>{ws1["C13"].value}</td><td>{ws1["D13"].value}</td><td>{ws1["E13"].value}</td></tr>
				</table>
			</td>
            <td><img src='./01_line.jpg' width="800" height="600"/></td>
		</tr>
    </table>
    <strong><font size="3" color="black" face="Arial" >Part 2: MRC distribution of types</font></strong>
    <table>
        <tr>
            <td>
                <table border="2">
                    <tr><td>{ws2["A1"].value}</td><td>{ws2["B1"].value}</td><td>New MRC Initiated on<br />{ws1['A13'].value[11:-1]}</td><td>{ws1["C1"].value}</td></tr>
                    <tr><td rowspan="15">MD</td><td>{ws2["B2"].value}</td><td>{ws2["C2"].value}</td><td>{ws2["D2"].value}</td></tr>
                    <tr><td>{ws2["B3"].value}</td><td>{ws2["C3"].value}</td><td>{ws2["D3"].value}</td></tr>
                    <tr><td>{ws2["B4"].value}</td><td>{ws2["C4"].value}</td><td>{ws2["D4"].value}</td></tr>
                    <tr><td>{ws2["B5"].value}</td><td>{ws2["C5"].value}</td><td>{ws2["D5"].value}</td></tr>
                    <tr><td>{ws2["B6"].value}</td><td>{ws2["C6"].value}</td><td>{ws2["D6"].value}</td></tr>
                    <tr><td>{ws2["B7"].value}</td><td>{ws2["C7"].value}</td><td>{ws2["D7"].value}</td></tr>
                    <tr><td>{ws2["B8"].value}</td><td>{ws2["C8"].value}</td><td>{ws2["D8"].value}</td></tr>
                    <tr><td>{ws2["B9"].value}</td><td>{ws2["C9"].value}</td><td>{ws2["D9"].value}</td></tr>
                    <tr><td>{ws2["B10"].value}</td><td>{ws2["C10"].value}</td><td>{ws2["D10"].value}</td></tr>
                    <tr><td>{ws2["B11"].value}</td><td>{ws2["C11"].value}</td><td>{ws2["D11"].value}</td></tr>
                    <tr><td>{ws2["B12"].value}</td><td>{ws2["C12"].value}</td><td>{ws2["D12"].value}</td></tr>
                    <tr><td>{ws2["B13"].value}</td><td>{ws2["C13"].value}</td><td>{ws2["D13"].value}</td></tr>
                    <tr><td>{ws2["B14"].value}</td><td>{ws2["C14"].value}</td><td>{ws2["D14"].value}</td></tr>
                    <tr><td>{ws2["B15"].value}</td><td>{ws2["C15"].value}</td><td>{ws2["D15"].value}</td></tr>
                    <tr><td>{ws2["B16"].value}</td><td>{ws2["C16"].value}</td><td>{ws2["D16"].value}</td></tr>
                    <tr><td rowspan="3">AIL</td><td>{ws2["B17"].value}</td><td>{ws2["C17"].value}</td><td>{ws2["D17"].value}</td></tr>
                    <tr><td>{ws2["B18"].value}</td><td>{ws2["C18"].value}</td><td>{ws2["D18"].value}</td></tr>
                    <tr><td>{ws2["B19"].value}</td><td>{ws2["C19"].value}</td><td>{ws2["D19"].value}</td></tr>
                </table>
            </td>
            <td><img src='./02_Pie.png' width="950" height="400"/></td>
        </tr>
	</table>
    <strong><font size="3" color="black" face="Arial" >Part 3: MRC status summary</font></strong>
    <table>
        <tr>
            <td>
                <table border="2">	
				    <tr><td>{ws3["A1"].value}</td><td>{ws3["B1"].value}</td></tr>
                    <tr><td>{ws3["A2"].value}</td><td>{ws3["B2"].value}</td></tr>
                    <tr><td>{ws3["A3"].value}</td><td>{ws3["B3"].value}</td></tr>
                    <tr><td>{ws3["A4"].value}</td><td>{ws3["B4"].value}</td></tr>
                </table>
            </td>
            <td><img src='./03_Pie.png' width="800" height="435"/></td>
        </tr>
    </table>
    <p><font size="3" color="black" >Best Regards<br/>MD Team<br/>{name}</font></p>
    '''
Mail_Item.Display()  # 这一步非常重要,没了这一步,在网页版邮箱就无法显示图片
Mail_Item.Send()
print('Send Email sucessfully')

import gc

gc.collect()

'''如何打包
---1、版本问题
pyecharts1.8.1
matplotlib3.1.1高版本不能打包

---谷歌驱动
谷歌驱动84.0版本注意谷歌浏览器的版本经常升级
注意谷歌驱动要放在生成图片文件的目录下而不是python程序的目录下

---打包注意事项,解决打包成功,但是执行失败的问题'''
'''1、将08_AutoEmail_HZ.py文件放在"C:\\Users\HZhan100"路径下
2、执行语句cmd命令进入(user前面只有一个杠\)
pyinstaller -D C:\\Users\HZhan100\08_AutoEmail_HZ.py --hidden-import matplotlib
将会在dist文件夹下生成对应的文件夹08_AutoEmail_HZ,里面有一系列文件
3、在文件夹08_AutoEmail_HZ下拷贝pyecharts文件夹
网上找的方法大都云里雾里的,大概意思就是pyecharts涉及到一些js,json文件没有打包,
使得整个打包软件找不到相关文件,所以报错。
我的方法是pyinstaller-D文件名后,会有一系列的文件生成在08_AutoEmail_HZ文件夹中,
我们另外从python的site_package中找到pyecharts文件夹
(C:\\Users\HZhan100\AppData\Local\Programs\Python\Python37\Lib\site-packages)
并把这整个文件夹都放到08_AutoEmail_HZ文件夹中,这样在运行打包的软件就不会报错了
3、如果没有生成exe文件,可能是文件被Windows defender或者Trend 趋势杀毒软件给杀毒删除了,关闭即可
参见链接 http://www.orcy.net.cn/771.html
a.win+r调出运行窗口,在其中输入cmd 回车
b. cd进入officescan的实际安装目录
c. 输入VSEncode.exe /U 回车
d. 选择你要恢复的文件,点Restore
4、如果有时候在html 生成图片的时候 报错,不能生成,怀疑是公司的内网有拦截,请采用ping id的链接方式,进行发送
'''


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值