6115

PyInstaller and python-docx module do not work together

Question:

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('\n' + '\n' + task1) textfile.write('\n' + '\n' + 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()

Answer1:

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

Answer2:

Ok so first lets just work with the <a href="https://stackoverflow.com/help/mcve" rel="nofollow">Minimal Verifiable Example</a> shall we?

from tkinter import * import tkinter.messagebox root = Tk() def Word(): wordsaveask = tkinter.messagebox.askquestion("Save", "do you want to save?") if wordsaveask == ("yes"): with open('Titan Tech.docx',"w") as f: f.write("TEST") tkinter.messagebox.showinfo('Saved', 'The file was made') else: tkinter.messagebox.showinfo("ok","did not save") button = Button(root,text="test",command=Word) button.pack() mainloop()

This works fine in the terminal but mysteriously doesn't get to the successfully saved message when opening after packing into an application.

You said that you don't get any error messages but without a terminal or ide raise TypeError would be invisible to you, so lets put something in place to redirect the message:

from tkinter import * import tkinter.messagebox root = Tk() def Word(): try: #SOMETHING HERE IS GOING WRONG wordsaveask = tkinter.messagebox.askquestion("Save", "Are you sure you want to export to a Microsoft Word file?") if wordsaveask == ("yes"): with open('Titan Tech.docx',"w") as f: f.write("TEST") tkinter.messagebox.showinfo('Save', 'The program has exported the information to a Microsoft Word document!') else: tkinter.messagebox.showinfo("ok","did not save") except: import traceback tkinter.messagebox.showinfo("ERROR",traceback.format_exc()) raise # Errors should never pass silently. - The Zen of Python, by Tim Peters button = Button(root,text="test",command=Word) button.pack() mainloop()

once I run this I get this handy little popup: <a href="https://i.stack.imgur.com/X5x0C.png" rel="nofollow"><img alt="mage of traceback, text is directly below" class="b-lazy" data-src="https://i.stack.imgur.com/X5x0C.png" data-original="https://i.stack.imgur.com/X5x0C.png" src="https://etrip.eimg.top/images/2019/05/07/timg.gif" /></a>

Traceback (most recent call last): File "/Users/Tadhg/Documents/codes/test.app/Contents/Resources/main.py", line 10, in Word with open('Titan Tech.docx',"w") as f: PermissionError: [Errno 13] Permission denied: 'Titan Tech.docx'

Now yes I am using a mac and no I am not using PyInstaller (made my own app builder with pure python code) but I still think this is a valid answer because it will tell you how to proceed with debugging. If you post the error message you get I'd be happy to help out more.

Recommend

  • How to set font of a messagebox with Python tkinter?
  • modestbranding not working for YouTube embed
  • youtube js api, internet explorer(8+, inc. 10) “SCRIPT438: Object doesn't support property or m
  • Youtube embedded video autoplay
  • Testing tkinter application
  • YTPlayerView load a list of videos
  • ffmpeg - multiple output with thumbnails
  • Get all root sites listed in share point Admin center using graph api beta
  • Why do the numeric format strings in C# round the number when not using decimals (F0)?
  • How to get a list of all blobs in a repository in Git
  • Use double quote then curly brace in powershell -Command
  • Why are views not counted if you embed a youtube iframe dynamically using jquery?
  • Deploying pre-encrypted configuration files to a production environment
  • HTML code to upload images
  • Instanciate service on startup in Angular2
  • get passwords from chrome
  • NSMutableArray Access Issue
  • Nodejs bluebird promise fails while processing image
  • Unix Network Programming Clarification
  • Django model for a Postgres view
  • C#: Import/Export Settings into/from a File
  • Clarification on min distance on LocationManager.requestLocationUpdates method, min Distance paramet
  • How can I set a binding to a Combox in a UserControl?
  • Insert new calendar with SyncAdapter- Calendar API Android
  • AJAX Html Editor Extender upload image appearing blank
  • How do I get HTML corresponding to current DOM tree?
  • JQuery Internet Explorer and ajaxstop
  • JSON response opens as a file, but I can't access it with JavaScript
  • Illegal mix of collations for operation for date/time comparison
  • Optimizing database types to compact database (SQLite)
  • TFS: Get latest causes slow project reloading
  • Running a C# exe file
  • In LanguageTool, how do you create a dictionary and use it for spell checking?
  • Change an a tag attribute in JavaScript based on screen width
  • Release, debug version and Authorization Google?
  • What do the 'size' numbers mean in the windbg !heap output?
  • using conditional logic : check if record exists; if it does, update it, if not, create it
  • Hits per day in Google Big Query
  • Reading document lines to the user (python)
  • Observable and ngFor in Angular 2