import csv from django.contrib.auth.decorators import login_required import io from django.shortcuts import render from django.http import HttpResponse from .forms import DossardForm from reportlab.pdfgen import canvas from reportlab.lib.pagesizes import A4 from reportlab.lib.units import mm import qrcode from PIL import Image from django.core.files.storage import default_storage def generate_dossards_pdf(data, rows, cols): buffer = io.BytesIO() c = canvas.Canvas(buffer, pagesize=A4) width, height = A4 margin = 10 * mm label_w = (width - 2 * margin) / cols label_h = (height - 2 * margin) / rows x0, y0 = margin, height - margin - label_h qr_scale = 0.8 # 80% de la zone pour le QR code for idx, (nom, classe) in enumerate(data): col = idx % cols row = (idx // cols) % rows page = idx // (rows * cols) if idx > 0 and row == 0 and col == 0: c.showPage() x = x0 + col * label_w y = y0 - row * label_h # Dessiner le rectangle de la zone d'étiquette c.setLineWidth(3) c.setStrokeColorRGB(0, 0, 0) c.rect(x, y, label_w, label_h) # Générer QR code qr = qrcode.make(f"{nom};{classe}") qr_img = io.BytesIO() qr.save(qr_img, format='PNG') qr_img.seek(0) qr_pil = Image.open(qr_img) # Calculer la taille maximale du QR code (carré) dans la zone qr_size = min(label_w, label_h) * qr_scale qr_x = x + (label_w - qr_size) / 2 qr_y = y + (label_h - qr_size) / 2 c.drawInlineImage(qr_pil, qr_x, qr_y, qr_size, qr_size) # Afficher le nom et la classe sous le QR code c.setFont("Helvetica-Bold", 12) c.drawCentredString(x + label_w/2, qr_y - 10, nom) c.setFont("Helvetica", 10) c.drawCentredString(x + label_w/2, qr_y - 24, classe) c.save() buffer.seek(0) return buffer @login_required def dossards_view(request): error = None progress = None pdf_url = None if request.method == 'POST': form = DossardForm(request.POST, request.FILES) if form.is_valid(): csv_file = form.cleaned_data['csv_file'] rows = form.cleaned_data['rows'] cols = form.cleaned_data['cols'] try: data = [] for line in csv_file.read().decode('utf-8').splitlines(): if line.count(';') == 1: nom, classe = line.split(';') data.append((nom.strip(), classe.strip())) total = len(data) progress = f"Génération des dossards : 0/{total}..." buffer = generate_dossards_pdf(data, rows, cols) response = HttpResponse(buffer, content_type='application/pdf') response['Content-Disposition'] = f'attachment; filename="dossards_{rows}x{cols}.pdf"' return response except Exception as e: error = str(e) else: error = "Formulaire invalide." else: form = DossardForm() return render(request, 'dossards.html', { 'form': form, 'error': error, 'progress': progress, 'pdf_url': pdf_url })