Xlwings,运行冷冻Python

问题描述 投票:0回答:1

我有以下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文件时指定要运行的具体方法吗?

谢谢。

python xlwings
1个回答
0
投票

当您运行“RunPython”时,您实际上正在执行函数“cv_pptx”。当您运行“RunPythonFrozen”时,您正在执行程序本身,但没有调用任何函数。在文件的末尾添加“cv_pptx()”。

您无需将photo_path参数添加到函数中。在函数中调用“wx.Book.caller()”后,可以引用电子表格中照片路径所在的工作表和单元格。

此外,您可以在通过添加将程序包捆绑到exe之前测试该程序

xw.Book(fpath_to_photo).set_mock_caller()

只需删除模拟调用,然后再将其转换为exe。

© www.soinside.com 2019 - 2024. All rights reserved.