|
|
|
@ -134,7 +134,7 @@ def export_csv(request, course_id): |
|
|
|
response = HttpResponse(content_type='text/csv') |
|
|
|
response = HttpResponse(content_type='text/csv') |
|
|
|
response['Content-Disposition'] = f'attachment; filename="course_{course_id}_resultats.csv"' |
|
|
|
response['Content-Disposition'] = f'attachment; filename="course_{course_id}_resultats.csv"' |
|
|
|
writer = csv.writer(response) |
|
|
|
writer = csv.writer(response) |
|
|
|
writer.writerow(['Rang', 'Nom', 'Prénom', 'Classe', 'Temps']) |
|
|
|
writer.writerow(['Rang', 'Nom', 'Classe', 'Temps']) |
|
|
|
|
|
|
|
|
|
|
|
import json |
|
|
|
import json |
|
|
|
rows_json = request.POST.get('rows') |
|
|
|
rows_json = request.POST.get('rows') |
|
|
|
@ -164,22 +164,18 @@ def export_pdf(request, course_id): |
|
|
|
p = canvas.Canvas(response, pagesize=A4) |
|
|
|
p = canvas.Canvas(response, pagesize=A4) |
|
|
|
width, height = A4 |
|
|
|
width, height = A4 |
|
|
|
|
|
|
|
|
|
|
|
# Choisit l'étiquette de la première colonne selon le type de course |
|
|
|
|
|
|
|
first_col_label = 'Tour' if course.type == 'multi' else 'Rang' |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# En-tête du document |
|
|
|
# En-tête du document |
|
|
|
y = height - 50 |
|
|
|
y = height - 50 |
|
|
|
p.setFont("Helvetica-Bold", 16) |
|
|
|
p.setFont("Helvetica-Bold", 16) |
|
|
|
p.drawString(50, y, f"Résultats - {course.nom} ({course.date})") |
|
|
|
p.drawString(50, y, f"Résultats - {course.nom} ({course.date})") |
|
|
|
|
|
|
|
|
|
|
|
# En-tête du tableau (colonnes: premier, Nom, Prénom, Classe, Temps) |
|
|
|
# En-tête du tableau |
|
|
|
y -= 40 |
|
|
|
y -= 40 |
|
|
|
p.setFont("Helvetica", 12) |
|
|
|
p.setFont("Helvetica", 12) |
|
|
|
p.drawString(50, y, first_col_label) |
|
|
|
p.drawString(50, y, "Rang") |
|
|
|
p.drawString(100, y, "Nom") |
|
|
|
p.drawString(100, y, "Nom") |
|
|
|
p.drawString(220, y, "Prénom") |
|
|
|
p.drawString(300, y, "Classe") |
|
|
|
p.drawString(340, y, "Classe") |
|
|
|
p.drawString(400, y, "Temps") |
|
|
|
p.drawString(460, y, "Temps") |
|
|
|
|
|
|
|
y -= 20 |
|
|
|
y -= 20 |
|
|
|
|
|
|
|
|
|
|
|
# Contenu : soit les lignes filtrées envoyées en POST, soit toutes les arrivées en base |
|
|
|
# Contenu : soit les lignes filtrées envoyées en POST, soit toutes les arrivées en base |
|
|
|
@ -189,24 +185,10 @@ def export_pdf(request, course_id): |
|
|
|
try: |
|
|
|
try: |
|
|
|
rows = json.loads(rows_json) |
|
|
|
rows = json.loads(rows_json) |
|
|
|
for row in rows: |
|
|
|
for row in rows: |
|
|
|
# If we receive a group marker row (injected client-side when grouping), render it as a header |
|
|
|
p.drawString(50, y, str(row[0])) |
|
|
|
if isinstance(row, list) and len(row) > 0 and row[0] == '__GROUP__': |
|
|
|
p.drawString(100, y, str(row[1])) |
|
|
|
# Render group header spanning the table width |
|
|
|
p.drawString(300, y, str(row[2])) |
|
|
|
p.setFont("Helvetica-Bold", 12) |
|
|
|
p.drawString(400, y, str(row[3])) |
|
|
|
p.drawString(50, y, str(row[1])) |
|
|
|
|
|
|
|
p.setFont("Helvetica", 12) |
|
|
|
|
|
|
|
else: |
|
|
|
|
|
|
|
# Standard row: expected format [first, nom, prenom, classe, temps] |
|
|
|
|
|
|
|
first = row[0] if len(row) > 0 else '' |
|
|
|
|
|
|
|
nom = row[1] if len(row) > 1 else '' |
|
|
|
|
|
|
|
prenom = row[2] if len(row) > 2 else '' |
|
|
|
|
|
|
|
classe = row[3] if len(row) > 3 else '' |
|
|
|
|
|
|
|
temps_val = row[4] if len(row) > 4 else '' |
|
|
|
|
|
|
|
p.drawString(50, y, str(first)) |
|
|
|
|
|
|
|
p.drawString(100, y, str(nom)) |
|
|
|
|
|
|
|
p.drawString(220, y, str(prenom)) |
|
|
|
|
|
|
|
p.drawString(340, y, str(classe)) |
|
|
|
|
|
|
|
p.drawString(460, y, str(temps_val)) |
|
|
|
|
|
|
|
y -= 20 |
|
|
|
y -= 20 |
|
|
|
# Nouvelle page si nécessaire |
|
|
|
# Nouvelle page si nécessaire |
|
|
|
if y < 50: |
|
|
|
if y < 50: |
|
|
|
@ -217,13 +199,10 @@ def export_pdf(request, course_id): |
|
|
|
else: |
|
|
|
else: |
|
|
|
arrivees = course.arrivees.select_related('coureur').order_by('rang') |
|
|
|
arrivees = course.arrivees.select_related('coureur').order_by('rang') |
|
|
|
for a in arrivees: |
|
|
|
for a in arrivees: |
|
|
|
# Affiche le numéro de tour pour les courses multi, sinon le rang |
|
|
|
p.drawString(50, y, str(a.rang)) |
|
|
|
first_value = a.tour if course.type == 'multi' else a.rang |
|
|
|
|
|
|
|
p.drawString(50, y, str(first_value)) |
|
|
|
|
|
|
|
p.drawString(100, y, a.coureur.nom) |
|
|
|
p.drawString(100, y, a.coureur.nom) |
|
|
|
p.drawString(220, y, a.coureur.prenom) |
|
|
|
p.drawString(300, y, a.coureur.classe) |
|
|
|
p.drawString(340, y, a.coureur.classe) |
|
|
|
p.drawString(400, y, str(a.temps)) |
|
|
|
p.drawString(460, y, str(a.temps)) |
|
|
|
|
|
|
|
y -= 20 |
|
|
|
y -= 20 |
|
|
|
# Nouvelle page si nécessaire |
|
|
|
# Nouvelle page si nécessaire |
|
|
|
if y < 50: |
|
|
|
if y < 50: |
|
|
|
|