Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
485 views
in Technique[技术] by (71.8m points)

excel - PyInstaller and python-docx module do not work together

I am trying to make an executable of my program to give to my FTC team. Everything works but when I try to use my script that includes python-docx in it but it does not complete the whole thing. It works when I run it in PyCharm and from the terminal. Here is the code. I have python3.

from tkinter import *
import sys,math,random,datetime,os,time
import tkinter.messagebox
from tkinter import filedialog
from tkinter.filedialog import askopenfilename
from tkinter.messagebox import showerror
from time import gmtime, strftime
from docx import Document
from docx.shared import Inches
import xlsxwriter

export = "Excel"
job = "No Job"
current_time = strftime("%m-%d-%Y", gmtime())
root = Tk()

TextArea = Text(width=60,height=17,pady=0)
task = Entry(width=90)
task.insert(10, "Task:")
e1 = Entry()
e1.insert(10, "First Name")
e2 = Entry()
e2.insert(10, "Last Name")
TextArea.insert(END, "Reflection:")
title = ["Titan Tech ", "Caleb Fahlgren made this!", "Python is life!", "FIRST Robotics!","This program is over 200 lines of code!"]
title = (random.choice(title))
root.title(title)
root.geometry("680x600")

#Submit Button
#This definition writes to the excel file
def Submit():
    submit = tkinter.messagebox.askquestion("Submit Entry", "Are you sure you want to submit?")
    if submit == "yes":
        current_time = strftime("%m-%d-%Y %H:%M", gmtime())
        fullname = "%s %s" % (e1.get(), e2.get())
        lastname = "%s" % (e2.get())
        task1 = "%s" % (task.get())
        alltext = TextArea.get("1.0",END)
        workbook = xlsxwriter.Workbook('Titan Tech ' + (strftime("%m-%d-%Y", gmtime())) + '.xlsx')
        worksheet = workbook.add_worksheet()
        format_text = workbook.add_format()
        format_text.set_text_wrap()
        cell_format = workbook.add_format({'align': 'center','valign': 'vcenter','border': 1,'text_wrap': 1})
        middle = workbook.add_format({'align':'center'})
        worksheet.merge_range('A5:G20', "", cell_format)
        worksheet.merge_range('A4:G4', "", cell_format)
        bold = workbook.add_format({'bold': 1})
        worksheet.write('A1', 'Name:',bold)
        worksheet.write('A4', task1)
        worksheet.write_string('B1',fullname, bold)
        worksheet.merge_range('A2:B2', "", cell_format)
        worksheet.merge_range('D2:E2', "", cell_format)
        worksheet.write_string('A2',"Student Initials")
        worksheet.write_string('C2',"_______",middle)
        worksheet.write_string('D2',"Mentor Initials")
        worksheet.write_string('F2',"_______",middle)
        worksheet.write('E1', 'Date:',bold)
        worksheet.write('F1',(strftime("%m-%d-%Y", gmtime())),bold)
        worksheet.write_rich_string('A5',alltext ,cell_format)
        userconfirm = tkinter.messagebox.showinfo("Save","Your entry has been saved to an " + export + " document!")
        workbook.close()

def Reset():
    python = sys.executable
    os.execl(python, python, * sys.argv)

def keypress(event):
    if event.keysym == 'Escape':
        root.destroy()

def Quit():
    quitask = tkinter.messagebox.askquestion("Quit", "Are you sure you want to quit?")
    if quitask == "yes":
        root.destroy()


firstname = Label(root, text="First Name",font=("Helvetica", 12),fg="green")
lastname = Label(root, text="Last Name",font=("Helvetica", 12),fg="green")
time = Label(root, text=current_time, font=("Helvetica", 12),fg="black")

ScrollBar = Scrollbar(root)
ScrollBar.config(command=TextArea.yview)
TextArea.config(yscrollcommand=ScrollBar.set)
ScrollBar.pack(side=RIGHT, fill=Y)


def cf():
    e1.delete(0, 'end')
    e2.delete(0, 'end')
    e1.insert(10, "Sample")
    e2.insert(10, "Name 1")
def al():
    e1.delete(0, 'end')
    e2.delete(0, 'end')
    e1.insert(10, "Sample")
    e2.insert(10, "Name 2")
def cm():
    e1.delete(0, 'end')
    e2.delete(0, 'end')
    e1.insert(10, "Sample")
    e2.insert(10, "Name 3")
def np():
    e1.delete(0, 'end')
    e2.delete(0, 'end')
    e1.insert(10, "Sample")
    e2.insert(10, "Name 4")
def cp():
    e1.delete(0, 'end')
    e2.delete(0, 'end')
    e1.insert(10, "Sample")
    e2.insert(10, "Name 5")
def ns():
    e1.delete(0, 'end')
    e2.delete(0, 'end')
    e1.insert(10, "Sample")
    e2.insert(10, "Name 6")
def ct():
    e1.delete(0, 'end')
    e2.delete(0, 'end')
    e1.insert(10, "Sample")
    e2.insert(10, "Name 7")
def kt():
    e1.delete(0, 'end')
    e2.delete(0, 'end')
    e1.insert(10, "Sample")
    e2.insert(10, "Name 8")
def mt():
    e1.delete(0, 'end')
    e2.delete(0, 'end')
    e1.insert(10, "Sample")
    e2.insert(10, "Name 9")
def ek():
    e1.delete(0, 'end')
    e2.delete(0, 'end')
    e1.insert(10, "Sample")
    e2.insert(10, "Name 10")
def n():
    e1.delete(0, 'end')
    e2.delete(0, 'end')
    e1.insert(10, "Team")
    e2.insert(10, "Name")
def other():

    e1.delete(0, 'end')
    e2.delete(0, 'end')

def TextFile():
    current_time = strftime("%m-%d-%Y", gmtime())
    fullname = "%s %s" % (e1.get(), e2.get())
    lastname = "%s" % (e2.get())
    task1 = "%s" % (task.get())
    alltext = TextArea.get("1.0",END)
    textfile1 = tkinter.messagebox.askquestion("Text File", "Are you sure you want to export as a text file?")
    if textfile1 == "yes":
        textfile = open('Titan Tech' + (strftime("%m-%d-%Y", gmtime())) + '.txt',"w")
        textfile.write("Titan Tech  | Team # 10385   ")
        textfile.write("Name: " + fullname)
        textfile.write("        " + "Date: " + current_time)
        textfile.write('
' + '
' + task1)
        textfile.write('
' + '
' + alltext)
        textfile.close()
        tkinter.messagebox.showinfo("Save", "You have exported to text file successfully. It is in the location of this program.")

def helpmenusave():
    helpsaveconfirm = tkinter.messagebox.showinfo("Save", "This program exports the Excel, World, or text document to the location of this program!")

def userinterfacemenu():
    helpuserinterface = tkinter.messagebox.showinfo("User Interface", "The Users tab is where you can click on your name to autofill the name text boxes. The Export tab is where you choose to export to a specific format.")

def Open():
    textopen = tkinter.filedialog.askopenfile(mode='r', filetypes=[('Text Files', '*.txt'),('All Files', '*')])
    if textopen != None:
        txtopen = textopen.read()
        TextArea.delete(1.0,END)
        TextArea.insert(END,txtopen)
        tkinter.messagebox.showinfo("Open",  "Success!")
        try:
            txtopen.close()
        except AttributeError:
            print("Attribute Error")

menubar = Menu(root)
filemenu = Menu(menubar,tearoff = 0)
filemenu.add_command(label="New",command=Reset)
filemenu.add_command(label="Open",command=Open)
filemenu.add_command(label="Exit",command=Quit)
menubar.add_cascade(label="File",menu=filemenu)

#help menu
helpmenu = Menu(menubar,tearoff = 0)
helpmenu.add_command(label="None", command=n)
helpmenu.add_command(label="Sample Name 1", command=cf)
helpmenu.add_command(label="Sample Name 2", command=al)
helpmenu.add_command(label="Sample Name 3", command=cm)
helpmenu.add_command(label="Sample Name 4", command=np)
helpmenu.add_command(label="Sample Name 5",command=cp)
helpmenu.add_command(label="Sample Name 6",command=ns)
helpmenu.add_command(label="Sample Name 7",command=ct)
helpmenu.add_command(label="Sample Name 8",command=kt)
helpmenu.add_command(label="Sample Name 9",command=mt)
helpmenu.add_command(label="Sample Name 10", command=ek)
helpmenu.add_command(label="Other", command=other)
menubar.add_cascade(label="Users",menu=helpmenu)

This is where the problem is. It works in Pycharm and in terminal but when I compile it with PyInstaller it only does the wordsaveask = tkinter.messagebox.askquestion line but nothing under it. It is supposed to create the Word file but doesn't. I also don't get any error messages.

def Word():
    current_time = strftime("%m-%d-%Y", gmtime())
    lastname = "%s" % (e2.get())
    fullname = "%s %s" % (e1.get(), e2.get())
    task1 = "%s" % (task.get())
    alltext = TextArea.get("1.0",END)
    wordsaveask = tkinter.messagebox.askquestion("Save", "Are you sure you want to export to a Microsoft Word file?")
    if wordsaveask == ("yes") :
        document = Document()
        document.add_heading('FTC Titan Tech Summary', 0)
        document.add_paragraph('Titan Tech  | Team # 10385')
        document.add_paragraph('Mentor Initials ____           Student Initials _____')
        document.add_paragraph('Name: ' + fullname)
        document.add_paragraph('Date: ' + current_time)
        document.add_paragraph(task1)
        document.add_paragraph(alltext)
        document.save('Titan Tech ' + (strftime("%m-%d-%Y", gmtime())) + '.docx')
        tkinter.messagebox.showinfo('Save', 'The program has exported the information to a Microsoft Word document!')

#export 
exportmenu = Menu(menubar, tearoff = 0)
exportmenu.add_command(label="Microsoft Excel",command=Submit)
exportmenu.add_command(label="Microsoft Word",command=Word)
exportmenu.add_command(label="Text File",command=TextFile)
menubar.add_cascade(label="Export",menu=exportmenu)

helpmenu = Menu(menubar, tearoff = 0)
helpmenu.add_command(label="Save Help", command=helpmenusave)
helpmenu.add_command(label="User Interface", command=userinterfacemenu)
menubar.add_cascade(label="Help",menu=helpmenu)
root.config(menu=menubar)

Submit = Button(root, fg="white", bg="green", text="Submit", width=50, command=Submit, activebackground="yellow")
Quit = Button(root, fg="white", bg="green", text="Quit", width=50, command=Quit,activebackground="yellow")

root.bind_all('<Key>', keypress)
firstname.pack()
e1.pack()
lastname.pack()
e2.pack()
time.pack()
task.pack()
TextArea.pack(expand=YES, fill=BOTH)
Submit.pack()
Quit.pack()
mainloop()
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Pyinstaller doesn't include docx modules(I had the same problem, i will write it for others because i couldnt find proper tutorial how to fix it)

If you have Pyinstaller installed use in cmd:

pyi-makespec your_py_file_name.py

This command creates .spec file but does not go on to build the executable.

Open .spec file in Notepad and edit it by adding:

import sys
from os import path
site_packages = next(p for p in sys.path if 'site-packages' in p)

And

datas=[(path.join(site_packages,"docx","templates"), "docx/templates")],

My example .spec file looks like this

# -*- mode: python -*-

import sys
from os import path
site_packages = next(p for p in sys.path if 'site-packages' in p)
block_cipher = None


a = Analysis(['xml_reader.py'],
             pathex=['C:\Users\Lenovo\Desktop\exe'],
             binaries=[],
             datas=[(path.join(site_packages,"docx","templates"), 
"docx/templates")],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          exclude_binaries=True,
          name='xml_reader',
          debug=False,
          strip=False,
          upx=True,
          console=True )
coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=False,
               upx=True,
               name='xml_reader')

To make exe file type in cmd

pyinstaller your_py_file_name.spec

It should produce dist folder where is your executable


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...