Stampare da browser con applicazione PHP e MYSql

Scrivere una applicazione in PHP é abbastanza facile, è un linguaggio che ha molte funzioni già pronte, puoi fare quasi tutto senza scrivere nuove funzioni. Se utilizzi un database ha già predisposta l’interfaccia con MYSql e anche li devi solo usare le funzioni che ti mette a disposizione. Se devi stampare, beh, se devi stampare è un po’ più complicato.

Io ho scritto un’applicazione in PHP che memorizza di dati con MYSql e visualizza i risultati con delle tabelle, facile facile. Poi mi hanno chiesto di stampare queste tabelle e sono impazzito. Si, perchè il browser pensa a tutto e tu puoi fare ben poco, ma se non sei contento di come stampa allora devi trovare trucchetti di ogni tipo per adeguare la stampa alle esigenze.

Stessa applicazione?

Il primo dubbio che ho avuto è stato se utilizzare la stessa applicazione che visualizza i dati o scriverne una appositamente per la stampa. Considerando che i dati sono gli stessi, i cicli identici, cambia solo la formattazione e altri piccoli particolari ho optato per utilizzare la stessa applicazione.

Quindi ho aggiunto all’applicazione un tasto [Stampa] nel Form che conteneva i campi di filtraggio, l’ho definito come segue:

    echo '<input class="bottone_stampa" type="submit" name="stampa" value="Stampa" formtarget="_blank" >';

La classe bottone_stampa l’ho utilizzata per dare un colore diverso a questo pulsante, il formtarget=blank l’ho utilizzato per aprire una nuova pagina, su questa pagina mando i dati da stampare formattati per la stampa.

Come stampare in automatico

Quindi abbiamo detto che apro una pagina nuova, ci metto le tabelle e gli altri dati stampare senza nessun elemento attivo (bottoni o link ). Sarebbe carino se la stampa partisse in automatico, del resto ho cliccato su un bottone che dice [Stampa].

Si può fare, e anche facilmente, basta aggiungere queste righe in javascript come prime righe del body

echo '<body>';
echo ' <script type="text/javascript">';
echo '      window.onload = function() {         window.print();       }';
echo ' </script>';

Con queste semplici istruzioni gli diciamo che quando finisce il caricamento della pagina (onload) deve stampare la finestra. Facile facile abbiamo risolto.

Intestazione e piè di pagina

Ora arriva la parte che mi ha fatto penare di più. I browser stampano di loro iniziativa l’intestazione e i il piè di pagina, ogni browser lo fa a modo suo ma a parte il fatto che stampano in posizioni diverse tutti stampano il TITLE della pagina, l’indirizzo della pagina, il contatore di pagine e la data/ora di stampa.

Inizialmente ho pensato di disattivarli per gestire io le informazioni da stampare, li ho disattivati mettendo i margini top e botton a 0, più avanti vedremo come si settano. Bello, effettivamente sparivano ma la tabella occupava tutto il foglio ed era bruttissima da vedere una volta stampata, allora ho pensato che tanto i browser permettono di disattivare la stampa dell’intestazione/piè di pagina e quindi si potevano disattivare da li, poi se uno li riattivava erano fatti suoi.

Ma subito è sorto un altro problema, la stampa la gestisce completamente il browser e quindi io non ho elementi per mettere il numero di pagina e altre informazioni utili. Ho visto che il css prevede l’utilizzo di alcuni comandi per il numero pagina ma ho fatto decine di prove e non hanno mai avuto effetto nemmeno con la navigazione anonima.

Perchè la navigazione anonima? Se me lo chiedete non avete mai provato a modificare i css e vederne al volo i risultati. Quasi tutti i browser non ricaricano il css quando lo hanno già nella cash e quindi voi fate le modifiche e il browser le ignora. Come risolvere? Inizialmente avevo risolto chiamando il css seguito da ? e un altro valore casuale (solitamente time()) così essendo diverso veniva ricaricato ma non sempre funziona e allora ho risolto con la navigazione anonima, come se fosse la prima volta che vado su un sito.

Tornando al problema con i vari parametri della @page (la direttiva CSS che specifica le informazioni per la stampa) non ho risolto nulla, gli unici valori che mi prendeva in considerazione erano i margini. Comunque ho risolto, come?

Semplice, nel TITLE ci ho messo la descrizione della stampa, così veniva riportata su ogni foglio, numero di pagina e data di stampa sono informazioni utili restava solo il problema dell’url della pagina. Ho risolto con un comandino in javascript aggiunto un attimo prima del print:

echo '<body>';
echo ' <script type="text/javascript">';
echo '      window.onload = function() {
         history.replaceState(history.state, "", "../Report");
         window.print();

       }';
echo ' </script>';

Il comando history.replacestate modifica l’indirizzo che viene visualizzato in alto nel browser. Il fatto che veniva cambiato non mi importava in quanto la pagina era specifica per la stampa e quindi andava chiusa. Se comunque l’utente faceva refresh nella cartella report avevo messo un index.php che lo rimandava alla pagina di logon.

Così facendo invece di uscire una porcheria piena di barre e di valori dei parametri passati come GET e dei vari percorsi esce soltalto il nome sito/report o qualsiasi cosa vogliate scrivere li.

Questo il css che ho utilizzato per la stampa caricato al posto del normale CSS visto che da programma capisco se devo generare stampa o video.

/* @page{  margin: 0mm 3mm 15mm 3mm; @bottom-center {content: counter(page);} } */
body{ font-size: 10pt; margin-top: 10pt;margin-bottom: 10pt;}
.anagrafe {font-size: 14pt;}
.note {font-size: 10pt;text-align: center;}
.testata {font-size: 16pt;text-align: center;}
#logo {  width:40%; }
/* table {page-break-inside: avoid;}   per far iniziare una tabella a pagina nuova se non entra nella pagina corrente */
table {width:100%;}
table th, table td {border:1px solid #000;}
.funzioni { text-align: center; margin: 0; margin-bottom: 1px; font-size: 24px;width:100%;}
.div50 {  width: 55%;}
.cont {  display:flex; }
@page
{
    size: auto;   /* auto is the initial value */
    margin: 10mm 10mm 10mm 10mm;
}

Ho lasciato alcuni parametri usati nelle prove ma commentati e altre funzioni utili magari in futuro sempre commentate.

Ci vediamo alla prossima.

Maurizio

Lascia un commento