diff --git a/redmine_reporter/formatters/factory.py b/redmine_reporter/formatters/factory.py index cf8aaa1..3142502 100644 --- a/redmine_reporter/formatters/factory.py +++ b/redmine_reporter/formatters/factory.py @@ -4,6 +4,7 @@ from .console import TableFormatter, CompactFormatter from .csv import CSVFormatter from .markdown import MarkdownFormatter from .odt import ODTFormatter +from .html import HTMLFormatter # Словарь для сопоставления расширений файлов с классами форматтеров @@ -11,6 +12,7 @@ FORMATTER_MAP: Dict[str, Type[Formatter]] = { ".odt": ODTFormatter, ".csv": CSVFormatter, ".md": MarkdownFormatter, + ".html": HTMLFormatter, } diff --git a/redmine_reporter/formatters/html.py b/redmine_reporter/formatters/html.py new file mode 100644 index 0000000..307c6f8 --- /dev/null +++ b/redmine_reporter/formatters/html.py @@ -0,0 +1,79 @@ +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 = [ + '
| Наименование Проекта | ", + "Номер версии* | ", + "Задача | ", + "Статус Готовность* | ", + "Затрачено за отчетный период | ", + "
|---|---|---|---|---|
| {project} | ' + ) + + # Ячейка "Версия" - только в первой строке версии + if first_row_in_version: + lines.append( + f'{version} | ' + ) + first_row_in_version = False + + # Остальные колонки + task_cell = f"{r['issue_id']}. {r['subject']}" + lines.append(f"{task_cell} | ") + lines.append(f"{r['status_ru']} | ") + lines.append(f"{r['time_text']} | ") + + lines.append("