2016-08-10 3 views
2

Я установил PyInstaller для создания исполняемых файлов для моих сценариев python, и это работает нормально. Я использовал PyPandoc для создания отчетов .docx, которые также работают нормально, когда запускаются обычные файлы python, но не из исполняемого файла PyInstaller. Он дает ошибку:PyPandoc в сочетании с 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).

+1

Можете ли вы добавить минимальный рабочий пример вашего сценария python, чтобы узнать, какую часть pandoc вы используете? Я пытался использовать только «pypandoc» и, кажется, отлично работает в моей системе Windows. Скорее всего, вам нужно добавить 'pypandoc' в качестве [скрытого импорта] (https://pythonhosted.org/PyInstaller/when-things-go-wrong.html#listing-hidden-imports) плюс некоторые другие функции dependecy. – Repiklis

+0

@Repiklis Я могу дать очень короткий пример кода, но не проверить его прямо сейчас. 'import pypandoc; pypandoc.convert (source = '# Пример заголовка \ nPlaceholder', to = 'docx', format = 'md', outputfile = 'test.docx') '. Это сохраняется в файле '.py', который я конвертирую с помощью PyInstaller с помощью команды' pyinstaller --onefile --clean -p H: \ AppData \ Python \ Python27 \ Lib \ site-packages pythonfile.py' – Mathias711

+0

Пожалуйста, напишите ваш образец кода в вопросе, чтобы другие могли понять вашу проблему. Я отправлю ответ ниже. – Repiklis

ответ

3

Здесь есть две проблемы. Первый заключается в том, что 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) 
+0

Спасибо за публикацию этого.По какой-то причине у меня нет аргумента '-p', но по крайней мере я нахожусь на правильном пути. Благодаря! – Mathias711

+0

В конце файла '.spec' вы должны добавить блок' 'collect' (https://pythonhosted.org/PyInstaller/spec-files.html#spec-file-operation) для компиляции как «один-одиник». – Repiklis

+0

Правильно ли, что аргумент 'resources' не должен быть списком? Я получаю TypeError с is, и без '[]' он работает. Для дальнейшего использования я включил папку аргументов '-p' в аргумент' pathex' (новый элемент в этом списке). – Mathias711

Смежные вопросы