Hai mai avuto la necessità di visualizzare documenti PDF all’interno di pagine web? Se la risposta è sì allora non perderti questo articolo.

Chi sviluppa portali internet o intranet, soprattutto in ambito industriale, prima o poi si è posto il problema di come poter Visualizzare PDF con HTML5 in modo agevole all’interno di pagine internet.

Il problema principale è che i documenti PDF sono sempre stati visti e trattati come degli oggetti estranei alla pagina HTML. Per visualizzarli correttamente di solito o si scaricano e si aprono successivamente con un visualizzatore (ad es. Acrobar Reader), oppure si aprono in una finestra separata del browser in cui il browser stesso lo renderizza a pieno schermo.

Questi due metodi sono poco eleganti, perché costringono l’utente a interagire con una seconda finestra, e poi con una terza, e una quarta, e così via per ogni documento PDF che si vuole aprire. Immagina di dover consultare di continuo dei PDF ogni volta diversi. Saresti sommerso di finestre da chiudere. Inoltre l’utente viene costretto ad abbandonare la pagina di navigazione di partenza, in favore di quella che visualizza il PDF a pieno schermo.

Questo modo di aprire i PDF diventa ingestibile nel caso io abbia bisogno di visualizzarli all’interno di un Chiosco Multimediale.

Totem multimediale
Esempio di chiosco multimediale

L’obiettivo di partenza

In questo articolo voglio condividere con te la mia esperienza, sperando ti possa essere utile.

La mia esigenza specifica era di realizzare un Chiosco Multimediale Web con interfaccia touch per la ricerca e consultazione di disegni tecnici in formato PDF nei diversi reparti produttivi di una fabbrica.

Nel precedente articolo ho spiegato cosa sia un chiosco multimediale e come realizzare un chiosco web con Raspberry Pi 4.

In questo articolo voglio condividere con te la seconda parte del progetto spiegandoti come ho realizzato la parte software che visualizza i documenti PDF.

La libreria che fa la magia

Tutto il progetto si basa sulla libreria PDF.js che all’interno della pagina web riesce a caricare un documento e PDF e visualizzarlo in puro formato HTML5.

In sostanza PDF.js “smonta” il PDF e lo rimonta visualizzando oggetti nativi HTML5. Quello che viene visualizzato non è altro che HTML5 e non più un PDF. semplicemente magico!

Questa libreria è frutto di un progetto Open Source della “Mozilla Foundation” ed è liberamente scaricabile dal suo repository GitHub ufficiale e utilizzabile sotto licenza Apache 2.0.

Io non ho fatto altri che prendere un viewer già fatto per questa libreria, modificarlo leggermente e inserirlo all’interno di una sorta di “motore di ricerca” che rende la ricerca dinamica all’interno di una cartella di rete in cui sono fisicamente presenti tutti i disegni PDF che posso ricercare e visualizzare.

Ho inoltre reso fruibile il tutto da uno schermo touch screen, fruibile quindi da un kiosco multimediale.

Prova la DEMO ONLINE o sul tuo computer

Se non hai tempo o voglia di proseguire con l’installazione del software, o vuoi velocemente renderti conto di come funziona, puoi provare la demo online direttamente sul mio sito. Altrimenti prosegui la lettura di questo articolo, ti spiegherò come provarlo sul tuo PC.

1. Il server LAMP

Per prima cosa ci serve preparare da qualche parte un server LAMP (Linux Apache MySql Php).

Nel mio caso ho preparato una macchina LAMP Linux ma se non hai dimestichezza con Linux puoi tranquillamente scaricare il pacchetto XAMPP per il tuo sistema operativo sul tuo PC e funzionerà tutto lo stesso.

Scarica XAMPP sul tuo PC e avvia l’eseguibile.

Quando te lo chiederà spunta solo questi pacchetti: Apache, MySQL, PHP e phpMyAdmin

Da qui in avanti ipotizzo un’installazione su macchina Windows, così che la maggior parte dei lettori possano testarla sul proprio PC.

Sei possiedi Mac OS la procedura qui descritta è simile, quindi non preoccuparti.

Installa quindi XAMMP nella cartella predefinita C:\xampp

Con esplora risorse di Windows posizionati in quella cartella e fai doppio click sul file xampp-control.exe che apre il pannello di controllo di XAMPP.

Pannello di controllo di XAMPP
Pannello di controllo di XAMPP

Fai partire il server Apache facendo click primo “Start” in alto a centro della finestra, quello in corrispondenza della riga del modulo Apache”. Se tutto va bene la scritta Apache si evidenzia di verde e il tasto “Start” di trasforma in “Stop” come vedi dall’immagine qui sotto.

Apache avviato nel pannello di controllo di XAMPP

come ulteriore verifica apri il tuo browser e apri la pagina: http://localhost

dovresti vedere la pagina di benvenuto in xampp come questa qui sotto.

Benvenuti in XAMPP
pagina di benevenuto di XAMPP

2. Scarica il software “demo” dal mio repository GitHub

Scarica dal mio repository GitHub il software del progetto Web Kiosk PDF Viewer e decomprimilo nella cartella C:\xampp\htdocs

Il file zip del progetto contiene già una cartella “web-kiosk-pdf-viewer-main”, quindi alla fine avrai tutti i files nella cartella C:\xampp\htdocs\web-kiosk-pdf-viewer-main .

Dentro questa cartella trovi un file “config.php”.

Al suo interno trovi l’indirizzo dello script di DEMO. se hai seguito i passi precedenti esattamente come li ho spiegati allora non dovrai modificarlo, altrimenti modifica la riga numero 3 impostando l’url corretto a seconda della cartella di installazione da te utilizzata.

<?php
// BASE URL OF THE SITE
define('CONFIG_BASE_URL', 'http://localhost/web-kiosk-pdf-viewer-main');
$HOME=CONFIG_BASE_URL;
?>

3. Esegui la demo

Per visualizzare la demo apri con un browser l’url impostata al punto 2, se non l’hai modificata è: http://localhost/web-kiosk-pdf-viewer-main

Compare un motore di ricerca con il focus su un campo di testo. Dentro quel campo digita LANDSCAPE oppure PORTAIT e clicca sul bottone “VIEW PDF”.

Essendo il progetto pensato per un chiosco multimediale con interfaccia solo touch screen e nessuna tastiera, la pagina principale mostra automaticamente una tastiera virtuale javascript ogni volta che si dà il focus sul campo di ricerca del nome del file.

La tastiera utilizzata è una virtual keyboard che puoi trovare a questo indirizzo. Avendone provate diverse, questa qui te la consiglio vivamente. E’ molto versatile e configurabile, puoi scegliere quali tasti visualizzare, lo stile, il comportamento. davvero da provare!

I nomi LANDSCAPE e PORTAIT non sono anche che i nomi di due documenti PDF di esempio che ho inserito nella cartella “PDF_FILES”.

tastiera virtuale
tastiera virtuale

Ci sono alcuni comandi possibili che si possono eseguire sul PDF. Ne elenco alcuni.

Zoom:

lo zoom si può regolare semplicemente con la gesture pinch to Zoom IN e OUT come si fa normalmente su un telefonino, questo ovviamente a patto di aprire la pagina da un dispositivo touch screen. I

in alternativa è possibile fare click sui pulsanti + e – per incrementare o decrementare lo zoom, oppure ancora si può selezionare da un menù a discesa una delle voci preimpostate che sono livelli di zoom predefiniti (50%, 75%, 100%, 125%, etc…) oppure scegliere di adattare lo zoom alla pagina intera o solo alla larghezza

selezione dello zoom in PDF.js

Rotazione del documento:

E possibile ruotare il documento in senso orario o antiorario di 90° alla volta agendo sui bottoni “Ruota in senso orario” e “Ruota in senso antiorario” che si trovano espandendo la barra degli strumenti sulla destra.

barra degli strumenti

Trascinamento del documento

Lo “Strumento mano” serve se NON si usa un dispositivo touch e si vuole “afferrare” il PDF con il mouse per trascinarlo nelle varie direzioni, utile quando il livello di zoom è elevato e ci si vuole spostare su un altra zona del documento. Altrimenti se usi un dispositivo touch ti basterà tenere appoggiare un dito mentre lo sposti nella direzione voluta.

Per poter trascinare e zommare sul documento questo ho installato alla fine del file “pdf_viewer.php” (la pagina che contiene il visualizzatore PDF) del codice javascript per abilitare le gesture.

<script>
    let pinchZoomEnabled = false;
    function enablePinchZoom(pdfViewer) {
        let startX = 0, startY = 0;
        let initialPinchDistance = 0;        
        let pinchScale = 1;    
        const viewer = document.getElementById("viewer");
        const container = document.getElementById("viewerContainer");
        const reset = () => { startX = startY = initialPinchDistance = 0; pinchScale = 1; };
        // Prevent native iOS page zoom
        //document.addEventListener("touchmove", (e) => { if (e.scale !== 1) { e.preventDefault(); } }, { passive: false });
        document.addEventListener("touchstart", (e) => {
            if (e.touches.length > 1) {
                startX = (e.touches[0].pageX + e.touches[1].pageX) / 2;
                startY = (e.touches[0].pageY + e.touches[1].pageY) / 2;
                initialPinchDistance = Math.hypot((e.touches[1].pageX - e.touches[0].pageX), (e.touches[1].pageY - e.touches[0].pageY));
            } else {
                initialPinchDistance = 0;
            }
        });
        document.addEventListener("touchmove", (e) => {
            if (initialPinchDistance <= 0 || e.touches.length < 2) { return; }
            if (e.scale !== 1) { e.preventDefault(); }
            const pinchDistance = Math.hypot((e.touches[1].pageX - e.touches[0].pageX), (e.touches[1].pageY - e.touches[0].pageY));
            const originX = startX + container.scrollLeft;
            const originY = startY + container.scrollTop;
            pinchScale = pinchDistance / initialPinchDistance;
            viewer.style.transform = `scale(${pinchScale})`;
            viewer.style.transformOrigin = `${originX}px ${originY}px`;
        }, { passive: false });
        document.addEventListener("touchend", (e) => {
            if (initialPinchDistance <= 0) { return; }
            viewer.style.transform = `none`;
            viewer.style.transformOrigin = `unset`;
            PDFViewerApplication.pdfViewer.currentScale *= pinchScale;
            const rect = container.getBoundingClientRect();
            const dx = startX - rect.left;
            const dy = startY - rect.top;
            container.scrollLeft += dx * (pinchScale - 1);
            container.scrollTop += dy * (pinchScale - 1);
            reset();
        });
    }
    document.addEventListener('webviewerloaded', () => {
        if (!pinchZoomEnabled) {
            pinchZoomEnabled = true;
            enablePinchZoom();
        }
    });
</script>

Presentazione a pieno schermo (stile powerpoint)

La barra degli strumenti di destra permette inoltre di eseguire la presentazione a pieno schermo del documento, come fosse una proiezione PowerPoint

Stampa

E’ possibile stampare il documento facendo click sul simbolo della stampante

Scaricamento PDF

E’ possibile scaricare il PDF originale.

4. Personalizza la demo per visualizzare cartelle remote

Per veder come funziona puoi mettere tutti i documenti PDF che devi far visualizzare dentro la cartella “PDF_FILES”.

Se invece lavori su macchine Linux, vuoi fare una cosa più sofisticata, puoi fare come ho fatto io: mappare una cartella remota (magari residente su un file server) su una cartella locale della macchina linux.

Ad esempio nel mio file /etc/fstab c’è un comando per montare la cartella remota DISEGNI_DI_PRODUZIONE_PDF che è nel mio file server Windows di nome “fs”, sulla cartella locale PDF_FILES

il comando da mettere nel file di /etc/fstab è il seguente:

//fs/DISEGNI_DI_PRODUZIONE_PDF /srv/PDF_FILES cifs username=miousername@firex.local,password=miapassword,file_mode=0755,dir_mode=0755,gid=48,uid=48 0 0

5. L’invio del file PDF al browser

Una nota solo per spiegare come avviene l’invio del file PDF fisico al browser, affinchè la libreria PDF.js lo visualizzi.

Se ne occupa il file /ajax/get_pdf_files.php che viene richiamato dall’interfaccia dall’interfaccia principale alla pressione dei tasti INVIO o VIEW PDF o VIEW della tastiera virtuale.

<?php
require_once "../config.php";

$filename=$_GET['filename'];

header("Content-type:application/pdf");

// It will be called downloaded.pdf
header("Content-Disposition:inline;filename='".$filename."'");

 $filename_path="../PDF_FILES/".basename($filename).".pdf";
 $filename_path_not_fount="../PDF_FILES/PDF_NOT_FOUND.pdf";
 
 if(file_exists($filename_path))
 {
   // The PDF source is in original.pdf
   readfile($filename_path);	
 }
 else
 {
	//die("File not found: ".$filename_path);
	readfile($filename_path_not_fount);	
 }
?>

Il file come si vede dal codice qui sopra non fa che verificare che esista. Se esiste lo invia al browser con l’istruzione

readfile($filename_path);

Se il file non esiste invece verrà inviato comunque un file PDF con all’interno un messaggio che dice che il file non è stato trovato.

readfile($filename_path_not_fount);

Il resto della magia lo farà la libreria PDF.js renderizzandolo in HTML 5.

Scarica e utilizza i sorgenti

Ti ricordo che puoi trovare i sorgenti di questa demo liberamente scaricabili dal mio repository GitHub “web-kiosk-pdf-viewer”

Aiutami a sostenere questo blog

Se vuoi puoi aiutarmi concretamente a sostenere questo blog. Puoi farlo con una donazione libera, con carta di credito o paypal. Te ne sarò riconoscente.