Cell formatting OK, notes with hb details

This commit is contained in:
2025-11-17 19:24:51 +01:00
parent a91e0cd7bc
commit 231a3e9861
2 changed files with 40 additions and 25 deletions

View File

@@ -3,14 +3,15 @@ from django.db.models.query import QuerySet
from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill, Alignment
from openpyxl.utils import get_column_letter
from datetime import date, datetime, timedelta
from datetime import date, datetime
from typing import List
import calendar
from ..models.weekpref import WeekPreference
from ..models.missions import Training
from ..models.hourbuildings import HourBuilding
from ..models.hourbuildings import HourBuilding,HourBuildingLeg
def export_selected(request: HttpRequest, queryset: QuerySet[WeekPreference]) -> HttpResponse:
@@ -20,9 +21,10 @@ def export_selected(request: HttpRequest, queryset: QuerySet[WeekPreference]) ->
# Init Variables
year = date.today().year
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{week}_export.xlsx"
filename = f"{year}_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}"'
@@ -31,7 +33,7 @@ def export_selected(request: HttpRequest, queryset: QuerySet[WeekPreference]) ->
ws = wb.active
if not ws:
raise Exception("Export: cannot select active workbook")
ws.title = f"{year} Week {week} Preferences"
ws.title = f"Week Preferences"
# 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)]
@@ -56,11 +58,9 @@ def export_selected(request: HttpRequest, queryset: QuerySet[WeekPreference]) ->
cell.font = bold_white
cell.alignment = center
# Scrittura dati
# Fill worksheet with EVERY training and hb for every student
row: int = 2
row_offset: int = 0
# Fill worksheet with EVERY training and hb for every student
for i, q in enumerate(queryset.order_by("student__surname", "student__name", "student__course"), start=1):
student_data: List[str]
student_phone: str = q.student.phone if q.student.phone else ""
@@ -89,7 +89,7 @@ def export_selected(request: HttpRequest, queryset: QuerySet[WeekPreference]) ->
mission_name if t.sunday else ""
]
mission_notes = t.notes if t.notes else "--"
mission_data.append([str(week), *student_data, *mission_days, student_phone, student_email, mission_notes])
mission_data.append([str(q.week), *student_data, *mission_days, student_phone, student_email, mission_notes])
# Fill HourBuilding rows
hb_name: str
@@ -97,7 +97,7 @@ def export_selected(request: HttpRequest, queryset: QuerySet[WeekPreference]) ->
hb_notes: str
hb_data: List[List[str]] = []
for h in HourBuilding.objects.filter(weekpref = q.id):
hb_name = f"HB-{h.aircraft}"
hb_name = f"HB-{h.aircraft}\nVedi Note ->"
hb_days = [
hb_name if h.monday else "",
hb_name if h.tuesday else "",
@@ -107,18 +107,18 @@ def export_selected(request: HttpRequest, queryset: QuerySet[WeekPreference]) ->
hb_name if h.saturday else "",
hb_name if h.sunday else ""
]
hb_notes = h.notes if h.notes else "--"
hb_data.append([str(week), *student_data, *hb_days, str(q.student.phone), q.student.email, hb_notes])
hb_notes = f"{h.notes}\n----\n" if h.notes else ""
hb_legs = HourBuildingLeg.objects.filter(hb_id = h.id)
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.strip('\r')
hb_data.append([str(q.week), *student_data, *hb_days, str(q.student.phone), q.student.email, hb_notes])
# Build rows for table
all_data: List[List[str]] = mission_data + hb_data
student_start: int = row + row_offset
for r in mission_data + hb_data:
prev_cell_val: str | None = None
merge_start: bool = False
merge_col_start: int = 1
for r in all_data:
for j, c in enumerate(r, start=1):
if prev_cell_val is None:
prev_cell_val = c
cell = ws.cell(row = row + row_offset, column = j, value = c)
cell.alignment = center
# Format Student Name
@@ -127,21 +127,27 @@ def export_selected(request: HttpRequest, queryset: QuerySet[WeekPreference]) ->
# Format Course Column
if j == course_index and q.student.course:
cell.fill = PatternFill("solid", fgColor=str(q.student.course.color).lstrip('#').lower())
prev_cell_val: str = r[0]
merge_start: bool = False
merge_col_start: int = 1
for c, v in enumerate(r, start=1):
# Merge cells in the row
if c == prev_cell_val and not merge_start:
if v == prev_cell_val and not merge_start:
merge_start = True
merge_col_start = max(j-1, 1)
elif c != prev_cell_val and merge_start:
merge_col_start = c-1 # start merge from previous column
elif v != prev_cell_val and merge_start:
merge_start = False
ws.merge_cells(start_row=row+row_offset,
end_row=row+row_offset,
start_column=merge_col_start,
end_column=max(j-1,1))
end_row=row+row_offset,
start_column=max(merge_col_start,1),
end_column=max(c-1,1)) # end merge to previous column
prev_cell_val = v
# Incement row counter
row_offset += 1
# End f preferences for this student
# End week preferences for this student
student_end: int = row + row_offset -1
# Merge Name
ws.merge_cells(start_row=student_start, end_row=student_end, start_column=student_index, end_column=student_index)
@@ -152,6 +158,14 @@ def export_selected(request: HttpRequest, queryset: QuerySet[WeekPreference]) ->
# Merge Mail
ws.merge_cells(start_row=student_start, end_row=student_end, start_column=mail_index, end_column=mail_index)
# Keep the largest column
for column_cells in ws.columns:
length: int = max(len(str(cell.value)) for cell in column_cells)
col_letter: str = "A"
if column_cells[0].column:
get_column_letter(column_cells[0].column)
ws.column_dimensions[col_letter].width = length
# Save document in HttpResponse
wb.save(response)

1
techdb/static/password Normal file
View File

@@ -0,0 +1 @@
admin: CantorAdmin2k25