From 46e6749fd5bb7d89459aef4f719ca7a331c02d96 Mon Sep 17 00:00:00 2001 From: Emanuele Date: Wed, 10 Dec 2025 11:05:22 +0100 Subject: [PATCH] improved xlsx formatting --- cntmanage/flightslot/actions/exportweek.py | 41 +++++++++++++++++----- cntmanage/flightslot/actions/send_email.py | 2 +- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/cntmanage/flightslot/actions/exportweek.py b/cntmanage/flightslot/actions/exportweek.py index c4c464e..11d8876 100644 --- a/cntmanage/flightslot/actions/exportweek.py +++ b/cntmanage/flightslot/actions/exportweek.py @@ -4,6 +4,7 @@ from django.db.models.query import QuerySet from openpyxl import Workbook from openpyxl.styles import Font, PatternFill, Alignment, Border, Side from openpyxl.utils import get_column_letter +from openpyxl.worksheet.page import PageMargins from ..models.courses import CourseTypes from ..models.missions import Training @@ -32,12 +33,15 @@ def export_selected(request: HttpRequest, queryset: QuerySet[WeekPreference]) -> raise Exception("Empty queryset") # Init Variables - year = date.today().year + today = date.today() + year = today.year + month = today.month + day = today.day week = queryset.first().week if queryset.first() else date.today().isocalendar().week weeks = queryset.order_by("week").distinct("week").all() # Prepare export filename and http content - filename = f"{year}_week{'+'.join([str(w.week) for w in weeks])}_export.xlsx" + filename = f"{year}{month}{day}_week_{'+'.join([str(w.week) for w in weeks])}_export.xlsx" response = HttpResponse(content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') response['Content-Disposition'] = f'attachment; filename="{filename}"' @@ -47,10 +51,6 @@ def export_selected(request: HttpRequest, queryset: QuerySet[WeekPreference]) -> if not ws: raise Exception("Export: cannot select active workbook") ws.title = f"Week Preferences" - ws.page_setup.orientation = ws.ORIENTATION_LANDSCAPE - ws.page_setup.paperSize = ws.PAPERSIZE_A3 - ws.page_setup.fitToHeight = 0 - ws.page_setup.fitToWidth = 1 # Header titles days = [f"{datetime.strptime(f"{year} {week} {x}", "%G %V %u").strftime("%A")} {datetime.strptime(f"{year} {week} {x}", "%G %V %u").day}" for x in range(1,8)] @@ -81,11 +81,19 @@ def export_selected(request: HttpRequest, queryset: QuerySet[WeekPreference]) -> border_all: Border = Border(bottom=border_thick, top=border_thick, left=border_thick, right=None) # Scrittura header + head_size: int = len(headers) for col, h in enumerate(headers, start=1): cell = ws.cell(row=1, column=col, value=h) cell.fill = header_fill cell.font = bold_white cell.alignment = center + match col: + case int(1): + cell.border = Border(top=border_thick, bottom=border_thick, left=border_thick) + case int(head_size): + cell.border = Border(top=border_thick, bottom=border_thick, right=border_thick) + case _: + cell.border = Border(top=border_thick, bottom=border_thick) ### Start of Student Loop ### # Fill worksheet with EVERY training and hb for every student @@ -181,6 +189,7 @@ def export_selected(request: HttpRequest, queryset: QuerySet[WeekPreference]) -> if c > course_index and c <= note_index: if len(cell_content): cell.fill = PatternFill('solid', fgColor=PALETTE[ri % len(PALETTE)].lstrip("#").lower()) + if MERGE: prev_cell_val: str = row_content[0] merge_start: bool = False @@ -225,9 +234,9 @@ def export_selected(request: HttpRequest, queryset: QuerySet[WeekPreference]) -> ws.merge_cells(start_row=student_start, end_row=student_end, start_column=mail_index, end_column=mail_index) # Keep the largest column - max_len: List[int] = [] - col_letter: str = "A" for column_cells in ws.columns: + col_letter: str = "A" + max_len: List[int] = [] for cell in column_cells: cell_lines = str(cell.value).splitlines() if len(cell_lines) == 0: @@ -236,9 +245,23 @@ def export_selected(request: HttpRequest, queryset: QuerySet[WeekPreference]) -> length: int = max(max_len) if column_cells[0].column: col_letter = get_column_letter(column_cells[0].column) - ws.column_dimensions[col_letter].width = length + 2 + ws.column_dimensions[col_letter].width = min(length + 2, 35) ### End of Student Loop ### + # Set paper size and format + ws.page_setup.orientation = ws.ORIENTATION_LANDSCAPE + ws.page_setup.paperSize = ws.PAPERSIZE_A3 + ws.page_setup.fitToHeight = 0 + ws.page_setup.fitToWidth = 1 + ws.print_options.horizontalCentered = True + ws.page_setup.fitToPage = True + ws.page_margins = PageMargins( + left=0.25, right=0.25, + top=0.75, bottom=0.75, + header=0.3, footer=0.3 + ) + ws.print_area = ws.calculate_dimension() + # Save document in HttpResponse wb.save(response) diff --git a/cntmanage/flightslot/actions/send_email.py b/cntmanage/flightslot/actions/send_email.py index b5569b9..5e71105 100644 --- a/cntmanage/flightslot/actions/send_email.py +++ b/cntmanage/flightslot/actions/send_email.py @@ -70,4 +70,4 @@ def send_mail_password(request: HttpRequest, queryset: QuerySet[Student]) -> Non else: messages.success(request=request, message=f"Successfully sent {len(mails)} messages") - return \ No newline at end of file + return