SFM/app/pipeline/report.py
2026-06-22 07:25:27 +03:00

70 lines
2.3 KiB
Python

from __future__ import annotations
from dataclasses import dataclass
from pathlib import Path
from typing import Iterable
from openpyxl import Workbook
from openpyxl.styles import Alignment, Font, PatternFill
from openpyxl.utils import get_column_letter
from .mapping import FIXED_REPORT_COLUMNS, build_fixed_row
@dataclass
class ReportRow:
file_name: str
record_id: str
operation_index: int
operation_fields: dict[str, str]
participant_fields: dict[str, str]
def write_report(rows: Iterable[ReportRow], destination: Path) -> None:
row_list = list(rows)
columns = list(FIXED_REPORT_COLUMNS)
workbook = Workbook()
sheet = workbook.active
sheet.title = "Отчет"
sheet.freeze_panes = "A2"
_write_header(sheet, columns)
for row_index, row in enumerate(row_list, start=2):
data = build_fixed_row(
file_name=row.file_name,
record_id=row.record_id,
operation_index=row.operation_index,
operation_fields=row.operation_fields,
participant_fields=row.participant_fields,
)
for col_index, column_name in enumerate(columns, start=1):
cell = sheet.cell(
row=row_index, column=col_index, value=data.get(column_name, "")
)
if "Дата" in column_name:
cell.number_format = "DD.MM.YYYY"
if "Сумм" in column_name or "Сумма" in column_name:
cell.number_format = "#,##0.00"
_auto_width(sheet, columns)
destination.parent.mkdir(parents=True, exist_ok=True)
workbook.save(destination)
def _write_header(sheet, columns: list[str]) -> None:
fill = PatternFill(start_color="E2F0D9", end_color="E2F0D9", fill_type="solid")
for index, name in enumerate(columns, start=1):
cell = sheet.cell(row=1, column=index, value=name)
cell.font = Font(bold=True)
cell.alignment = Alignment(
horizontal="center", vertical="center", wrap_text=True
)
cell.fill = fill
def _auto_width(sheet, columns: list[str]) -> None:
for index, column_name in enumerate(columns, start=1):
width = max(12, min(60, len(column_name) + 4))
column_letter = get_column_letter(index)
sheet.column_dimensions[column_letter].width = width