152 lines
4.6 KiB
Python
152 lines
4.6 KiB
Python
import qrcode
|
|
from reportlab.lib.pagesizes import A4, landscape
|
|
from reportlab.lib.units import cm
|
|
from reportlab.lib.utils import ImageReader
|
|
from reportlab.pdfgen import canvas
|
|
from PIL import Image
|
|
import io
|
|
import os
|
|
|
|
# --- CONFIGURAZIONE ---
|
|
partecipanti = [
|
|
# {"id": "ABC123", "nome": "Mario Rossi Mrio Rossi Mario R", "azienda": "ItDevCon Srl"},
|
|
# {"id": "f6d8a77b7348f111", "nome": "Pietro Angelo Polito", "azienda": "Tecnofarma Srl"},
|
|
# {"id": "f0d8a77b7348f111", "nome": "Helena Giliberti", "azienda": ""},
|
|
# {"id": "f3d8a77b7348f111", "nome": "Simone Ercolani", "azienda": "Itaca"},
|
|
# {"id": "f2d8a77b7348f111", "nome": "Emanuele Malvatani", "azienda": "Itaca"},
|
|
# {"id": "f1d8a77b7348f111", "nome": "Lorenzo Maria Soricetti", "azienda": "Itaca"},
|
|
# {"id": "f4d8a77b7348f111", "nome": "Luca Malvatani", "azienda": "Itaca"},
|
|
{"id": "f5d8a77b7348f111", "nome": "Alessio Cimadamore", "azienda": "Itaca"},
|
|
# Aggiungi quanti partecipanti vuoi
|
|
]
|
|
|
|
base_url = "https://live.itdevcon.it/web/vote/"
|
|
|
|
output_pdf = "badge_qr.pdf"
|
|
|
|
# Dimensioni singolo badge (cm)
|
|
badge_w = 9 * cm
|
|
badge_h = 5 * cm
|
|
|
|
# Margini pagina A4 landscape
|
|
margin_x = 1.0 * cm
|
|
margin_y = 1.5 * cm
|
|
|
|
# Layout griglia su A4 landscape
|
|
rows_per_page = 2
|
|
cols_per_page = 3
|
|
|
|
# Font
|
|
font_name = "Helvetica-Bold"
|
|
font_size = 18
|
|
font_azienda = "Helvetica"
|
|
font_size_azienda = 12
|
|
|
|
# QR code
|
|
qr_width = 3.2 * cm # larghezza/altezza del QR nel PDF
|
|
|
|
# Colore branding
|
|
color_brand = "#040073"
|
|
color_brand_light = "#4A6DAD"
|
|
|
|
|
|
def create_qr_image(data, size=200):
|
|
"""Genera un'immagine QR code in memoria come BytesIO PNG."""
|
|
qr = qrcode.QRCode(
|
|
version=1,
|
|
error_correction=qrcode.constants.ERROR_CORRECT_M,
|
|
box_size=10,
|
|
border=1,
|
|
)
|
|
qr.add_data(data)
|
|
qr.make(fit=True)
|
|
img = qr.make_image(fill_color=color_brand, back_color="white")
|
|
img = img.convert("RGB")
|
|
img = img.resize((size, size), Image.LANCZOS)
|
|
img_bytes = io.BytesIO()
|
|
img.save(img_bytes, format="PNG")
|
|
img_bytes.seek(0)
|
|
return img_bytes
|
|
|
|
|
|
def draw_badge(c, x, y, id_partecipante, nome, azienda):
|
|
"""Disegna un singolo badge 9x5 cm con angolo in basso a sinistra a (x, y)."""
|
|
nome = nome[:26]
|
|
azienda = azienda[:26]
|
|
link = f"{base_url}{id_partecipante}"
|
|
|
|
# Angoli per facilitare il ritaglio (L di 0.5 cm per angolo)
|
|
c.setStrokeColorRGB(0, 0, 0)
|
|
c.setLineWidth(0.5)
|
|
corner = 0.5 * cm
|
|
|
|
# Angolo basso-sinistra
|
|
c.line(x, y, x + corner, y)
|
|
c.line(x, y, x, y + corner)
|
|
|
|
# Angolo basso-destra
|
|
c.line(x + badge_w - corner, y, x + badge_w, y)
|
|
c.line(x + badge_w, y, x + badge_w, y + corner)
|
|
|
|
# Angolo alto-sinistra
|
|
c.line(x, y + badge_h - corner, x, y + badge_h)
|
|
c.line(x, y + badge_h, x + corner, y + badge_h)
|
|
|
|
# Angolo alto-destra
|
|
c.line(x + badge_w - corner, y + badge_h, x + badge_w, y + badge_h)
|
|
c.line(x + badge_w, y + badge_h - corner, x + badge_w, y + badge_h)
|
|
|
|
# Nome centrato nella parte superiore
|
|
c.setFillColor(color_brand)
|
|
c.setFont(font_name, font_size)
|
|
text_width = c.stringWidth(nome, font_name, font_size)
|
|
text_x = x + (badge_w - text_width) / 2
|
|
text_y = y + badge_h - 0.7 * cm
|
|
c.drawString(text_x, text_y, nome)
|
|
|
|
# Azienda centrata subito sotto il nome (font più fine)
|
|
c.setFillColor(color_brand_light)
|
|
c.setFont(font_azienda, font_size_azienda)
|
|
text_width = c.stringWidth(azienda, font_azienda, font_size_azienda)
|
|
text_x = x + (badge_w - text_width) / 2
|
|
text_y_azienda = text_y - 0.6 * cm
|
|
c.drawString(text_x, text_y_azienda, azienda)
|
|
|
|
# QR code centrato subito sotto l'azienda
|
|
qr_bytes = create_qr_image(link, size=200)
|
|
qr_img = ImageReader(qr_bytes)
|
|
qr_x = x + (badge_w - qr_width) / 2
|
|
qr_y = text_y_azienda - qr_width - 0.3 * cm
|
|
c.drawImage(qr_img, qr_x, qr_y, width=qr_width, height=qr_width)
|
|
|
|
|
|
def generate_pdf():
|
|
c = canvas.Canvas(output_pdf, pagesize=landscape(A4))
|
|
page_w, page_h = landscape(A4)
|
|
|
|
# Spazio fisso tra badge per facilitare il ritaglio
|
|
gap = 0.2 * cm
|
|
|
|
per_page = rows_per_page * cols_per_page
|
|
|
|
for idx, p in enumerate(partecipanti):
|
|
if idx > 0 and idx % per_page == 0:
|
|
c.showPage()
|
|
|
|
pos_in_page = idx % per_page
|
|
col = pos_in_page % cols_per_page
|
|
row = pos_in_page // cols_per_page
|
|
|
|
x = page_w - margin_x - badge_w - col * (badge_w + gap)
|
|
y = page_h - margin_y - (row + 1) * badge_h - row * gap
|
|
|
|
draw_badge(c, x, y, p["id"], p["nome"], p.get("azienda", ""))
|
|
|
|
c.save()
|
|
print(f"PDF generato: {os.path.abspath(output_pdf)}")
|
|
print(f"Totale badge: {len(partecipanti)}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
generate_pdf()
|