使用py2exe打包依赖python-docx的Python脚本后运行可执行文件报错的解决方案咨询
解决py2exe打包python-docx脚本后找不到模板文件的问题
我之前也踩过这个坑!问题出在py2exe默认只会打包Python代码文件,而python-docx运行时依赖的default-footer.xml这类模板资源文件并没有被自动包含进去,而且打包后的路径结构和本地开发环境不一样,导致库找不到这些文件。
下面给你两个可行的解决办法,按需求选就行:
方法一:修改setup.py手动包含模板文件(推荐)
这个方法不需要改动原脚本,只需要调整打包配置,把python-docx的模板文件一起打包到dist目录的对应位置:
- 先找到你本地python-docx的templates目录路径,在Python控制台里运行这两行代码就能得到:
import docx import os print(os.path.join(os.path.dirname(docx.__file__), 'templates'))
- 修改你的
setup.py,添加data_files参数来指定要打包的模板文件:
from distutils.core import setup import py2exe import docx import os # 获取python-docx的templates目录绝对路径 docx_templates_dir = os.path.join(os.path.dirname(docx.__file__), 'templates') # 收集templates目录下的所有模板文件 template_files = [os.path.join(docx_templates_dir, filename) for filename in os.listdir(docx_templates_dir)] setup( # 如果是控制台程序就把windows改成console windows=['你的脚本名称.py'], options={ 'py2exe': { 'includes': ['docx'], # 如果你不需要单文件打包,用bundle_files=3(默认)会更稳定 'bundle_files': 3, 'dist_dir': 'dist' } }, # 把模板文件打包到dist/docx/templates目录下,和原库的路径结构一致 data_files=[('docx/templates', template_files)] )
- 重新运行
python setup.py py2exe打包,打包完成后检查dist/docx/templates目录,确认所有xml模板文件都在里面,再运行exe就不会报错了。
方法二:适配单文件打包(如果需要生成单个exe)
如果要打包成单文件(bundle_files=1),py2exe会把所有文件解压到临时目录,这时候需要在脚本里手动指定模板文件的路径:
- 修改你的原Python脚本,在开头添加路径适配代码:
import sys import os import docx # 处理py2exe单文件打包后的临时路径 if hasattr(sys, '_MEIPASS'): # sys._MEIPASS是py2exe单文件运行时的临时解压目录 docx_template_path = os.path.join(sys._MEIPASS, 'docx', 'templates') # 覆盖python-docx内部的模板目录路径 docx.parts.story.PART_TEMPLATE_DIR = docx_template_path from docx.shared import PackageReader PackageReader._TEMPLATE_DIR = docx_template_path
- 对应的
setup.py还是要保留data_files配置,确保模板文件被打包进去:
from distutils.core import setup import py2exe import docx import os docx_templates_dir = os.path.join(os.path.dirname(docx.__file__), 'templates') template_files = [os.path.join(docx_templates_dir, f) for f in os.listdir(docx_templates_dir)] setup( windows=['你的脚本名称.py'], options={ 'py2exe': { 'includes': ['docx'], 'bundle_files': 1, # 单文件打包 'dist_dir': 'dist' } }, data_files=[('docx/templates', template_files)] )
这样打包出来的单文件exe运行时,就能在临时目录里找到模板文件了。
内容的提问来源于stack exchange,提问作者yukta sarode




