From 4a5dee7a14797029fb2354bc4a92d2c722dddb41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9A=D0=BE=D0=BA=D0=BE=D1=81=20=D0=90=D1=80=D1=82=D0=B5?= =?UTF-8?q?=D0=BC=20=D0=9D=D0=B8=D0=BA=D0=BE=D0=BB=D0=B0=D0=B5=D0=B2=D0=B8?= =?UTF-8?q?=D1=87?= Date: Wed, 21 Jan 2026 12:45:41 +0700 Subject: [PATCH] Update template with table-styles --- redmine_reporter/formatter_odt.py | 14 +++++++------- template.odt | Bin 8822 -> 8937 bytes 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/redmine_reporter/formatter_odt.py b/redmine_reporter/formatter_odt.py index 95205db..8ad9a60 100644 --- a/redmine_reporter/formatter_odt.py +++ b/redmine_reporter/formatter_odt.py @@ -1,3 +1,4 @@ +import os from typing import List, Tuple from redminelib.resources import Issue from odf.opendocument import load @@ -5,7 +6,6 @@ from odf.text import P from odf.table import Table, TableColumn, TableRow, TableCell from .formatter import get_version, hours_to_human, STATUS_TRANSLATION -import os def format_odt(issue_hours: List[Tuple[Issue, float]]) -> "OpenDocument": @@ -21,7 +21,7 @@ def format_odt(issue_hours: List[Tuple[Issue, float]]) -> "OpenDocument": header_paragraph = P(stylename=para_style_name, text=header_text) doc.text.addElement(header_paragraph) - # Группировка: project → version → [(issue, hours, status_ru)] + # Группировка: project - version - [(issue, hours, status_ru)] projects = {} for issue, hours in issue_hours: project = str(issue.project) @@ -35,7 +35,7 @@ def format_odt(issue_hours: List[Tuple[Issue, float]]) -> "OpenDocument": projects[project][version] = [] projects[project][version].append((issue, hours, status_ru)) - # Создание таблицы + # Создаём таблицу table = Table(name="Report") for _ in range(5): table.addElement(TableColumn()) @@ -50,7 +50,7 @@ def format_odt(issue_hours: List[Tuple[Issue, float]]) -> "OpenDocument": header_row.addElement(cell) table.addElement(header_row) - # Данные: двухуровневая группировка + # Данные с двухуровневой группировкой и объединением ячеек for project, versions in projects.items(): total_project_rows = sum(len(rows) for rows in versions.values()) first_version_in_project = True @@ -62,7 +62,7 @@ def format_odt(issue_hours: List[Tuple[Issue, float]]) -> "OpenDocument": for issue, hours, status_ru in rows: row = TableRow() - # Ячейка "Проект" — только в первой строке всего проекта + # Ячейка "Проект" - только в первой строке всего проекта if first_version_in_project and first_row_in_version: cell_project = TableCell() cell_project.setAttribute("numberrowsspanned", str(total_project_rows)) @@ -70,7 +70,7 @@ def format_odt(issue_hours: List[Tuple[Issue, float]]) -> "OpenDocument": cell_project.addElement(p) row.addElement(cell_project) - # Ячейка "Версия" — только в первой строке каждой версии + # Ячейка "Версия" - только в первой строке каждой версии if first_row_in_version: cell_version = TableCell() cell_version.setAttribute("numberrowsspanned", str(row_span_version)) @@ -79,7 +79,7 @@ def format_odt(issue_hours: List[Tuple[Issue, float]]) -> "OpenDocument": row.addElement(cell_version) first_row_in_version = False else: - # Пропускаем — уже объединена + # Пропускаем - уже объединена pass # Остальные колонки diff --git a/template.odt b/template.odt index 44af317424181f0858e825c0141653c325a04549..214534e3330e02258b4c0467fd6362de2e694282 100644 GIT binary patch delta 6601 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 J8{MP%{{U=lKN$c3 delta 6499 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 wALqaFo>726mTz1