Source code for dscat.dictionary
r"""Read Excel data dictionaries with openpyxl (read-only, values-only).
Cells are normalised to stripped strings with carriage returns removed (the SPARK
dictionaries ship CRLF, which otherwise leaves a stray ``\r`` in header cells).
"""
from __future__ import annotations
from pathlib import Path
from typing import Any
import openpyxl
def _clean(value: Any) -> str:
if value is None:
return ""
if isinstance(value, str):
return value.replace("\r", "").strip()
return str(value).strip()
[docs]
def sheet_names(path: Path) -> list[str]:
"""Return the worksheet names in an Excel workbook, in document order.
Parameters
----------
path : Path
Path to the ``.xlsx`` dictionary.
Returns
-------
list of str
Worksheet names.
"""
wb = openpyxl.load_workbook(path, read_only=True, data_only=True)
try:
return list(wb.sheetnames)
finally:
wb.close()
[docs]
def read_sheet(path: Path, sheet: str, max_rows: int | None = None) -> list[list[str]]:
"""Read a worksheet as rows of cleaned string cells.
Parameters
----------
path : Path
Path to the ``.xlsx`` dictionary.
sheet : str
Worksheet name.
max_rows : int, optional
Stop after this many rows; ``None`` reads the whole sheet.
Returns
-------
list of list of str
One list of stripped string cells per row.
"""
wb = openpyxl.load_workbook(path, read_only=True, data_only=True)
try:
ws = wb[sheet]
rows: list[list[str]] = []
for i, row in enumerate(ws.iter_rows(values_only=True)):
if max_rows is not None and i >= max_rows:
break
rows.append([_clean(c) for c in row])
return rows
finally:
wb.close()