mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-27 23:35:01 +00:00
Sanitise and deduplicate scenario sheet names 🟩
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
a8c90b0d95
commit
000ebf82be
1 changed files with 21 additions and 1 deletions
|
|
@ -8,6 +8,7 @@ dynamic number of scenario sheets is handled natively.
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from io import BytesIO
|
||||
from typing import Sequence
|
||||
|
||||
|
|
@ -15,6 +16,24 @@ from openpyxl import Workbook
|
|||
|
||||
from domain.scenario_export.scenario_sheet import ExportSheet
|
||||
|
||||
# Excel forbids these in a sheet title and caps titles at 31 characters.
|
||||
_ILLEGAL_SHEET_CHARS = re.compile(r"[:\\/?*\[\]]")
|
||||
_MAX_SHEET_NAME = 31
|
||||
|
||||
|
||||
def _safe_sheet_name(name: str, used: set[str]) -> str:
|
||||
"""An Excel-legal, unique sheet name: illegal characters stripped, capped at
|
||||
31 chars, and suffixed on collision (two scenarios can share a name)."""
|
||||
clean = _ILLEGAL_SHEET_CHARS.sub("", name or "scenario").strip() or "scenario"
|
||||
clean = clean[:_MAX_SHEET_NAME]
|
||||
base, index = clean, 1
|
||||
while clean in used:
|
||||
suffix = f" ({index})"
|
||||
clean = base[: _MAX_SHEET_NAME - len(suffix)] + suffix
|
||||
index += 1
|
||||
used.add(clean)
|
||||
return clean
|
||||
|
||||
|
||||
def render_workbook(sheets: Sequence[tuple[str, ExportSheet]]) -> bytes:
|
||||
"""Render the scenario sheets into a single branded ``.xlsx`` as bytes. Each
|
||||
|
|
@ -25,8 +44,9 @@ def render_workbook(sheets: Sequence[tuple[str, ExportSheet]]) -> bytes:
|
|||
if default is not None:
|
||||
workbook.remove(default)
|
||||
|
||||
used_names: set[str] = set()
|
||||
for name, sheet in sheets:
|
||||
worksheet = workbook.create_sheet(title=name)
|
||||
worksheet = workbook.create_sheet(title=_safe_sheet_name(name, used_names))
|
||||
worksheet.append(list(sheet.columns))
|
||||
for row in sheet.rows:
|
||||
worksheet.append([row.get(column, "") for column in sheet.columns])
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue