Kit Manager: add Export as XLS button

Saves the kit table to an Excel file with section headers, check
marks, and all four data columns. Default filename is based on the
open SAX file.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-09-11 13:06:30 +03:00
co-authored by Claude Opus 4.6
parent db8472371e
commit d3d141cca8
2 changed files with 70 additions and 2 deletions
+69 -1
View File
@@ -15,8 +15,9 @@ declared can be unticked, which turns its Action into REMOVE. An installed kit t
declared starts unticked, and ticking it adds it at its newest build.
"""
import os
import tkinter as tk
from tkinter import messagebox, ttk
from tkinter import filedialog, messagebox, ttk
import app_state
import palette
@@ -267,6 +268,9 @@ class KitsPanel:
button_row, text="Update kits", command=self._update_marked,
).pack(side=tk.LEFT, padx=6)
ttk.Button(button_row, text="Close", command=self.close).pack(side=tk.RIGHT)
ttk.Button(
button_row, text="Export as XLS", command=self._export_xls,
).pack(side=tk.RIGHT, padx=6)
self.rows = []
self.row_by_item = {}
@@ -286,6 +290,70 @@ class KitsPanel:
self._close_editor()
self.frame.destroy()
def _export_xls(self):
try:
from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill, Alignment
except ImportError:
messagebox.showerror("Export", "openpyxl is not installed.")
return
default_name = ""
if app_state.current_file_path:
base = os.path.splitext(os.path.basename(app_state.current_file_path))[0]
default_name = f"{base}_kits.xlsx"
path = filedialog.asksaveasfilename(
title="Export Kit Table",
defaultextension=".xlsx",
initialfile=default_name,
filetypes=[("Excel Files", "*.xlsx")],
)
if not path:
return
wb = Workbook()
ws = wb.active
ws.title = "Kits"
headers = ["", "Kit name", "Installed", "Latest", "Action"]
header_font = Font(bold=True)
section_fill = PatternFill(start_color="DCDCDC", end_color="DCDCDC", fill_type="solid")
for col, header in enumerate(headers, 1):
cell = ws.cell(row=1, column=col, value=header)
cell.font = header_font
row_num = 2
for row in self.rows:
if "section" in row:
cell = ws.cell(row=row_num, column=2, value=row["section"])
cell.font = Font(bold=True)
for col in range(1, 6):
ws.cell(row=row_num, column=col).fill = section_fill
row_num += 1
continue
check = "✓" if row["checked"] else ""
ws.cell(row=row_num, column=1, value=check).alignment = Alignment(horizontal="center")
ws.cell(row=row_num, column=2, value=row["kit"])
ws.cell(row=row_num, column=3, value=row["installed_text"])
ws.cell(row=row_num, column=4, value=row["latest_text"])
ws.cell(row=row_num, column=5, value=self._action_text(row))
row_num += 1
ws.column_dimensions["A"].width = 4
ws.column_dimensions["B"].width = 28
ws.column_dimensions["C"].width = 16
ws.column_dimensions["D"].width = 16
ws.column_dimensions["E"].width = 30
try:
wb.save(path)
app_state.set_status(f"Kit table exported to {os.path.basename(path)}")
except Exception as e:
messagebox.showerror("Export", f"Could not save file:\n{e}")
def _close_editor(self):
if self._editor_widget is not None:
self._editor_widget.destroy()