質問: タイトルの通りなのですが、 PythonファイルをPyinstallerを使ってexeファイルにしたのですが、上手く実行できません。 因みにそのPythonファイルではpipしたpptxというパッケージをインポートしております。 pipしたパッケージをインポートしている.pyファイルは、exeファイルに変換しても実行できないのでしょうか? 何方かご教示願います。 【追記】 実行ファイルを実行しようとすると、 pptx.exc.PackageNotFoundError: Package not found at 'C:\Users\sassp\AppData\Local\Temp\_MEI112482\pptx\templates\default.pptx' というエラーが出てしまいます。 失礼いたしました。
回答: `python-pptx` は、自身のパッケージディレクトリにエラーメッセージが言っている `default.pptx` 等の **データファイルを持っているのですが、これが PyInstaller によって exe ファイルに同梱されていない** ことが原因です。 PyInstaller はスクリプトの `import` 文を辿って必要なファイルを探しに行くのですが、実行対象ではないただのデータファイルは `import` されるわけではありませんから、当然ながらこの処理では見つけることが出来ず、出力結果に含まれません。従って、 **データファイルはユーザが明示的に同梱することを指定する** 必要が御座います。 こういった場合 ドキュメントに記載されている 通り、 `--add-data` というコマンドライン引数を使うか、あるいは spec ファイルで `Analysis.datas` に追加してやることで、全て手動で含めてやっても良いのですが、今回のように **特定のパッケージに含まれるデータファイルを指定する場合、そのパッケージ名で自動的に起動される hook ファイルを作成するのが簡単** です。 PyInstaller の hook については こちらのドキュメント を御読み頂くと良いかと存じますが、簡単に言えば `example.mypackage` というファイルが `import` されているスクリプトを exe 化する時、 `hook-example.mypackage.py` という名前のファイルがあれば自動的に実行し、必要なデータファイルの指定などの追加処理を加えることが出来る仕組みです。 幸い、 **「あるパッケージ内のデータファイルを探して追加する」という処理は頻出なので、 `collect_data_files()` という関数 が用意されております** から、これを使うだけで済みます。 `pptx` パッケージの `import` に合わせるため、以下のようなファイルを `hook-pptx.py` という名前で作成し、そのファイルが入ったフォルダを `pyinstaller` 実行時に `--additional-hooks-dir` というコマンドライン引数で指定してあげてください。自動的に `pptx` のパッケージフォルダ内にあるデータファイルを検索し、出力される exe ファイルに同梱してくれるようになるはずです。 ``` from PyInstaller.utils.hooks import collect_data_files datas = collect_data_files('pptx') ```