在Python处理HDF5格式时出现错误 'sequence item 2: expected str instance, NoneType found

0 投票
0 回答
22 浏览
提问于 2025-04-12 08:24

我正在写一个程序,用来把多工作表的Excel文件转换成.h5格式。这个程序在Python里运行得很好,但当我用pyinstaller打包成exe文件后,convert_to_hdf5这个函数就报错了,错误信息是'序列项2:期望是字符串实例,但找到了NoneType'。

import tkinter as tk
from tkinter import filedialog, messagebox
import pandas as pd
import numpy as np
from pathlib import Path
import threading
import os
from os.path import expanduser
from datetime import datetime

class ExcelToHDF5Converter:
    def __init__(self, root):
        self.root = root
        self.root.title("Excel转HDF5")
        self.folder_path = ""
        self.setup_ui()

    def setup_ui(self):
        self.center_window(350, 180)
        # set window
        root.configure(background='#f0f0f0')
        
        self.convert_button = tk.Button(self.root, text="Select a Excel File", width=30, command=self.start_convert, padx=10, pady=5)
        self.convert_button.pack(pady=20)

        self.open_path_button = tk.Button(self.root, text="open folder", width=30, command=self.open_path, padx=10, pady=5)
        self.open_path_button.pack(pady=20)
        self.open_path_button.config(state=tk.DISABLED)

    def center_window(self, width, height):
        screen_width = self.root.winfo_screenwidth()
        screen_height = self.root.winfo_screenheight()
        x = (screen_width / 2) - (width / 2)
        y = (screen_height / 3) - (height / 2)
        self.root.geometry('%dx%d+%d+%d' % (width, height, x, y))

    def start_convert(self):
        file_path = filedialog.askopenfilename(filetypes=[("Excel文件", "*.xlsx *.xls")])
        if not file_path:
            # messagebox.showinfo("message", "select excel file")  
            return
        
        self.convert_button.config(text="Converting, please wait...", state=tk.DISABLED)
        threading.Thread(target=self.convert_to_hdf5, args=(file_path,)).start()

    def convert_to_hdf5(self, file_path):
        error_message = ''  # error_message

        downloads_path = os.path.join(expanduser("~"), 'Downloads')
        current_time = datetime.now().strftime("%Y%m%d%H%M%S")

        original_path = Path(file_path)
        new_filename = f"{original_path.stem}-{current_time}"
        hdf5_filename = Path(new_filename).with_suffix('.h5')
        hdf5_path = Path(downloads_path) / hdf5_filename

        try:
            xls = pd.ExcelFile(file_path)
            with pd.HDFStore(hdf5_path, 'w') as hdf:
                for sheet_name in xls.sheet_names:
                    df = pd.read_excel(xls, sheet_name=sheet_name, dtype=str)
                    df.fillna("", inplace=True)  # replace NaN to ""
                    df = df.astype(str)  
                    safe_sheet_name = sheet_name.replace(' ', '_').replace('-', '_')
                    if df.shape[0] < 3:  # if data line <3,pass to next sheet
                        print(f"Skipping empty sheet: {sheet_name}")
                        continue
                    print(sheet_name)  
                    print(df)

                    hdf.put(safe_sheet_name, df, data_columns=False)

                self.folder_path = downloads_path
                self.root.after(0, lambda: self.open_path_button.config(text="Conversion successful, open folder", state=tk.NORMAL))

        except Exception as e:
            error_message = f"Conversion failed: {e}"

        finally:
            if error_message:
                self.root.after(0, lambda: messagebox.showerror("Error", error_message))
                print(error_message)
            self.root.after(0, lambda: self.convert_button.config(text="Select a Excel File", state=tk.NORMAL))
            
    def open_path(self):
        folder_path = self.folder_path
        if folder_path:
            try:
                os.startfile(folder_path)
            except Exception as e:
                messagebox.showerror("Error", f"Failed to open folder: {e}")

if __name__ == "__main__":
    root = tk.Tk()
    app = ExcelToHDF5Converter(root)
    root.mainloop()

我反复测试了各种导入的库,还在pyinstaller里添加了隐藏导入,但都没能解决这个问题。我怀疑有一个依赖库没有被添加,但我不知道具体是哪个。有没有人能帮我解决这个问题?

0 个回答

暂无回答

撰写回答