用于创建包含图像和图形的 PDF 文件的 orca 替代品
Alternative of orca for creating PDF file with images and figures
我正在使用此脚本创建 pdf 文件并附加带有统计信息的图像:
import MySQLdb
from plotly import graph_objs as go
import numpy as np
import os
from plotly.subplots import make_subplots
from PyPDF2 import PdfFileMerger
from datetime import datetime, timedelta
import smtplib
from email.message import EmailMessage
import imghdr
# Database connect
db = MySQLdb.connect(host="localhost",
user="root",
passwd="****",
db="ofasorgu_10_168_1_71")
today = datetime.today().strftime('%Y-%m-%d')
one_week = (datetime.today() - timedelta(days=7)).strftime('%Y-%m-%d')
two_week = (datetime.today() - timedelta(days=14)).strftime('%Y-%m-%d')
three_week = (datetime.today() - timedelta(days=21)).strftime('%Y-%m-%d')
four_week = (datetime.today() - timedelta(days=28)).strftime('%Y-%m-%d')
# Functions
def load_post_views(table, today, one_week, two_week, three_week, four_week):
product_views_dict = dict()
cursor = db.cursor()
cursor.execute(
"SELECT client_id, product_id, referrer, `date`" +
" FROM " + table +
" WHERE `date`>='"+four_week+"'")
for x in range(0, cursor.rowcount):
row = cursor.fetchone()
network = ""
period = ""
client_id = row[0]
product_id = row[1]
referrer = row[2]
date = str(row[3])
email_cursor = db.cursor()
email_cursor.execute("SELECT address FROM c8ty_connections_email WHERE entry_id=" + str(client_id))
email = email_cursor.fetchone()
product_cursor = db.cursor()
product_cursor.execute("SELECT post_title FROM c8ty_posts WHERE id=" + str(product_id))
product_name = product_cursor.fetchone()
# Add client ID key
if client_id not in product_views_dict:
product_views_dict[client_id] = dict()
# Add product ID key to client ID parent key
if product_id not in product_views_dict[client_id]:
product_views_dict[client_id][product_id] = {
today + " - " + one_week: {
"facebook": 0,
"twitter": 0,
"instagram": 0,
"linkedin": 0,
"pinterest": 0,
"website": 0,
},
one_week + " - " + two_week: {
"facebook": 0,
"twitter": 0,
"instagram": 0,
"linkedin": 0,
"pinterest": 0,
"website": 0,
},
two_week + " - " + three_week: {
"facebook": 0,
"twitter": 0,
"instagram": 0,
"linkedin": 0,
"pinterest": 0,
"website": 0,
},
three_week + " - " + four_week: {
"facebook": 0,
"twitter": 0,
"instagram": 0,
"linkedin": 0,
"pinterest": 0,
"website": 0,
}
}
# Find referrer
if "facebook" in referrer:
network = "facebook"
elif "twitter" in referrer:
network = "twitter"
elif "instagram" in referrer:
network = "instagram"
elif "linkedin" in referrer:
network = "linkedin"
elif "pinterest" in referrer:
network = "pinterest"
else:
network = "website"
# Check view period
if date <= today and date > one_week:
period = today + " - " + one_week
if date <= one_week and date > two_week:
period = one_week + " - " + two_week
if date <= two_week and date > three_week:
period = two_week + " - " + three_week
if date <= three_week and date > four_week:
period = three_week + " - " + four_week
product_views_dict[client_id][product_id][period][network] += 1
product_views_dict[client_id]["email"] = email[0]
product_views_dict[client_id][product_id]["product"] = product_name[0]
return product_views_dict
def draw_statistic(data_dict):
for clinetID, product_info in data_dict.items():
client_email = product_info["email"]
for productID, product_data in product_info.items():
if type(product_data) is dict:
product_name = product_data['product']
table_data = [
[
today + " - " + one_week,
one_week + " - " + two_week,
two_week + " - " + three_week,
three_week + " - " + four_week,
today + " - " + four_week
]
]
total_one = []
total_two = []
total_three = []
total_four = []
overall_traces = []
networks_and_positions = [
{"network": "website","row": 2,"col": 1},
{"network": "linkedin","row": 2,"col": 2},
{"network": "facebook","row": 3,"col": 1},
{"network": "twitter","row": 3,"col": 2},
{"network": "instagram","row": 4,"col": 1},
{"network": "pinterest","row": 4,"col": 2}
]
fig = make_subplots(rows=5, cols=2)
merge_fig = make_subplots(rows=1, cols=1)
count = 2
for dictionary in networks_and_positions:
network = dictionary['network']
row = dictionary['row']
col = dictionary['col']
total_one.append(product_data[today + " - " + one_week][network])
total_two.append(product_data[one_week + " - " + two_week][network])
total_three.append(product_data[two_week + " - " + three_week][network])
total_four.append(product_data[three_week + " - " + four_week][network])
table_data.append([
product_data[today + " - " + one_week][network],
product_data[one_week + " - " + two_week][network],
product_data[two_week + " - " + three_week][network],
product_data[three_week + " - " + four_week][network],
sum([
product_data[today + " - " + one_week][network],
product_data[one_week + " - " + two_week][network],
product_data[two_week + " - " + three_week][network],
product_data[three_week + " - " + four_week][network]
])
])
xaxis = [
today + " - " + one_week,
one_week + " - " + two_week,
two_week + " - " + three_week,
three_week + " - " + four_week,
]
yaxis = [
product_data[today + " - " + one_week][network],
product_data[one_week + " - " + two_week][network],
product_data[two_week + " - " + three_week][network],
product_data[three_week + " - " + four_week][network]
]
chart_name = network.capitalize() + " statistic"
# Create bar chart
if (count == 2):
social_fig = go.Bar(
x=xaxis,
y=yaxis,
name=chart_name
)
else:
social_fig = go.Bar(
x=xaxis,
y=yaxis,
name=chart_name,
yaxis="y"+str(count)
)
# Add chart to fig
fig.add_trace(
social_fig,
row=row,
col=col
)
count += 1
trace_name = network.capitalize() + " views"
overall_traces.append(
go.Scatter(
x=xaxis,
y=yaxis,
name=trace_name
)
)
total_column_values_array = [sum(total_one), sum(total_two), sum(total_three), sum(total_four),]
total_column_values_array.append(
sum(total_one)+sum(total_two)+sum(total_three)+sum(total_four)
)
table_data.append(total_column_values_array)
# Create product table
fig.add_trace(
go.Table(
header=dict(values=["Period", "Website", "Facebook", "Twitter", "Instagram", "LinkedIn", "Pinterest", "Total"]),
cells=dict(values=table_data)
)
)
merge_fig.add_traces(overall_traces)
# Craete folder if doesn't exist
if not os.path.exists("files"):
os.mkdir("files")
statistic_file = "files/statistic_"+product_name+".pdf"
overall_file = "files/overall_"+product_name+".pdf"
out_file = "files/"+product_name+"_statistic.pdf"
# Create charts file
fig.update_layout(height=1500, width=1000, title_text="<b>Greetings</b><br />This is statistic from <a href='https://www.cfasuk.co.uk/'>CFAS UK</a> for your product <b>"+product_name+"</b>")
fig.update_layout(
yaxis3=dict(title="Website views", titlefont=dict(color="#636efa")),
yaxis4=dict(title="LinkedIn views", titlefont=dict(color="#ef553b")),
yaxis5=dict(title="Facebook views", titlefont=dict(color="#00cc96")),
yaxis6=dict(title="Twitter views", titlefont=dict(color="#b780f9")),
yaxis7=dict(title="Instagram views", titlefont=dict(color="#ffa15a")),
yaxis8=dict(title="Pinterest views", titlefont=dict(color="#19d3f3")),
)
fig.write_image(statistic_file)
# Create overall file
merge_fig.update_layout(height=700, width=1000, title_text="Overall <b>"+product_name+"</b> statistic")
merge_fig.write_image(overall_file)
merge = PdfFileMerger(strict=False)
# Append charts file to merger
merge.append(statistic_file)
# Append overall file to merger
merge.append(overall_file)
# Create end statistic file with both charts and overall
merge.write(out_file)
merge.close()
# Delete statistic file
os.remove(statistic_file)
# Delete overall file
os.remove(overall_file)
# Send email with file
send_mail(
"tomaivanovtomov@gmail.com",
"tomaivanovtomov@gmail.com",
"CFAS UK, "+product_name+" statistic",
"This is automated email. Please, do not reply!<br/>"+
"If you find some problem with the statistic or the product is not yours, please contact CFAS UK team.<br/>"+
"Best regards!",
out_file
)
def send_mail(send_from, send_to, subject, text, file=None):
with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
smtp.login("tomaivanovtomov@gmail.com", "zmjquvphuvigqdai")
msg = EmailMessage()
msg['Subject'] = subject
msg['From'] = send_from
msg['To'] = send_to
msg.set_content(text)
with open(file, "rb") as f:
file_data = f.read()
file_name = f.name
msg.add_attachment(file_data, maintype='application/pdf', subtype='pdf', filename=file_name)
smtp.send_message(msg)
# Init
product_views_dict = load_post_views("an_product_view", today, one_week, two_week, three_week, four_week)
brochure_views_dict = load_post_views("an_brochure_view", today, one_week, two_week, three_week, four_week)
draw_statistic(product_views_dict)
draw_statistic(brochure_views_dict)
db.close()
exit()
当我在我的本地服务器上测试时,它工作正常。但我需要将它上传到 Centos 服务器上的共享帐户。在我的托管服务提供商上。在那里我无法安装 anaconda
,我需要为静态图像安装 orca
。是否有创建图像然后将其添加到 pdf 文件的替代方法?先感谢您!
是的(您不需要在代码中使用任何工具后端依赖项),有一个非常简单的替代库示例,如下所示。
您可以为此使用 matplotlib 集成。
您可以导入这些模块,如下所示
from plotly.offline import init_notebook_mode, plot_mpl
import matplotlib.pyplot as plt
您可以按如下方式使用它们:
init_notebook_mode()
fig = plt.figure()
# you can configure you plot here use below to save it as image
plot_mpl(fig)
plot_mpl(fig, image='png')
或者如果你想仍然坚持只情节并寻找替代方案,你可以看到下面
你可以使用plotly的离线模块在服务器上生成静态图片,并用它来生成PDF。您可以使用 from plotly.offline import plot
导入它。导入后,您可以使用下面的绘图函数
fig = go.Figure( data=data, layout=layout )
plot( fig, filename='your-file-name' , image = 'png')
如果您使用的是 Plotly,则可以安装 kaleido
,它将使用它而不是 orca 来生成静态图像。
如果你只能通过 pip 安装你的包,这很好。
我正在使用此脚本创建 pdf 文件并附加带有统计信息的图像:
import MySQLdb
from plotly import graph_objs as go
import numpy as np
import os
from plotly.subplots import make_subplots
from PyPDF2 import PdfFileMerger
from datetime import datetime, timedelta
import smtplib
from email.message import EmailMessage
import imghdr
# Database connect
db = MySQLdb.connect(host="localhost",
user="root",
passwd="****",
db="ofasorgu_10_168_1_71")
today = datetime.today().strftime('%Y-%m-%d')
one_week = (datetime.today() - timedelta(days=7)).strftime('%Y-%m-%d')
two_week = (datetime.today() - timedelta(days=14)).strftime('%Y-%m-%d')
three_week = (datetime.today() - timedelta(days=21)).strftime('%Y-%m-%d')
four_week = (datetime.today() - timedelta(days=28)).strftime('%Y-%m-%d')
# Functions
def load_post_views(table, today, one_week, two_week, three_week, four_week):
product_views_dict = dict()
cursor = db.cursor()
cursor.execute(
"SELECT client_id, product_id, referrer, `date`" +
" FROM " + table +
" WHERE `date`>='"+four_week+"'")
for x in range(0, cursor.rowcount):
row = cursor.fetchone()
network = ""
period = ""
client_id = row[0]
product_id = row[1]
referrer = row[2]
date = str(row[3])
email_cursor = db.cursor()
email_cursor.execute("SELECT address FROM c8ty_connections_email WHERE entry_id=" + str(client_id))
email = email_cursor.fetchone()
product_cursor = db.cursor()
product_cursor.execute("SELECT post_title FROM c8ty_posts WHERE id=" + str(product_id))
product_name = product_cursor.fetchone()
# Add client ID key
if client_id not in product_views_dict:
product_views_dict[client_id] = dict()
# Add product ID key to client ID parent key
if product_id not in product_views_dict[client_id]:
product_views_dict[client_id][product_id] = {
today + " - " + one_week: {
"facebook": 0,
"twitter": 0,
"instagram": 0,
"linkedin": 0,
"pinterest": 0,
"website": 0,
},
one_week + " - " + two_week: {
"facebook": 0,
"twitter": 0,
"instagram": 0,
"linkedin": 0,
"pinterest": 0,
"website": 0,
},
two_week + " - " + three_week: {
"facebook": 0,
"twitter": 0,
"instagram": 0,
"linkedin": 0,
"pinterest": 0,
"website": 0,
},
three_week + " - " + four_week: {
"facebook": 0,
"twitter": 0,
"instagram": 0,
"linkedin": 0,
"pinterest": 0,
"website": 0,
}
}
# Find referrer
if "facebook" in referrer:
network = "facebook"
elif "twitter" in referrer:
network = "twitter"
elif "instagram" in referrer:
network = "instagram"
elif "linkedin" in referrer:
network = "linkedin"
elif "pinterest" in referrer:
network = "pinterest"
else:
network = "website"
# Check view period
if date <= today and date > one_week:
period = today + " - " + one_week
if date <= one_week and date > two_week:
period = one_week + " - " + two_week
if date <= two_week and date > three_week:
period = two_week + " - " + three_week
if date <= three_week and date > four_week:
period = three_week + " - " + four_week
product_views_dict[client_id][product_id][period][network] += 1
product_views_dict[client_id]["email"] = email[0]
product_views_dict[client_id][product_id]["product"] = product_name[0]
return product_views_dict
def draw_statistic(data_dict):
for clinetID, product_info in data_dict.items():
client_email = product_info["email"]
for productID, product_data in product_info.items():
if type(product_data) is dict:
product_name = product_data['product']
table_data = [
[
today + " - " + one_week,
one_week + " - " + two_week,
two_week + " - " + three_week,
three_week + " - " + four_week,
today + " - " + four_week
]
]
total_one = []
total_two = []
total_three = []
total_four = []
overall_traces = []
networks_and_positions = [
{"network": "website","row": 2,"col": 1},
{"network": "linkedin","row": 2,"col": 2},
{"network": "facebook","row": 3,"col": 1},
{"network": "twitter","row": 3,"col": 2},
{"network": "instagram","row": 4,"col": 1},
{"network": "pinterest","row": 4,"col": 2}
]
fig = make_subplots(rows=5, cols=2)
merge_fig = make_subplots(rows=1, cols=1)
count = 2
for dictionary in networks_and_positions:
network = dictionary['network']
row = dictionary['row']
col = dictionary['col']
total_one.append(product_data[today + " - " + one_week][network])
total_two.append(product_data[one_week + " - " + two_week][network])
total_three.append(product_data[two_week + " - " + three_week][network])
total_four.append(product_data[three_week + " - " + four_week][network])
table_data.append([
product_data[today + " - " + one_week][network],
product_data[one_week + " - " + two_week][network],
product_data[two_week + " - " + three_week][network],
product_data[three_week + " - " + four_week][network],
sum([
product_data[today + " - " + one_week][network],
product_data[one_week + " - " + two_week][network],
product_data[two_week + " - " + three_week][network],
product_data[three_week + " - " + four_week][network]
])
])
xaxis = [
today + " - " + one_week,
one_week + " - " + two_week,
two_week + " - " + three_week,
three_week + " - " + four_week,
]
yaxis = [
product_data[today + " - " + one_week][network],
product_data[one_week + " - " + two_week][network],
product_data[two_week + " - " + three_week][network],
product_data[three_week + " - " + four_week][network]
]
chart_name = network.capitalize() + " statistic"
# Create bar chart
if (count == 2):
social_fig = go.Bar(
x=xaxis,
y=yaxis,
name=chart_name
)
else:
social_fig = go.Bar(
x=xaxis,
y=yaxis,
name=chart_name,
yaxis="y"+str(count)
)
# Add chart to fig
fig.add_trace(
social_fig,
row=row,
col=col
)
count += 1
trace_name = network.capitalize() + " views"
overall_traces.append(
go.Scatter(
x=xaxis,
y=yaxis,
name=trace_name
)
)
total_column_values_array = [sum(total_one), sum(total_two), sum(total_three), sum(total_four),]
total_column_values_array.append(
sum(total_one)+sum(total_two)+sum(total_three)+sum(total_four)
)
table_data.append(total_column_values_array)
# Create product table
fig.add_trace(
go.Table(
header=dict(values=["Period", "Website", "Facebook", "Twitter", "Instagram", "LinkedIn", "Pinterest", "Total"]),
cells=dict(values=table_data)
)
)
merge_fig.add_traces(overall_traces)
# Craete folder if doesn't exist
if not os.path.exists("files"):
os.mkdir("files")
statistic_file = "files/statistic_"+product_name+".pdf"
overall_file = "files/overall_"+product_name+".pdf"
out_file = "files/"+product_name+"_statistic.pdf"
# Create charts file
fig.update_layout(height=1500, width=1000, title_text="<b>Greetings</b><br />This is statistic from <a href='https://www.cfasuk.co.uk/'>CFAS UK</a> for your product <b>"+product_name+"</b>")
fig.update_layout(
yaxis3=dict(title="Website views", titlefont=dict(color="#636efa")),
yaxis4=dict(title="LinkedIn views", titlefont=dict(color="#ef553b")),
yaxis5=dict(title="Facebook views", titlefont=dict(color="#00cc96")),
yaxis6=dict(title="Twitter views", titlefont=dict(color="#b780f9")),
yaxis7=dict(title="Instagram views", titlefont=dict(color="#ffa15a")),
yaxis8=dict(title="Pinterest views", titlefont=dict(color="#19d3f3")),
)
fig.write_image(statistic_file)
# Create overall file
merge_fig.update_layout(height=700, width=1000, title_text="Overall <b>"+product_name+"</b> statistic")
merge_fig.write_image(overall_file)
merge = PdfFileMerger(strict=False)
# Append charts file to merger
merge.append(statistic_file)
# Append overall file to merger
merge.append(overall_file)
# Create end statistic file with both charts and overall
merge.write(out_file)
merge.close()
# Delete statistic file
os.remove(statistic_file)
# Delete overall file
os.remove(overall_file)
# Send email with file
send_mail(
"tomaivanovtomov@gmail.com",
"tomaivanovtomov@gmail.com",
"CFAS UK, "+product_name+" statistic",
"This is automated email. Please, do not reply!<br/>"+
"If you find some problem with the statistic or the product is not yours, please contact CFAS UK team.<br/>"+
"Best regards!",
out_file
)
def send_mail(send_from, send_to, subject, text, file=None):
with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
smtp.login("tomaivanovtomov@gmail.com", "zmjquvphuvigqdai")
msg = EmailMessage()
msg['Subject'] = subject
msg['From'] = send_from
msg['To'] = send_to
msg.set_content(text)
with open(file, "rb") as f:
file_data = f.read()
file_name = f.name
msg.add_attachment(file_data, maintype='application/pdf', subtype='pdf', filename=file_name)
smtp.send_message(msg)
# Init
product_views_dict = load_post_views("an_product_view", today, one_week, two_week, three_week, four_week)
brochure_views_dict = load_post_views("an_brochure_view", today, one_week, two_week, three_week, four_week)
draw_statistic(product_views_dict)
draw_statistic(brochure_views_dict)
db.close()
exit()
当我在我的本地服务器上测试时,它工作正常。但我需要将它上传到 Centos 服务器上的共享帐户。在我的托管服务提供商上。在那里我无法安装 anaconda
,我需要为静态图像安装 orca
。是否有创建图像然后将其添加到 pdf 文件的替代方法?先感谢您!
是的(您不需要在代码中使用任何工具后端依赖项),有一个非常简单的替代库示例,如下所示。
您可以为此使用 matplotlib 集成。
您可以导入这些模块,如下所示
from plotly.offline import init_notebook_mode, plot_mpl
import matplotlib.pyplot as plt
您可以按如下方式使用它们:
init_notebook_mode()
fig = plt.figure()
# you can configure you plot here use below to save it as image
plot_mpl(fig)
plot_mpl(fig, image='png')
或者如果你想仍然坚持只情节并寻找替代方案,你可以看到下面
你可以使用plotly的离线模块在服务器上生成静态图片,并用它来生成PDF。您可以使用 from plotly.offline import plot
导入它。导入后,您可以使用下面的绘图函数
fig = go.Figure( data=data, layout=layout )
plot( fig, filename='your-file-name' , image = 'png')
如果您使用的是 Plotly,则可以安装 kaleido
,它将使用它而不是 orca 来生成静态图像。
如果你只能通过 pip 安装你的包,这很好。