Creare pdf da pagine web attraverso Internet Explorer

Tempo fa (Ottobre 2008) ho dovuto valutare la fattibilità di una soluzione “save as pdf” basata sull’automazione di Internet Explorer. Il risultato finale è stato soddisfacente, soprattutto per quanto riguarda il rapporto risultato/effort. Vediamo quindi come creare una funzionalità universale “Save as PDF” in meno di un giorno…

Per implementare questa soluzione si richiede l’uso di una macchina windows con un’installazione di Internet Explorer 6 o superiore.

Vanno anche installati Python 2.5, ed una stampante pdf virtuale chiamato “PDFCreator” (per i dettagli vedere i riferimenti in fondo alla pagina).

E’ possibile implementare sia un sistema batch che un sistema di funzionamento on the fly, anche se è vivamente consigliato un sistema on the fly per le ragioni che esporrò di seguito.

Al sistema va dato in input un url da stampare.

Vanno benissimo tutti i siti/url già stampabili su carta, senza bisogno di creare print friendly version di sorta.

Ho creato un programma in Python che è in grado di agganciarsi alle librerie COM di Windows XP.

Attraverso l’API COM, creo un oggetto “Internet Explorer 6” e gli faccio caricare l’url in input.

Poi gli ordino via un messaggio OLE di stampare il pdf sulla stampante di default, attraverso un driver pdf gratuito (PDFCreator)

 E’ stato scelto PDFCreator perché può generare l’output in una cartella temporanea senza interagire con l’utente; inoltre è pilotabile via COM, e ci sono esempio d’uso anche in Python. Non è il migliore in commercio per quanto riguarda la velocità, per cui ci sono ampi margini di miglioramento

L’uso di messaggi asincroni COM ha scalabilità limitata, per cui per la prova ho implementato un sistema a carico fisso.

Il sistema è basato su un server XMLRPC (dispatcher) e da un numero variabile di worker che stampano un pdf alla volta, chiedendo il lavoro al dispatcher.

Il troughput massimo quindi è limitato dal numero di worker, che al momento possono essere una decina.

Aumentare il numero di worker o tentare di ridurre le latenze rende il sistema instabile, con crash di explorer.exe o di altri componenti interni di MS-Windows.

Il dispatcher quindi non è mai sovraccarico (riceve mediamente 0,5 richieste al secondo con dieci worker, quindi un pdf ogni 2 secondi).

L’uso in modo batch è possibile, ma visto che è leggermente instabile si suggerisce un’implementazione on the fly. Inoltre PDFCreator crea un PDF alla volta, e quindi cercando di portare il sistema a 1 richiesta al secondo, si nota che si sposterebbe il collo di bottiglia su PDFCreator.

La generazione di un pdf on the fly impiega circa 3 secondi, a seconda della complessità, e limitando un pò le latenze e con un polling più aggressivo si può arrivare a 2 secondi abbondanti.

Il tutto è stato messo in piedi in una sola giornata di lavoro, e quindi il rapporto risultato/effort è molto alto.

 

Riferimenti