You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用py2exe打包依赖python-docx的Python脚本后运行可执行文件报错的解决方案咨询

解决py2exe打包python-docx脚本后找不到模板文件的问题

我之前也踩过这个坑!问题出在py2exe默认只会打包Python代码文件,而python-docx运行时依赖的default-footer.xml这类模板资源文件并没有被自动包含进去,而且打包后的路径结构和本地开发环境不一样,导致库找不到这些文件。

下面给你两个可行的解决办法,按需求选就行:

方法一:修改setup.py手动包含模板文件(推荐)

这个方法不需要改动原脚本,只需要调整打包配置,把python-docx的模板文件一起打包到dist目录的对应位置:

  1. 先找到你本地python-docx的templates目录路径,在Python控制台里运行这两行代码就能得到:
import docx
import os
print(os.path.join(os.path.dirname(docx.__file__), 'templates'))
  1. 修改你的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)]
)
  1. 重新运行python setup.py py2exe打包,打包完成后检查dist/docx/templates目录,确认所有xml模板文件都在里面,再运行exe就不会报错了。

方法二:适配单文件打包(如果需要生成单个exe)

如果要打包成单文件(bundle_files=1),py2exe会把所有文件解压到临时目录,这时候需要在脚本里手动指定模板文件的路径:

  1. 修改你的原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
  1. 对应的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

火山引擎 最新活动