【问题标题】:PyPandoc in combination with PyInstallerPyPandoc 与 PyInstaller 结合使用
【发布时间】:2016-12-16 21:44:39
【问题描述】:

我安装了 PyInstaller 来为我的 python 脚本创建可执行文件,而且效果很好。我使用 PyPandoc 创建了.docx 报告,它在运行普通 python 文件时也可以正常运行,但不能从 PyInstaller 生成的可执行文件中运行。它给出了错误:

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.

在创建可执行文件期间,我没有看到有关 PyPandoc 的奇怪问题。如何将 Pandoc 包含到我的可执行文件中,以便其他人(未安装 Python 和/或 Pandoc)可以使用该可执行文件并创建 .docx 报告?

编辑:一个工作过程包括以下步骤:

  1. 创建一个包含以下代码的文件:

    import pypandoc
    pypandoc.convert(sou‌​rce='# Sample title\nPlaceholder', to='docx', format='md', outputfile='test.doc‌​x')
    
  2. 将此文件另存为pythonfile.py

  3. 使用 PyInstaller 创建可执行文件:

    pyinstaller --onefile --clean pythonfile.py
    
  4. 现在可执行文件应该在没有安装 Pandoc(或 PyPandoc)的计算机上运行。

【问题讨论】:

  • 您能否添加一个 Python 脚本的最小工作示例来查看您正在使用 pandoc 的哪个部分?我只尝试了pypandoc,似乎在我的 Windows 系统中运行良好。您很可能需要将pypandoc 添加为hidden import 以及其他一些依赖项。
  • @Repiklis 我可以给出一个非常简短的示例代码,但现在不进行测试。 import pypandoc; pypandoc.convert(source='# Sample title\nPlaceholder', to='docx', format='md', outputfile='test.docx')。这保存在一个.py 文件中,我通过命令pyinstaller --onefile --clean -p H:\AppData\Python\Python27\Lib\site-packages pythonfile.py 使用PyInstaller 进行转换
  • 请在问题中发布您的示例代码,以便其他人了解您的问题。我将在下面发布答案。
  • @Repiklis 添加了它。提前致谢!

标签: python pyinstaller pandoc pypandoc


【解决方案1】:

这里有两个问题。第一个是pypandoc 需要pandoc.exe 才能工作。 pyinstaller 不会自动获取它,但您可以手动指定它。

要做到这一点,你必须create a .spec file。我生成和使用的看起来是这样的:

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'])

您可以使用pyinstaller myspec.spec 构建可执行文件。不要忘记更改路径和name 参数。

如果您在目录模式下构建它,这应该足够了。但是,对于 one-file 模式,由于 pyinstaller bootloader process 的工作方式,事情有点复杂。 pandoc.exe 文件在执行期间被解压缩到一个临时文件夹中,但执行发生在您原来的 .exe 文件夹中。根据this question,如果您运行冻结的代码,您必须在调用 pypandoc 更改当前文件夹之前将以下行添加到您的代码中。

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

【讨论】:

  • 感谢您发布此信息。由于某种原因,我没有让-p 参数起作用,但至少我走在正确的轨道上。谢谢!
  • 您必须在.spec 文件的末尾添加collect block 才能编译为one-dir
  • resources 参数不应该是一个列表是否正确?我得到一个带有 is 的 TypeError,没有 [] 它可以工作。为了将来参考,我将 -p 参数文件夹包含在 pathex 参数中(该列表中的一个新项目)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-22
  • 2019-08-06
  • 2013-02-01
  • 2013-01-10
  • 2018-09-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多