Untitled
unknown
plain_text
a year ago
6.2 kB
9
Indexable
import tkinter as tk
from tkinter import filedialog, messagebox
from tkinter import ttk
from openpyxl import load_workbook
import os
import json
CONFIG_FILE = "config.json"
class ExcelViewer(tk.Tk):
def __init__(self):
super().__init__()
self.title("Excel Viewer")
self.geometry("1000x563")
# Treeview erstellen
self.treeview = ttk.Treeview(self, selectmode="browse", show="headings")
self.treeview.pack(fill="both", expand=True)
self.columns = []
self.file_path = None
# Sortierstatus initialisieren
self.sort_reverse = {} # Speichert den Sortierstatus für jede Spalte
self.load_config()
self.create_menu()
# Binde das Ereignis für Größenänderung
self.bind("<Configure>", self.adjust_column_widths)
def create_menu(self):
menu = tk.Menu(self)
self.config(menu=menu)
menu.add_command(label="Datei auswählen", command=self.select_file)
def save_config(self):
config = {
"file_path": self.file_path,
"columns": self.columns
}
with open(CONFIG_FILE, "w") as f:
json.dump(config, f, indent=4)
def load_config(self):
if os.path.exists(CONFIG_FILE):
with open(CONFIG_FILE, "r") as f:
config = json.load(f)
self.file_path = config.get("file_path")
self.columns = config.get("columns", [])
if self.file_path and self.columns:
self.load_excel_data(self.file_path)
def select_file(self):
self.file_path = filedialog.askopenfilename(filetypes=[("Excel files", "*.xlsx")])
if self.file_path:
self.save_config()
self.load_excel_data(self.file_path)
def load_excel_data(self, file_path):
try:
workbook = load_workbook(file_path)
sheet = workbook.active
# Treeview zurücksetzen
self.treeview.delete(*self.treeview.get_children())
self.treeview["columns"] = []
# Header aus der Excel-Datei holen
headers = [cell.value for cell in next(sheet.iter_rows())]
# Konfiguration prüfen
if not self.columns:
# Feste Spaltenbreite setzen
self.columns = [
{"header": header, "alignment": "center", "width": 150} # Feste Breite von 150
for header in headers
]
self.save_config()
# Treeview konfigurieren
self.treeview["columns"] = [col["header"] for col in self.columns]
for column in self.columns:
header_name = column["header"]
self.treeview.heading(
header_name,
text=header_name,
command=lambda c=header_name: self.sort_column(c)
)
self.treeview.column(header_name,
width=column["width"],
anchor=self.get_anchor(column["alignment"]))
# Initialisierungsstatus der Sortierfolge
if header_name not in self.sort_reverse:
self.sort_reverse[header_name] = False
# Daten einfügen, nur wenn mindestens eine Zelle der Zeile nicht leer ist
for row in sheet.iter_rows(min_row=2, values_only=True):
if any(value is not None and value != "" for value in
row): # Prüft, ob mindestens eine Zelle nicht leer ist
row_values = [
value if value is not None else "" # None-Werte durch leeren String ersetzen
for value in row
]
self.treeview.insert("", "end", values=row_values)
except Exception as e:
messagebox.showerror("Fehler", f"Konnte Datei nicht laden: {e}")
def sort_column(self, column):
"""Sortiert die Treeview-Einträge nach der angegebenen Spalte und zeigt ein Symbol für die Sortierreihenfolge."""
data = [
(self.treeview.item(item, "values"), item)
for item in self.treeview.get_children("")
]
# Spaltenindex anhand des Spaltennamens
col_idx = self.treeview["columns"].index(column)
# Sortieren: Alle Werte als Strings behandeln
sorted_data = sorted(
data,
key=lambda x: str(x[0][col_idx]),
reverse=self.sort_reverse[column]
)
# Sortierfolge umkehren
self.sort_reverse[column] = not self.sort_reverse[column]
# Treeview zurücksetzen und neu sortierte Einträge einfügen
for index, (_, item_id) in enumerate(sorted_data):
self.treeview.move(item_id, "", index)
# Überschriften aktualisieren
self.update_headers(column)
def update_headers(self, sorted_column):
"""Aktualisiert die Spaltenüberschriften und fügt ein Sortiersymbol hinzu."""
for column in self.treeview["columns"]:
# Entferne vorhandene Symbole
base_text = column
if column.endswith(" ▲") or column.endswith(" ▼"):
base_text = column[:-2]
# Füge ein Symbol für die sortierte Spalte hinzu
if column == sorted_column:
sort_symbol = "▲" if not self.sort_reverse[column] else "▼"
self.treeview.heading(column, text=f"{base_text} {sort_symbol}")
else:
self.treeview.heading(column, text=base_text)
def adjust_column_widths(self, event=None):
"""Passt die Spaltenbreiten an, aber nur für die Spalten mit festen Breiten."""
# Keine Veränderung der Spaltenbreiten hier, da die Spalten feste Breiten haben
def get_anchor(self, alignment):
if alignment == "left":
return "w"
elif alignment == "center":
return "center"
elif alignment == "right":
return "e"
return "w"
if __name__ == "__main__":
app = ExcelViewer()
app.mainloop()
Editor is loading...
Leave a Comment