export-form-4: добавил лист структура в экспорт, поправил экспорт с метаданными по editable columns

This commit is contained in:
tsygankoviva 2026-08-06 13:56:06 +03:00
parent 1eb5959a50
commit f1d6c65851
2 changed files with 37 additions and 17 deletions

View File

@ -115,6 +115,12 @@ class ExportService:
row_normalizer=self.form1_row_normalizer.normalize, row_normalizer=self.form1_row_normalizer.normalize,
value_serializer=self.value_serializer.to_excel_value, value_serializer=self.value_serializer.to_excel_value,
), ),
"STRUCTURE": DepthSheetWriter(
columns_dict=FORM1_DEPTH_COLUMNS,
row_normalizer=self.form1_row_normalizer.normalize,
value_serializer=self.value_serializer.to_excel_value,
colors_config=FORM1_COLORS["AHR"],
),
} }
self.form3_report_writer = TabularSheetWriter( self.form3_report_writer = TabularSheetWriter(
columns=FORM3_REPORT_COLUMNS, columns=FORM3_REPORT_COLUMNS,

View File

@ -1,5 +1,6 @@
from __future__ import annotations from __future__ import annotations
import abc
from collections import defaultdict from collections import defaultdict
from typing import Any, Callable from typing import Any, Callable
@ -15,7 +16,28 @@ RowNormalizer = Callable[[dict[str, Any]], dict[str, Any]]
ValueSerializer = Callable[[Any], Any] ValueSerializer = Callable[[Any], Any]
class TabularSheetWriter: class AbstractWriter(abc.ABC):
def _set_widths(self, worksheet: Worksheet):
for col in worksheet.columns:
max_len = 0
col_letter = get_column_letter(col[0].column) # Get alphabetical column name (e.g., 'A')
for cell in col:
if cell.value is not None:
cell_len = len(str(cell.value))
if cell_len > max_len:
max_len = cell_len
adjusted_width = max(max_len + 3, 10)
worksheet.column_dimensions[col_letter].width = adjusted_width
@abc.abstractmethod
def write(self, *args, **kwargs):
pass
class TabularSheetWriter(AbstractWriter):
def __init__( def __init__(
self, self,
columns: list[tuple[str, str]], columns: list[tuple[str, str]],
@ -34,9 +56,10 @@ class TabularSheetWriter:
worksheet.append( worksheet.append(
[self.value_serializer(normalized.get(key)) for key, _ in self.columns] [self.value_serializer(normalized.get(key)) for key, _ in self.columns]
) )
self._set_widths(worksheet)
class DepthSheetWriter: class DepthSheetWriter(AbstractWriter):
alignment = Alignment(horizontal='center', vertical='center') alignment = Alignment(horizontal='center', vertical='center')
thin_border = Border( thin_border = Border(
left=Side(style='thin'), left=Side(style='thin'),
@ -166,20 +189,6 @@ class DepthSheetWriter:
cell.font = Font(color=color["color"]) cell.font = Font(color=color["color"])
return current_column return current_column
def _set_widths(self, worksheet: Worksheet):
for col in worksheet.columns:
max_len = 0
col_letter = get_column_letter(col[0].column) # Get alphabetical column name (e.g., 'A')
for cell in col:
if cell.value is not None:
cell_len = len(str(cell.value))
if cell_len > max_len:
max_len = cell_len
adjusted_width = max(max_len + 3, 10)
worksheet.column_dimensions[col_letter].width = adjusted_width
def _set_color_to_row(self, ws: Worksheet, item_type: str) -> None: def _set_color_to_row(self, ws: Worksheet, item_type: str) -> None:
if not self.palette or item_type in ("SUB_ITEM", "INPUT"): if not self.palette or item_type in ("SUB_ITEM", "INPUT"):
return return
@ -199,7 +208,12 @@ class DepthSheetWriter:
def write(self, worksheet: Worksheet, rows: list[tuple]) -> None: def write(self, worksheet: Worksheet, rows: list[tuple]) -> None:
self._write_header(worksheet) self._write_header(worksheet)
for row in rows: for row in rows:
raw_data = row[3] if len(row) > 3 and isinstance(row[3], dict) else {} if len(row) > 3 and isinstance(row[3], dict):
if row[0] == 'META':
continue
raw_data = row[3]
else:
raw_data = {}
normalized = self.row_normalizer(raw_data) normalized = self.row_normalizer(raw_data)
worksheet.append( worksheet.append(
[self.value_serializer(normalized.get(key)) for key in self.columns] [self.value_serializer(normalized.get(key)) for key in self.columns]