import csv import io from typing import List from ..types import ReportRow from .base import Formatter class CSVFormatter(Formatter): """Форматтер для экспорта в CSV. Использует полные значения project/version (а не display-значения с пустыми ячейками для групп). Каждая строка CSV самодостаточна — это корректно для табличного формата (#31). Файл сохраняется в UTF-8 с BOM (utf-8-sig) для корректного отображения кириллицы в Microsoft Excel (#26). """ def __init__(self, no_time: bool = False, **_kwargs): super().__init__() self.no_time = no_time def format(self, rows: List[ReportRow]) -> str: output = io.StringIO() writer = csv.writer(output, dialect="excel") headers = ["Project", "Version", "Issue ID", "Subject", "Status"] if not self.no_time: headers.append("Spent Time") writer.writerow(headers) for r in rows: time_text = r["time_text"].replace("\n", " / ") data = [ r["project"], r["version"], r["issue_id"], r["subject"], r["status_ru"], ] if not self.no_time: data.append(time_text) writer.writerow(data) return output.getvalue() def save(self, rows: List[ReportRow], output_path: str) -> None: content = self.format(rows) with open(output_path, "w", encoding="utf-8-sig", newline="") as f: f.write(content)