.. _le_stampe/stampe_genropy/stampe_risorsa/esempi_stampa/stampa_griglia_3: Stampa griglia 3: Comuni ======================== Supponiamo di voler stampare un elenco di record sulla base di una **query con delle condizioni** specifiche, considerando però solo i **"migliori" 100** risultati. In quest'esempio vedremo come definire la risorsa di stampa relativa ai **Dati dei Comuni italiani**, **filtrati per regione**. La stampa verrà lanciata dalla tabella *Comune* del package *GLBL* di `Sandbox `_. In particolare, questo esempio ci permetterà di vedere come utilizzare il metodo ``calcRowHeight`` per calcolare l'altezza variabile delle righe e come definire una ``gridstruct`` che faccia uso di ``sqlcolumn`` e ``columnset``, nonché l'utilizzo di ``limit`` e ``order_by`` nel nostro ``gridQueryParameters`` Definizione della print action ------------------------------ Per prima cosa andiamo a definire la :ref:`risorsa print` che chiamiamo *stampa_comuni.py* all'interno della cartella ``resources/tables/_packages/glbl/prodotto/print``, esattamente come abbiamo fatto nella :ref:`Stampa con griglia 1: Fatturato per esercizio` . Richiederemo come parametro solo la *Regione*. Si noti che in questo caso stiamo effettuando un `Override di un package built-in di Genropy `_, per questo motivo abbiamo ipotizzato di inserire la risorsa in un nostro package, modificando però il percorso della cartella come specificato. Non essendoci particolari variazioni sui parametri richiesti per la stampa rimandiamo al caso precedente per una trattazione più completa. Definizione della risorsa html_res ---------------------------------- Passiamo a questo punto alla definizione della :ref:`risorsa html_res` che chiamiamo *dati_comuni.py* all'interno della cartella ``resources/tables/_packages_glbl/comune/html_res``. Rimandiamo alla :ref:`Stampa con griglia 1: Fatturato per esercizio` per la trattazione della definizione dei parametri della classe *Main*, dei metodi ``defineCustomStyles``, ``docHeader``, ``docFooter`` e ``outputDocName``, che non variano anche in questo caso in modo significativo. Considerato l'elevato numero di colonne e lo spazio ridotto, nel *Main* specifichiamo invece ``page_orientation='H'``, che imposterà l'orientamento della stampa a *orizzontale*. Sempre nella classe *Main* definiamo anche ``grid_row_height = 5``, che indicherà una generica altezza di riga di riferimento che poi andremo a modificare caso per caso con il metodo ``calcRowHeight``. Infine, utilizziamo una totalizzazione per pagina con ``totalize_mode='page'``:: class Main(TableScriptToHtml): row_table = 'glbl.comune' page_width = 200 page_height = 297 page_orientation = 'H' doc_header_height = 20 doc_footer_height = 0 grid_header_height = 5 grid_row_height = 5 totalize_footer=True totalize_mode='page' Tramite il metodo ``gridQueryParameters`` specifichiamo poi come condizione l'appartenenza alla *Regione*, limitando il numero di risultati a 100 e ordinandoli per popolazione decrescente:: def gridQueryParameters(self): return dict(condition='@sigla_provincia.regione=:regione', condition_regione=self.parameter('regione'), order_by='$popolazione_residente DESC', limit=100) Si noti che con ``order_by='$popolazione_residente DESC'`` specifichiamo la natura *decrescente* sulla base della quale ordinare i risultati della ricerca, mentre con ``limit=100`` prendiamo di questa selezione solo i primi 100 risultati. È probabile però che avendo tante colonne e uno spazio ridotto alcuni comuni con nome particolarmente lungo o province con nomi particolarmente lunghi vengano troncate o presentino comunque problemi di visualizzazione. Ecco che ci viene in aiuto il metodo :ref:`calcRowHeight` , che prenderà il valore standard di ``grid_row_height`` che abbiamo inserito nel *Main* e lo modificherà sulla base del "contenuto" (in termini di numero di caratteri) della specifica riga:: def calcRowHeight(self): nome_offset = 22 n_rows_nome_comune = len(self.rowField('denominazione'))//nome_offset + 1 n_rows_nome_provincia = len(self.rowField('_sigla_provincia_nome'))//nome_offset + 1 n_rows = max(n_rows_nome_comune, n_rows_nome_provincia) height = (self.grid_row_height * n_rows) return height Il metodo ritorna quindi un'altezza dopo aver rapportato la lunghezza in termini di numero di caratteri del campo *denominazione* o *@sigla_provincia.nome* a un valore "offset" che impostiamo noi all'interno del metodo. Si noti che questa procedura non è obbligatoria, ma è quella che dal punto di vista pratico ha maggiori probabilità di funzionare nella molteplicità dei casi possibili: è possibile utilizzare anche altre procedure, a patto che venga sempre restituita un'altezza come risultato finale. Nel metodo ``gridStruct``, infine, utilizziamo :ref:`sqlcolumn e columnset` :: def gridStruct(self,struct): r = struct.view().rows() r.fieldcell('denominazione', mm_width=0, white_space='pre-line') com = r.columnset('com', name='DATI COMUNE', background='lightblue', color='white', font_size='14px', font_weight='bold') com.fieldcell('@localita.codice_istat', mm_width=15, name='Codice') com.fieldcell('@localita.prefisso_tel', mm_width=15, name='Pref.Tel.') com.fieldcell('@localita.cap', mm_width=14) ... prov = r.columnset('prov', name='DATI PROVINCIA', background='lightgreen', color='white', font_size='14px', font_weight='bold') prov.fieldcell('sigla_provincia', mm_width=12, name='Sigla') prov.fieldcell('@sigla_provincia.nome', mm_width=24, white_space='pre-line') prov.fieldcell('@sigla_provincia.codice_istat', mm_width=15, name='Codice') ... incid = r.columnset('incid', name='INCIDENZA', background='lightcoral', color='white', font_size='14px', font_weight='bold') incid.cell('superficie_perc', sqlcolumn="$superficie/@sigla_provincia.tot_superficie*100 AS superficie_perc", format='#,###.00', mm_width=15, name='Sup.%', content_class='aligned_right') incid.cell('popolazione_perc', sqlcolumn="$popolazione_residente/@sigla_provincia.numero_abitanti*100 AS popolazione_perc", format='#,###.00', mm_width=15, name='Pop.%', content_class='aligned_right') Si noti che l'utilizzo della ``sqlcolumn`` è in questo caso assolutamente alternativo a una qualsiasi ``formulaColumn``. La discriminante di scelta tra l'una e l'altra è esclusivamente l'utilità o meno al di fuori della specifica stampa: se la colonna calcolata può essere utile anche al di fuori della stampa allora si consiglia l'utilizzo della *formulaColumn*, se invece, come in questo caso, stiamo effettuando un `override di un package built-in di Genropy `_, ai soli scopi di questa stampa, e non abbiamo intenzione di modificare il model, allora è consigliato l'utilizzo della *sqlcolumn* .. raw:: html
Puoi scaricare i file di stampa qui di seguito e scompattare il file zip direttamente in ``fatt/resources/tables`` di `Sandbox `_. .. raw:: html
**Allegati:** - `_packages `_ - `dati-comuni_lom `_