Fixed sheet formatting

This commit is contained in:
2025-11-18 14:52:05 +01:00
parent 231a3e9861
commit 71809d331f

View File

@@ -2,7 +2,7 @@ from django.http import HttpRequest, HttpResponse
from django.db.models.query import QuerySet from django.db.models.query import QuerySet
from openpyxl import Workbook from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill, Alignment from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
from openpyxl.utils import get_column_letter from openpyxl.utils import get_column_letter
from datetime import date, datetime from datetime import date, datetime
@@ -34,22 +34,33 @@ def export_selected(request: HttpRequest, queryset: QuerySet[WeekPreference]) ->
if not ws: if not ws:
raise Exception("Export: cannot select active workbook") raise Exception("Export: cannot select active workbook")
ws.title = f"Week Preferences" 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 # 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)] 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)]
headers = ["Week", "Student", "Course", *days, "Cell.", "Mail", "Notes"] headers = ["Week", "Student", "Course", *days, "Cell.", "Mail", "Notes"]
# Header fields positions # Header fields positions
week_index: int = headers.index("Week") + 1
student_index: int = headers.index("Student") + 1 student_index: int = headers.index("Student") + 1
course_index: int = headers.index("Course") + 1 course_index: int = headers.index("Course") + 1
cell_index: int = headers.index("Cell.") + 1 cell_index: int = headers.index("Cell.") + 1
mail_index: int = headers.index("Mail") + 1 mail_index: int = headers.index("Mail") + 1
note_index: int = headers.index("Notes") + 1
# Stile header # Stile header
header_fill = PatternFill("solid", fgColor="0e005c") header_fill = PatternFill("solid", fgColor="0e005c")
bold_white = Font(color="FFFFFF", bold=True) bold_white = Font(color="FFFFFF", bold=True)
bold_black = Font(color="000000", bold=True) bold_black = Font(color="000000", bold=True)
center = Alignment(horizontal="center", vertical="center") center = Alignment(horizontal="center", vertical="center", wrapText=True)
# Cell styles
border_thick: Side = Side(style='thick', color='000000')
border_bottom: Border = Border(bottom=border_thick)
border_all: Border = Border(bottom=border_thick, top=border_thick, left=border_thick, right=None)
# Scrittura header # Scrittura header
for col, h in enumerate(headers, start=1): for col, h in enumerate(headers, start=1):
@@ -58,7 +69,9 @@ def export_selected(request: HttpRequest, queryset: QuerySet[WeekPreference]) ->
cell.font = bold_white cell.font = bold_white
cell.alignment = center cell.alignment = center
### Start of Student Loop ###
# Fill worksheet with EVERY training and hb for every student # Fill worksheet with EVERY training and hb for every student
# Each of this iterations fills the table for a student
row: int = 2 row: int = 2
row_offset: int = 0 row_offset: int = 0
for i, q in enumerate(queryset.order_by("student__surname", "student__name", "student__course"), start=1): for i, q in enumerate(queryset.order_by("student__surname", "student__name", "student__course"), start=1):
@@ -111,7 +124,7 @@ def export_selected(request: HttpRequest, queryset: QuerySet[WeekPreference]) ->
hb_legs = HourBuildingLeg.objects.filter(hb_id = h.id) hb_legs = HourBuildingLeg.objects.filter(hb_id = h.id)
for hh in hb_legs: for hh in hb_legs:
hb_notes += f"{hh.departure} -> {hh.destination} [{hh.time}]\n" if not hh.stop else f"STOP at {hh.departure} [{hh.time}]\n" hb_notes += f"{hh.departure} -> {hh.destination} [{hh.time}]\n" if not hh.stop else f"STOP at {hh.departure} [{hh.time}]\n"
hb_notes.strip('\r') hb_notes.strip('\n')
hb_data.append([str(q.week), *student_data, *hb_days, str(q.student.phone), q.student.email, hb_notes]) hb_data.append([str(q.week), *student_data, *hb_days, str(q.student.phone), q.student.email, hb_notes])
# Build rows for table # Build rows for table
@@ -126,6 +139,7 @@ def export_selected(request: HttpRequest, queryset: QuerySet[WeekPreference]) ->
cell.font = bold_black cell.font = bold_black
# Format Course Column # Format Course Column
if j == course_index and q.student.course: if j == course_index and q.student.course:
cell.font = bold_black
cell.fill = PatternFill("solid", fgColor=str(q.student.course.color).lstrip('#').lower()) cell.fill = PatternFill("solid", fgColor=str(q.student.course.color).lstrip('#').lower())
prev_cell_val: str = r[0] prev_cell_val: str = r[0]
@@ -149,7 +163,12 @@ def export_selected(request: HttpRequest, queryset: QuerySet[WeekPreference]) ->
# End week preferences for this student # End week preferences for this student
student_end: int = row + row_offset -1 student_end: int = row + row_offset -1
# Merge Name
# Merge Week, thick border
# ws.cell(row=student_start, column=week_index).border = border_all
# ws.merge_cells(start_row=student_start, end_row=student_end, start_column=week_index, end_column=week_index)
# Merge Name, thick border
ws.cell(row=student_start, column=student_index).border = border_all
ws.merge_cells(start_row=student_start, end_row=student_end, start_column=student_index, end_column=student_index) ws.merge_cells(start_row=student_start, end_row=student_end, start_column=student_index, end_column=student_index)
# Merge Course # Merge Course
ws.merge_cells(start_row=student_start, end_row=student_end, start_column=course_index, end_column=course_index) ws.merge_cells(start_row=student_start, end_row=student_end, start_column=course_index, end_column=course_index)
@@ -158,15 +177,22 @@ def export_selected(request: HttpRequest, queryset: QuerySet[WeekPreference]) ->
# Merge Mail # Merge Mail
ws.merge_cells(start_row=student_start, end_row=student_end, start_column=mail_index, end_column=mail_index) ws.merge_cells(start_row=student_start, end_row=student_end, start_column=mail_index, end_column=mail_index)
# Add thick border to the last cell row of this student
for i in range(course_index, len(all_data[0])+1):
ws.cell(row=student_end, column=i).border = border_bottom
# Keep the largest column # Keep the largest column
for column_cells in ws.columns: for column_cells in ws.columns:
length: int = max(len(str(cell.value)) for cell in column_cells) length: int = max(len(str(cell.value)) for cell in column_cells)
col_letter: str = "A" col_letter: str = "A"
if column_cells[0].column: if column_cells[0].column:
get_column_letter(column_cells[0].column) col_letter = get_column_letter(column_cells[0].column)
ws.column_dimensions[col_letter].width = length ws.column_dimensions[col_letter].width = length + 2
### End of Student Loop ###
# Save document in HttpResponse
wb.save(response) # Save document in HttpResponse
wb.save(response)
return response return response