如何在cx_Freeze打包的exe中正确使用openpyxl读取Excel文件?
解决cx_Freeze打包后openpyxl无法读取Excel模板的问题
你遇到的问题很典型——cx_Freeze打包后,程序运行的上下文路径和开发时完全不同,原来用__file__获取的路径指向的是cx_Freeze临时解压目录里的脚本,而非你的exe所在位置,自然找不到模板文件。下面给你两种可行的解决方案,按需选择:
方案一:将模板文件放在exe同目录(推荐,方便用户替换模板)
1. 修改路径获取逻辑
把原来的路径代码替换成下面的逻辑,它会自动判断当前是开发环境还是打包后的exe环境:
import os import sys def get_app_base_path(): # 判断是否处于cx_Freeze冻结状态 if getattr(sys, 'frozen', False): # 冻结状态下,sys.executable就是你的exe文件路径 base_path = os.path.dirname(sys.executable) else: # 开发环境下,用原来的方式获取脚本所在路径 base_path = os.path.dirname(os.path.realpath(__file__)) return base_path # 拼接模板文件路径 current_path = get_app_base_path() file_path = os.path.join(current_path, "folder", "filename.xlsx") wb = openpyxl.load_workbook(file_path)
2. 在setup.py中配置文件复制
打包时需要告诉cx_Freeze把你的模板文件夹复制到exe输出目录,修改你的setup.py:
from cx_Freeze import setup, Executable import os # 批量收集所有模板文件(如果有多个的话) include_files = [] template_folder = "folder" for root, dirs, files in os.walk(template_folder): for file in files: if file.endswith(".xlsx"): # 源路径和目标路径保持一致结构 src = os.path.join(root, file) dest = os.path.join(root, file) include_files.append((src, dest)) # 定义可执行文件 exe = Executable( script="你的主脚本文件名.py", base="Win32GUI" # 如果是GUI程序,加上这个避免黑框;控制台程序可以去掉 ) setup( name="你的应用名称", version="1.0", description="应用描述", executables=[exe], options={ "build_exe": { "include_files": include_files, # 确保openpyxl被打包进去,避免依赖缺失 "packages": ["openpyxl"], # 可选:排除不需要的模块减小包体积 "excludes": ["tkinter", "unittest"] } } )
打包后,你会在build目录下的exe文件夹里看到和开发环境一样的folder文件夹,里面的模板文件都在,exe运行时就能正确读取了。
方案二:将模板文件打包进exe内部(适合不想让用户修改模板的场景)
如果不想让用户直接接触模板文件,可以把它们打包进exe,程序运行时cx_Freeze会自动把这些文件解压到临时目录,你可以通过sys._MEIPASS访问这个目录:
1. 修改路径获取逻辑
import os import sys def get_template_file_path(): if getattr(sys, 'frozen', False): # 冻结状态下,模板文件在sys._MEIPASS指向的临时目录 base_path = sys._MEIPASS else: base_path = os.path.dirname(os.path.realpath(__file__)) return os.path.join(base_path, "folder", "filename.xlsx") file_path = get_template_file_path() wb = openpyxl.load_workbook(file_path)
2. setup.py配置和方案一完全相同
同样需要在include_files里添加模板文件,cx_Freeze会自动把它们打包进exe,运行时解压到临时目录供程序读取。
额外注意事项
- 打包后先去
build目录检查一下,确认模板文件是否被正确复制/打包; - 如果运行exe时还是提示找不到文件,可以在代码里加一行
print(file_path),看实际路径是什么,排查问题; - 确保你的openpyxl版本和打包环境一致,避免依赖版本冲突。
内容的提问来源于stack exchange,提问作者octo
相关产品推荐
相关产品推荐

