I am writing a program that converts multi-sheet Excel files into .h5 format. The program runs normally in Python, but after being packaged into an exe file with pyinstaller, the convert_to_hdf5 function reports an error 'sequence item 2: expected str instance, NoneType found'.
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()
I have repeatedly tested various imported libraries and added hidden-import in pyinstaller, but none of them could solve the problem. I suspect that there is a dependent library that has not been added, but I don't know which one. Can anyone help me with this?