from typing import List, Dict, Any from .base import Formatter from ..types import ReportRow class HTMLFormatter(Formatter): """Форматтер для экспорта отчёта в HTML.""" def __init__(self, **kwargs): super().__init__() def format(self, rows: List[ReportRow]) -> str: # Сгруппируем данные projects: Dict[str, Dict[str, List[ReportRow]]] = {} for r in rows: proj = r["project"] ver = r["version"] if proj not in projects: projects[proj] = {} if ver not in projects[proj]: projects[proj][ver] = [] projects[proj][ver].append(r) lines = [ '', " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", ] for project, versions in projects.items(): total_project_rows = sum(len(tasks) for tasks in versions.values()) first_version_in_project = True for version, task_rows in versions.items(): row_span_version = len(task_rows) first_row_in_version = True for r in task_rows: lines.append(" ") # Ячейка "Проект" - только в первой строке проекта if first_version_in_project and first_row_in_version: lines.append( f' ' ) # Ячейка "Версия" - только в первой строке версии if first_row_in_version: lines.append( f' ' ) first_row_in_version = False # Остальные колонки task_cell = f"{r['issue_id']}. {r['subject']}" lines.append(f" ") lines.append(f" ") lines.append(f" ") lines.append(" ") first_version_in_project = False lines.append(" ") lines.append("
Наименование ПроектаНомер версии*ЗадачаСтатус Готовность*Затрачено за отчетный период
{project}{version}{task_cell}{r['status_ru']}{r['time_text']}
") return "\n".join(lines) def save(self, rows: List[ReportRow], output_path: str) -> None: content = self.format(rows) with open(output_path, "w", encoding="utf-8") as f: f.write(content)