Generazione di Schede Tecniche: Creazione di PDF su Richiesta e in Batch
Questo articolo spiega come generiamo le schede tecniche dei prodotti in formato PDF, sia su richiesta (quando gli utenti le richiedono) che in batch (pre-generandole per i prodotti più popolari).
Il Problema: Creare Schede Tecniche dei Prodotti
Ogni prodotto necessita di una scheda tecnica PDF professionale con:
-
Nome e immagini del prodotto
-
Specifiche tecniche raggruppate per categoria
-
Brand aziendale e informazioni di contatto
-
Layout ottimizzato (pagina singola, colonne bilanciate)
Generare PDF ad ogni richiesta è lento (~2 secondi per PDF). Pre-generare tutti i 65.000 SKU spreca spazio di archiviazione e tempo.
La Soluzione: Approccio Ibrido
Utilizziamo due metodi di generazione:
Su richiesta: Genera il PDF quando l'utente lo richiede (la prima volta)
Batch: Pre-genera i PDF per i prodotti più popolari (ogni notte)
Generazione su Richiesta
Struttura URL
/ds/<sku>.pdf
/ds/<sku>
Entrambi gli URL generano lo stesso PDF.
Flusso della Richiesta
@web.route("/ds/<sku>.pdf")
def datasheet(sku: str):
# Valida SKU
# ... (dettagli implementativi omessi)
Processo di Generazione
Passo 1: Ottieni Dati del Prodotto
# Nome prodotto
name = expand_sku(sku)
# ... (dettagli implementativi omessi)
Passo 2: Bilanciamento Colonne
Le caratteristiche sono distribuite su 3 colonne per bilanciare il numero di righe:
# Calcola righe per gruppo di caratteristiche
all_groups = []
for heading, f_items in features.items():
# ... (dettagli implementativi omessi)
Passo 3: Calcola Altezze Immagini
# Altezza immagine principale (proporzionale alle proporzioni)
with Image.open(main_image_path) as img:
main_width, main_height = img.size
# ... (dettagli implementativi omessi)
Passo 4: Calcola Spaziatore
Spinge il piè di pagina in fondo alla pagina:
available_height = 25.0 # cm
content_height = total_image_height + text_height_cm
spacer_height = max(0, available_height - content_height)
Passo 5: Render HTML
html = render_template(
"datasheet.html",
sku=sku,
# ... (dettagli implementativi omessi)
Passo 6: Genera PDF
options = {
"page-size": "A4",
"enable-local-file-access": None,
"load-error-handling": "ignore",
"load-media-error-handling": "ignore",
"no-stop-slow-scripts": None
}
pdf_data = pdfkit.from_string(html, options=options)
Passo 7: Mantieni Solo la Prima Pagina
reader = PdfReader(BytesIO(pdf_data))
if len(reader.pages) > 1:
writer = PdfWriter()
writer.add_page(reader.pages[0])
output = BytesIO()
writer.write(output)
pdf_data = output.getvalue()
Prestazioni
Tempo di generazione: ~2 secondi per PDF
Caching: Nessun caching (sempre aggiornato)
Vantaggio: Sempre aggiornato con i dati più recenti del prodotto
Generazione in Batch
Scopo
Pre-generare PDF per i prodotti più popolari per ridurre il carico su richiesta.
Posizione Script
scripts/utils/generate_datasheets.py
Tracciamento Cambiamenti
Tracciamo le modifiche alle sezioni di productdb.json rilevanti per ogni SKU:
def get_sku_productdb_hash(sku: str) -> str:
"""Ottieni l'hash delle sezioni di productdb rilevanti per questo SKU."""
with open(PRODUCTDB_PATH, "r") as f:
# ... (dettagli implementativi omessi)
Priorità
Diamo priorità agli SKU in base alla frequenza di richiesta:
def load_popular_skus() -> List[str]:
"""Carica SKU popolari dai log di accesso."""
try:
# ... (dettagli implementativi omessi)
Strategia di Generazione
def batch_generate():
# Carica cache hash
hash_cache = load_hash_cache()
# ... (dettagli implementativi omessi)
Programmazione
La generazione batch viene eseguita ogni notte tramite cron:
0 2 * * * cd /home/ubuntu/manage && python scripts/utils/generate_datasheets.py
Archiviazione
Locale: /home/ubuntu/web-static/ds/<sku>.pdf
S3: s3://thinvent-web-static/ds/<sku>.pdf
CDN: Servito via CloudFront
Struttura del Template
Il template della scheda tecnica utilizza un layout a 3 colonne:
<div class="container">
<!-- Intestazione con logo e nome prodotto -->
<div class="header">
<img src="logo.png">
<h1>{{ name }}</h1>
</div>
<!-- Immagine principale -->
<img src="{{ images[0][1] }}" style="width: 9.5cm">
<!-- Miniature (fino a 4) -->
<div class="thumbnails">
{% for name, url in images[1:5] %}
<img src="{{ url }}" style="width: 4.5cm">
{% endfor %}
</div>
<!-- Caratteristiche in 3 colonne -->
<div class="features">
<div class="column">
{% for heading, items in features1 %}
<h3>{{ heading }}</h3>
{% for name, value in items.items() %}
<div><strong>{{ name }}:</strong> {{ value }}</div>
{% endfor %}
{% endfor %}
</div>
<div class="column">
<!-- features2 -->
</div>
<div class="column">
<!-- features3 -->
</div>
</div>
<!-- Spaziatore per spingere il piè di pagina in basso -->
<div style="height: {{ spacer_height }}cm"></div>
<!-- Piè di pagina con informazioni di contatto -->
<div class="footer">
<p>www.thinvent.in | sales@thinvent.in | +91-124-4343177</p>
</div>
</div>
Configurazione
Le costanti controllano il layout:
DATASHEET_COLUMN_COUNT = 3
DATASHEET_HEADING_LINE_WEIGHT = 2 # Righe per intestazione
DATASHEET_FEATURE_NAME_MAX_LEN = 30 # Caratteri prima del wrapping
DATASHEET_FEATURE_VALUE_CHARS_PER_LINE = 40 # Caratteri per riga
PDF_PAGE_SIZE = "A4"
Punti di Integrazione
Pagine Prodotto
Link alla scheda tecnica:
<a href="/ds/{{ sku }}.pdf" target="_blank">Scarica Scheda Tecnica</a>
Google Shopping
Schede tecniche collegate nel feed prodotto:
<g:product_detail>
<g:section_name>Scheda Tecnica</g:section_name>
<g:attribute_name>PDF</g:attribute_name>
<g:attribute_value>https://www.thinvent.in/ds/{{ sku }}.pdf</g:attribute_value>
</g:product_detail>
Campagne Email
Schede tecniche allegate alle email di preventivo.
Gestione Errori
SKU Non Valido
if not check_sku(sku):
abort(422, description="Prodotto non trovato.")
Fallimento Generazione
try:
pdf_data = generate_datasheet_pdf(sku)
if pdf_data is None:
abort(500, description="Generazione PDF fallita.")
except Exception as e:
logger.error(f"Generazione PDF fallita per {sku}: {e}")
abort(500, description="Generazione PDF fallita.")
Immagini Mancanti
try:
with Image.open(image_path) as img:
width, height = img.size
except Exception:
# Usa dimensioni predefinite
width, height = 800, 600
Riferimenti
Librerie
Articoli Correlati
-
Estrazione Caratteristiche - Ottenere specifiche prodotto
-
Generazione Contenuti AI - Descrizioni prodotto
-
Struttura SKU - Identificatori prodotto
Riepilogo
La generazione delle schede tecniche utilizza un approccio ibrido:
Su Richiesta:
-
✅ Genera quando l'utente richiede
-
✅ Sempre aggiornato
-
✅ Nessuno spreco di archiviazione
-
✅ ~2 secondi per PDF
Batch:
-
✅ Pre-genera prodotti popolari
-
✅ Traccia cambiamenti productdb
-
✅ Priorità per frequenza di richiesta
-
✅ Lavoro cron notturno
Processo:
-
✅ Ottieni dati prodotto (nome, immagini, caratteristiche, descrizione)
-
✅ Bilanciamento caratteristiche su 3 colonne
-
✅ Calcola altezze immagini
-
✅ Render template HTML
-
✅ Genera PDF con pdfkit
-
✅ Mantieni solo la prima pagina
Archiviazione:
-
✅ Locale:
/home/ubuntu/web-static/ds/ -
✅ S3:
s3://thinvent-web-static/ds/ -
✅ CDN: Distribuzione CloudFront
Questo approccio ibrido bilancia l'aggiornamento (su richiesta) con le prestazioni (pre-generazione batch).