我有以下Visual Basic代码从冻结的Python模块运行代码:
Sub CVpptx()
RunFrozenPython ("C:\Users\admin\Desktop\drect\dist\drect\drect.exe")
End Sub
Python代码:
import xlwings as xw
from xlwings import Range
from openpyxl import load_workbook
from pptx import Presentation
from pptx.shapes.autoshape import Shape
from pptx.util import Inches, Pt
from pptx.dml.color import ColorFormat, RGBColor
from pptx.enum.shapes import MSO_SHAPE
import matplotlib.pyplot as plt
from math import pi
from io import StringIO
from shutil import copyfileobj
import datetime
import subprocess
import sys, os
import tkinter.filedialog as fdialog
import tkinter.messagebox as msgbox
import tkinter
if getattr(sys, 'frozen', False):
main_path = sys.executable
else:
main_path = __file__[0:__file__.rfind("\\")]
asset_path = main_path + "\\assets\\"
def add_text_box(slide,left, top, width, height):
l = Inches(left)
t = Inches(top)
w = Inches (width)
h = Inches (height)
txBox = slide.shapes.add_textbox(l, t, w, h)
return txBox
def add_image(photo_path,slide,left, top, width, height):
l = Inches(left)
t = Inches(top)
w = Inches (width)
h = Inches (height)
pic = slide.shapes.add_picture(photo_path, l, t, width=w, height=h)
return pic
def add_text(text,textbox):
tf = textbox.text_frame
tf.text = text
def add_slide(prs,type=6, logo=True):
slide_layout = prs.slide_layouts[type]
new_slide = prs.slides.add_slide(slide_layout)
if (logo):
add_logo(new_slide)
return new_slide
def set_design(sp):
fill = sp.fill
fill.solid()
fill.fore_color.rgb = RGBColor(0x01, 0x23, 0x45)
fill.fore_color.theme_color = MSO_THEME_COLOR.ACCENT_1
fill.fore_color.brightness = 0.25
fill.transparency = 0.25
sp.fill = None
fill.background()
def add_shape(s,left, top, width, height):
shapes = s.shapes
l = Inches(left)
t = Inches(top)
w = Inches(width)
h = Inches(height)
shape = shapes.add_shape(MSO_SHAPE.ROUNDED_RECTANGLE, l, t, w, h)
return shape
def personal_slide(prs,photo_path):
s = add_slide(prs)
add_image(photo_path,s, 0.5, 1, 1.8, 2.5)
allrows=Range("A1").expand()
for rownum, row in enumerate(allrows.value):
txbox = add_text_box(s,5, rownum, 3, 2)
add_text(str(row[1]),txbox)
spider_chart()
skills = add_image(main_path+"temp.png",s, 4, 1, 2, 2.5)
remove_file(main_path+"temp.png")
def add_logo(s):
add_image(asset_path+"logo.png",s, 9, 0.2, 0.8, 0.4)
def remove_file(path):
os.remove(path)
def languages_slide(prs):
s = add_slide(prs)
allrows=Range("A1").expand()
for rownum, row in enumerate(allrows.value):
txbox = add_text_box(s,5, rownum, 3, 2)
add_text(str(row[1]),txbox)
def programming_slide(prs):
s = add_slide(prs)
allrows=Range("A1").expand()
for rownum, row in enumerate(allrows.value):
txbox = add_text_box(s,5, rownum, 3, 2)
add_text(str(row[1]),txbox)
def debug(msg):
f=open(main_path+"log.txt","a")
f.write(msg+"\n")
f.close()
def databases_slide(prs):
s = add_slide(prs)
allrows=Range("A1").expand()
for rownum, row in enumerate(allrows.value):
txbox = add_text_box(s,5, rownum, 3, 2)
add_text(str(row[1]),txbox)
def bi_slide(prs):
s = add_slide(prs)
allrows=Range("A1").expand()
for rownum, row in enumerate(allrows.value):
txbox = add_text_box(s,5, rownum, 3, 2)
add_text(str(row[1]),txbox)
def ux_slide(prs):
s = add_slide(prs)
allrows=Range("A1").expand()
for rownum, row in enumerate(allrows.value):
txbox = add_text_box(s,5, rownum, 3, 2)
add_text(str(row[1]),txbox)
def spider_chart():
cat = ['Analysis', 'Design', 'Production', 'Recipe', 'Project Management']
values = [90, 60, 65, 70, 80]
N = len(cat)
x_as = [n / float(N) * 2 * pi for n in range(N)]
# Because our chart will be circular we need to append a copy of the first
# value of each list at the end of each list with data
values += values[:1]
x_as += x_as[:1]
# Set color of axes
plt.rc('axes', linewidth=0.5, edgecolor="#888888")
# Create polar plot
ax = plt.subplot(111, polar=True)
# Set clockwise rotation. That is:
ax.set_theta_offset(pi / 2)
ax.set_theta_direction(-1)
# Set position of y-labels
ax.set_rlabel_position(0)
# Set color and linestyle of grid
ax.xaxis.grid(True, color="#888888", linestyle='solid', linewidth=0.5)
ax.yaxis.grid(True, color="#888888", linestyle='solid', linewidth=0.5)
# Set number of radial axes and remove labels
plt.xticks(x_as[:-1], [])
# Set yticks
# plt.yticks([20, 40, 60, 80, 100], ["20", "40", "60", "80", "100"])
# Plot data
ax.plot(x_as, values, linewidth=0, linestyle='solid', zorder=3)
# Fill area
ax.fill(x_as, values, 'b', alpha=0.3)
# Set axes limits
plt.ylim(0, 100)
# Draw ytick labels to make sure they fit properly
for i in range(N):
angle_rad = i / float(N) * 2 * pi
if angle_rad == 0:
ha, distance_ax = "center", 10
elif 0 < angle_rad < pi:
ha, distance_ax = "left", 1
elif angle_rad == pi:
ha, distance_ax = "center", 1
else:
ha, distance_ax = "right", 1
ax.text(angle_rad, 100 + distance_ax, cat[i], size=10, horizontalalignment=ha, verticalalignment="center")
plt.savefig(main_path+"temp.png",bbox_inches='tight',format='png')
def save_stringIO(s,path):
with open (path, 'wb') as fd:
s.seek (0)
shutil.copyfileobj (s, fd)
def get_timestamp():
return datetime.datetime.now().strftime("%d_%m_%Y__%H_%M_%S")
def cv_pptx(photo_path):
debug(main_path)
prs = Presentation()
wb = xw.Book.caller()
candidate=""
for w in wb.sheets:
if w.name.find("$")==-1:
w.activate()
if w.name=="Personal":
personal_slide(prs,photo_path)
if w.name=="Languages":
languages_slide(prs)
if w.name=="Programming":
programming_slide(prs)
if w.name=="Databases":
databases_slide(prs)
if w.name=="BI":
bi_slide(prs)
if w.name=="Ux":
ux_slide(prs)
presentation=main_path + "cv_"+get_timestamp()+".pptx"
prs.save(presentation)
os.system("start "+presentation)
我使用Pyinstaller来冻结Python代码。该脚本在标准的Python 3.6-Anaconda安装上运行。当我从Excel文件中调用Python模块的方法时:
RunPython ("import drect; drect.cv_pptx('" & ThisWorkbook.photo_path & "')")'
一切正常,但是当我尝试调用冻结的exe文件时:
RunFrozenPython ("C:\Users\admin\Desktop\drect\dist\drect\drect.exe")
什么都没发生。我没有收到任何错误或消息。好像代码没有执行。运行exe文件时,没有指定python模块的具体方法。可以在调用exe文件时指定要运行的具体方法吗?
谢谢。
当您运行“RunPython”时,您实际上正在执行函数“cv_pptx”。当您运行“RunPythonFrozen”时,您正在执行程序本身,但没有调用任何函数。在文件的末尾添加“cv_pptx()”。
您无需将photo_path参数添加到函数中。在函数中调用“wx.Book.caller()”后,可以引用电子表格中照片路径所在的工作表和单元格。
此外,您可以在通过添加将程序包捆绑到exe之前测试该程序
xw.Book(fpath_to_photo).set_mock_caller()
只需删除模拟调用,然后再将其转换为exe。