PyPandoc in combination with PyInstaller

最后都变了- 提交于 2019-12-12 17:32:56

问题


I installed PyInstaller to create executables for my python scripts, and that works fine. I used PyPandoc to create .docx reports, which also run fine when the normal python files are run, but not from the PyInstaller generated executable. It gives the error:

Traceback (most recent call last):
  File "src\flexmodel_postcalc.py", line 295, in postcalculate_everything
  File "src\flexmodel_postcalc.py", line 281, in generate_report_docx
  File "src\flexmodel_report_docx.py", line 118, in generate_text_useages_docx
  File "pypandoc\__init__.py", line 50, in convert
  File "pypandoc\__init__.py", line 70, in _convert
  File "pypandoc\__init__.py", line 197, in get_pandoc_formats
  File "pypandoc\__init__.py", line 336, in _ensure_pandoc_path
OSError: No pandoc was found: either install pandoc and add it
to your PATH or install pypandoc wheels with included pandoc.

During the executable creation I see no strange issues about PyPandoc. How can I include Pandoc into my executable so others (without Python and/or Pandoc installation) can use the executable and create .docx reports?

edit: a working process included the following steps:

  1. Create a file including the following code:

    import pypandoc
    pypandoc.convert(sou‌​rce='# Sample title\nPlaceholder', to='docx', format='md', outputfile='test.doc‌​x')
    
  2. Save this file as pythonfile.py

  3. create an executable with PyInstaller:

    pyinstaller --onefile --clean pythonfile.py
    
  4. Now the executable should run on a computer without Pandoc (or PyPandoc) installed.


回答1:


There are two issues here. The first one is that pypandoc needs pandoc.exe to work. This is not picked up by pyinstaller automatically, but you can specify it manually.

To do this you you have to create a .spec file. The one I generated and used looks like this:

block_cipher = None

a = Analysis(['pythonfile.py'],
             pathex=['CodeDIR'],
             binaries=[],
             datas=[],
             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,
          a.binaries,
          a.zipfiles,
          a.datas,
          name='EXEName',
          debug=False,
          strip=False,
          upx=True,
          console=True , 
          resources=['YourPandocLocationHere\\\\pandoc.exe'])

You can build the executable by using pyinstaller myspec.spec. Don't forget to change the paths and the name parameter.

If you were building that in a directory mode this should be enough. However, for the one-file mode, things are a bit more complicated due to the way the pyinstaller bootloader process works. The pandoc.exe file is unzipped during execution in a temporary folder, but the execution happens in your original .exe folder. According to this question, you have to add the following lines to your code before calling pypandoc to change your current folder, if you run the frozen code.

if hasattr(sys, '_MEIPASS'):
    os.chdir(sys._MEIPASS)


来源:https://stackoverflow.com/questions/38874563/pypandoc-in-combination-with-pyinstaller

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!