openpyxl not found in exe file made with pyinstaller
Question:
I wrote a Python code using a virtual evn with pip, and I built it with pyinstaller to use it as executable, and it works. Now I’m moving to conda environment to use also geopandas, fiona and gdal. I can run it without any errors, but if I build the code into the .exe, this error raised:
Traceback (most recent call last):
File "main.py", line 5, in <module>
File "PyInstallerloaderpyimod03_importers.py", line 495, in exec_module
File "openpyxl__init__.py", line 6, in <module>
File "PyInstallerloaderpyimod03_importers.py", line 495, in exec_module
File "openpyxlworkbook__init__.py", line 4, in <module>
File "PyInstallerloaderpyimod03_importers.py", line 495, in exec_module
File "openpyxlworkbookworkbook.py", line 9, in <module>
File "PyInstallerloaderpyimod03_importers.py", line 495, in exec_module
File "openpyxlworksheet_write_only.py", line 13, in <module>
File "openpyxlworksheet_writer.py", line 23, in init openpyxl.worksheet._writer
ModuleNotFoundError: No module named 'openpyxl.cell._writer'
[12248] Failed to execute script 'main' due to unhandled exception!
I tried also to reinstall openpyxl through conda, but nothing changed.
The command line to build is:
pyinstaller --onefile main_new.spec main.py
and the spec file is:
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(['main.py'],
pathex=[],
binaries=[],
datas=[('./inputs/*.csv', 'inputs')],
hiddenimports=[
'openpyxl',
'xlrd',
'xlswriter'
],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='DESAT',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True,
disable_windowed_traceback=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None )
How can I solve this issue?
Thank you!
Answers:
I think it might help to collect all submodules of openpyxl when building your *.exe.
Refer to this or to the many answers on this platform regarding hook-files:
https://pyinstaller.org/en/stable/hooks.html#PyInstaller.utils.hooks.collect_submodules
edit: In my case I use it this way:
hook-files in the directory of your *.py (you want to convert) contain the collect_submodules
function (right side in the screenshot) and in the *.spec file the hookspath
is defined to be the same as your *.py (left side of the screenshot)
The error is referring to ‘openpyxl.cell._writer’ that is inside openpyxl. in fact, pyinstaller was actually able to find openpyxl.
I checked inside, and I found that in the pip environment i was using the 3.0.9 version, while in the conda one I was using the 3.0.10.
Downgrading to 3.0.9, no –hidden-import or other needed, it is just working.
Explicitly importing the module does the trick. It can be imported from the command line, or by modifying the .spec file to import.
Command line mode:
pyinstaller main.py --hidden-import openpyxl.cell._writer
Note: The module name does not need to be wrapped in quotes
Modify the .spec way:
a = Analysis(
...
hiddenimports=['openpyxl.cell._writer'],
...
)
I wrote a Python code using a virtual evn with pip, and I built it with pyinstaller to use it as executable, and it works. Now I’m moving to conda environment to use also geopandas, fiona and gdal. I can run it without any errors, but if I build the code into the .exe, this error raised:
Traceback (most recent call last):
File "main.py", line 5, in <module>
File "PyInstallerloaderpyimod03_importers.py", line 495, in exec_module
File "openpyxl__init__.py", line 6, in <module>
File "PyInstallerloaderpyimod03_importers.py", line 495, in exec_module
File "openpyxlworkbook__init__.py", line 4, in <module>
File "PyInstallerloaderpyimod03_importers.py", line 495, in exec_module
File "openpyxlworkbookworkbook.py", line 9, in <module>
File "PyInstallerloaderpyimod03_importers.py", line 495, in exec_module
File "openpyxlworksheet_write_only.py", line 13, in <module>
File "openpyxlworksheet_writer.py", line 23, in init openpyxl.worksheet._writer
ModuleNotFoundError: No module named 'openpyxl.cell._writer'
[12248] Failed to execute script 'main' due to unhandled exception!
I tried also to reinstall openpyxl through conda, but nothing changed.
The command line to build is:
pyinstaller --onefile main_new.spec main.py
and the spec file is:
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(['main.py'],
pathex=[],
binaries=[],
datas=[('./inputs/*.csv', 'inputs')],
hiddenimports=[
'openpyxl',
'xlrd',
'xlswriter'
],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='DESAT',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True,
disable_windowed_traceback=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None )
How can I solve this issue?
Thank you!
I think it might help to collect all submodules of openpyxl when building your *.exe.
Refer to this or to the many answers on this platform regarding hook-files:
https://pyinstaller.org/en/stable/hooks.html#PyInstaller.utils.hooks.collect_submodules
edit: In my case I use it this way:
hook-files in the directory of your *.py (you want to convert) contain the collect_submodules
function (right side in the screenshot) and in the *.spec file the hookspath
is defined to be the same as your *.py (left side of the screenshot)
The error is referring to ‘openpyxl.cell._writer’ that is inside openpyxl. in fact, pyinstaller was actually able to find openpyxl.
I checked inside, and I found that in the pip environment i was using the 3.0.9 version, while in the conda one I was using the 3.0.10.
Downgrading to 3.0.9, no –hidden-import or other needed, it is just working.
Explicitly importing the module does the trick. It can be imported from the command line, or by modifying the .spec file to import.
Command line mode:
pyinstaller main.py --hidden-import openpyxl.cell._writer
Note: The module name does not need to be wrapped in quotes
Modify the .spec way:
a = Analysis(
...
hiddenimports=['openpyxl.cell._writer'],
...
)