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!

Asked By: Francesco Chirico

||

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)
enter image description here

Answered By: flipSTAR

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.

Answered By: Francesco Chirico

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'],
...
)
Answered By: Bob Yang