pyinstaller|打包生成的EXE报错No module named ‘openpyxl.cell._writer‘

一、问题描述

# -*- coding: utf-8 -*-
# @Create Time : 2024/4/22 13:38
# @Edit Time : 2024/4/23 10:59
# @Author : Tim
# @File : UI.py
# @Software : PyCharm


import re
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
import pandas as pd
import threading

# 新增曲目列表
SONG_NAMES = ["歌曲A", "歌曲B", "歌曲C"]

# 存储每首歌曲对应的评分
SONG_SCORES = {}


def center_window(window, width, height):
    screen_width = window.winfo_screenwidth()
    screen_height = window.winfo_screenheight()

    x = (screen_width // 2) - (width // 2)
    y = (screen_height // 2) - (height // 2)

    window.geometry(f"{width}x{height}+{x}+{y}")


def is_valid_integer(text):
    return re.match(r'^\d+$', text) and 1 <= int(text) <= 120


def save_to_excel_thread(name, age, gender, score1, score2, score3):
    data = {
        "姓名": [name],
        "年龄": [age],
        "性别": [gender],
        "歌曲A": [score1],
        "歌曲B": [score2],
        "歌曲C": [score3]
    }
    try:
        df = pd.DataFrame(data)

        # 这里假设默认当前工作目录是可写的,更健壮的实现应考虑指定路径或检查权限
        df.to_excel('data.xlsx', index=False)
        messagebox.showinfo("成功", "数据已保存到Excel文件")
    except Exception as e:
        messagebox.showerror("错误", f"保存失败: {e}")


def save_to_excel(name_entry, age_entry, gender_combobox, score_combobox1, score_combobox2, score_combobox3):
    name = name_entry.get().strip()
    age = age_entry.get().strip()
    gender = gender_combobox.get().strip()

    score1 = score_combobox1.get().strip().split(".")[0]
    score2 = score_combobox2.get().strip().split(".")[0]
    score3 = score_combobox3.get().strip().split(".")[0]

    if not all([name, age, gender, score1, score2, score3]):
        messagebox.showerror("错误", "请确保所有字段都已填写")
        return

    # 输入验证
    if not is_valid_integer(age):
        messagebox.showerror("错误", "年龄:请输入1-120的整数")
        return

    # 使用线程来异步保存数据
    save_thread = threading.Thread(target=save_to_excel_thread,
                                   args=(name, age, gender, score1, score2, score3))
    save_thread.start()


def assessors_info_window(root):
    # 评价人信息窗口
    assessors_frame = ttk.Frame(root, padding=(10, 10))
    assessors_frame.pack(fill=tk.X, padx=10, pady=10)

    # 评价人信息
    assessors_label = tk.Label(assessors_frame, text="评价人员信息", font=("Arial", 10, "bold"))
    assessors_label.grid(row=0, column=0, sticky=tk.W, padx=(0, 10))

    # 姓名部分
    name_label = tk.Label(assessors_frame, text="姓名:")
    name_label.grid(row=1, column=0, sticky=tk.E, padx=(0, 10))
    name_entry = tk.Entry(assessors_frame, width=20)
    name_entry.grid(row=1, column=1, padx=(10, 0), pady=(0, 10))

    # 年龄部分
    age_label = tk.Label(assessors_frame, text="年龄:")
    age_label.grid(row=2, column=0, sticky=tk.E, padx=(0, 10))
    age_entry = tk.Entry(assessors_frame, width=20)
    age_entry.grid(row=2, column=1, padx=(10, 0), pady=(0, 10))

    # 性别部分
    gender_label = tk.Label(assessors_frame, text="性别:")
    gender_label.grid(row=3, column=0, sticky=tk.E, padx=(0, 10))
    gender_combobox = ttk.Combobox(assessors_frame, values=["男", "女"], state="readonly", width=18)
    gender_combobox.grid(row=3, column=1, padx=(10, 0), pady=(0, 10))

    return name_entry, age_entry, gender_combobox


def song_and_score_window(root):
    global SONG_NAMES
    song_assessment_score_list = ['1.极差', '2.很差', '3.略差', '4.一般', '5.略好',
                                  '6.良好', '7.很好', '8.非常好', '9.极好', '10.完美']
    # 评价曲目与评分窗口
    song_and_score_frame = ttk.Frame(root, padding=(10, 10))
    song_and_score_frame.pack(fill=tk.X, padx=10, pady=10)

    # 评价内容
    content_label = tk.Label(song_and_score_frame, text="评价内容", font=("Arial", 10, "bold"))
    content_label.grid(row=0, column=0, sticky=tk.W, padx=(0, 10))

    # 评分  1.极差 2.很差 3.略差 4.一般 5.略好]\n[6.良好 7.很好 8.非常好 9.极好 10.完美
    score_label1 = tk.Label(song_and_score_frame, text=f"{SONG_NAMES[0]}:")
    score_label1.grid(row=1, column=0, sticky=tk.E, padx=(47, 10))
    score_combobox1 = ttk.Combobox(song_and_score_frame, values=[item for item in song_assessment_score_list],
                                   state="readonly",
                                   width=18)
    score_combobox1.grid(row=1, column=1, padx=(10, 0), pady=(0, 10))

    score_label2 = tk.Label(song_and_score_frame, text=f"{SONG_NAMES[1]}:")
    score_label2.grid(row=2, column=0, sticky=tk.E, padx=(47, 10))
    score_combobox2 = ttk.Combobox(song_and_score_frame, values=[item for item in song_assessment_score_list],
                                   state="readonly",
                                   width=18)
    score_combobox2.grid(row=2, column=1, padx=(10, 0), pady=(0, 10))

    score_label3 = tk.Label(song_and_score_frame, text=f"{SONG_NAMES[2]}:")
    score_label3.grid(row=3, column=0, sticky=tk.E, padx=(47, 10))
    score_combobox3 = ttk.Combobox(song_and_score_frame, values=[item for item in song_assessment_score_list],
                                   state="readonly",
                                   width=18)
    score_combobox3.grid(row=3, column=1, padx=(10, 0), pady=(0, 10))

    return score_combobox1, score_combobox2, score_combobox3


def create_gui():
    root = tk.Tk()
    root.title("主观评价")

    name_entry, age_entry, gender_combobox = assessors_info_window(root)
    score_combobox1, score_combobox2, score_combobox3 = song_and_score_window(root)

    # 添加保存按钮
    save_button = ttk.Button(root, text="保存到EXCEL",
                             command=lambda: save_to_excel(name_entry, age_entry, gender_combobox, score_combobox1,
                                                           score_combobox2, score_combobox3))
    save_button.pack(side=tk.BOTTOM, pady=10)

    width, height = 350, 380
    center_window(root, width, height)
    root.geometry(f"{width}x{height}")

    root.mainloop()


if __name__ == "__main__":
    create_gui()
 pyinstaller -F -w UI.py    

        使用pyinstaller打包生成的EXE在执行过程中报错,如下图所示。

pyinstaller|打包生成的EXE报错No module named ‘openpyxl.cell._writer‘_第1张图片

二、问题分析

        我在pycharm中可以正常运行UI.py,然而打包之后却报缺少这个方法,说明这个方法有可能与我的代码执行无关,尝试忽略该方法,重新打包,执行以下指令。

pyinstaller --onefile --hidden-import=openpyxl.cell._writer UI.py

pyinstaller|打包生成的EXE报错No module named ‘openpyxl.cell._writer‘_第2张图片

        可以正常运行。问题解决。

你可能感兴趣的:(Python,python)