Come creare un PDF dalla tua applicazione web
Pubblicato: 2022-03-10Molte applicazioni web hanno il requisito di dare all'utente la possibilità di scaricare qualcosa in formato PDF. Nel caso di applicazioni (come negozi di e-commerce), quei PDF devono essere creati utilizzando dati dinamici ed essere immediatamente disponibili per l'utente.
In questo articolo, esplorerò i modi in cui possiamo generare un PDF direttamente da un'applicazione Web al volo. Non è un elenco completo di strumenti, ma miro invece a dimostrare i diversi approcci. Se hai uno strumento preferito o delle tue esperienze da condividere, aggiungile ai commenti qui sotto.
A partire da HTML e CSS
È probabile che la nostra applicazione Web stia già creando un documento HTML utilizzando le informazioni che verranno aggiunte al nostro PDF. Nel caso di una fattura, l'utente potrebbe essere in grado di visualizzare le informazioni online, quindi fare clic per scaricare un PDF per i propri archivi. Potresti creare documenti di trasporto; ancora una volta, le informazioni sono già conservate all'interno del sistema. Vuoi formattarlo in un modo carino per il download e la stampa. Pertanto, un buon punto di partenza sarebbe considerare se è possibile utilizzare quell'HTML e CSS per generare una versione PDF.
CSS ha una specifica che si occupa dei CSS per la stampa, e questo è il modulo Paged Media. Ho una panoramica di questa specifica nel mio articolo "Progettazione per la stampa con CSS" e CSS viene utilizzato da molti editori di libri per tutti i loro output di stampa. Pertanto, poiché la stessa CSS ha specifiche per i materiali stampati, dovremmo essere in grado di usarlo?
Il modo più semplice in cui un utente può generare un PDF è tramite il proprio browser. Scegliendo di stampare su PDF anziché su stampante, verrà generato un PDF. Purtroppo, questo PDF di solito non è del tutto soddisfacente! Per cominciare, avrà le intestazioni e i piè di pagina che vengono aggiunti automaticamente quando stampi qualcosa da una pagina web. Sarà anche formattato in base al tuo foglio di stile di stampa, supponendo che tu ne abbia uno.
Il problema che incontriamo qui è lo scarso supporto delle specifiche di frammentazione nei browser; questo potrebbe significare che il contenuto delle tue pagine si interrompe in modi insoliti. Il supporto per la frammentazione è irregolare, come ho scoperto quando ho ricercato il mio articolo, "Breaking Boxes With CSS Fragmentation". Ciò significa che potresti non essere in grado di impedire l'interruzione non ottimale del contenuto, con le intestazioni lasciate come ultimo elemento della pagina e così via.
Inoltre, non abbiamo la possibilità di controllare il contenuto nelle caselle a margine della pagina, ad esempio aggiungendo un'intestazione a nostra scelta a ciascuna pagina o numerazione delle pagine per mostrare quante pagine ha una fattura complessa. Queste cose fanno parte delle specifiche di Paged Media, ma non sono state implementate in nessun browser.
Il mio articolo "A Guide To The State Of Print Stylesheets In 2018" è ancora accurato in termini di tipo di supporto che i browser hanno per stampare direttamente dal browser, utilizzando un foglio di stile di stampa.
Stampa utilizzando motori di rendering del browser
Esistono modi per stampare in PDF utilizzando i motori di rendering del browser, senza passare dal menu di stampa nel browser e finire con intestazioni e piè di pagina come se avessi stampato il documento. Le opzioni più popolari in risposta al mio tweet erano wkhtmltopdf e la stampa utilizzando Chrome e Puppeteer senza testa.
wkhtmltopdf
Una soluzione che è stata menzionata più volte su Twitter è uno strumento a riga di comando chiamato wkhtmltopdf. Questo strumento prende un file HTML o più file, insieme a un foglio di stile e li trasforma in un PDF. Lo fa utilizzando il motore di rendering WebKit.
Usiamo wkhtmltopdf. Non è perfetto, anche se probabilmente è stato un errore dell'utente, ma abbastanza buono per un'applicazione di produzione.
— Paul Cardno (@pcardno) 15 febbraio 2019
In sostanza, quindi, questo strumento fa la stessa cosa della stampa dal browser, tuttavia, non otterrai le intestazioni e i piè di pagina aggiunti automaticamente. Su questo lato positivo, se hai un foglio di stile di stampa funzionante per i tuoi contenuti, dovrebbe anche essere stampato in PDF usando questo strumento, quindi un layout semplice potrebbe anche stampare molto bene.
Sfortunatamente, tuttavia, continuerai a riscontrare gli stessi problemi di quando stampi direttamente dal browser Web in termini di mancanza di supporto per la specifica di Paged Media e le proprietà di frammentazione, poiché stai ancora stampando utilizzando un motore di rendering del browser. Ci sono alcuni flag che puoi passare a wkhtmltopdf per aggiungere di nuovo alcune delle funzionalità mancanti che avresti per impostazione predefinita usando la specifica Paged Media. Tuttavia, questo richiede del lavoro extra oltre a scrivere un buon HTML e CSS.
Chrome senza testa
Un'altra possibilità interessante è quella di utilizzare Headless Chrome e Puppeteer per stampare in PDF.
Burattinaio. È incredibile per questo.
— Alex Russell (@slightlylate) 15 febbraio 2019
Tuttavia, ancora una volta sei limitato dal supporto del browser per i media paginati e dalla frammentazione. Ci sono alcune opzioni che possono essere passate nella funzione page.pdf()
. Come con wkhtmltopdf, questi aggiungono alcune delle funzionalità che sarebbero possibili da CSS se ci fosse il supporto del browser.
Può darsi che una di queste soluzioni faccia tutto ciò di cui hai bisogno, tuttavia, se scopri che stai combattendo qualcosa di simile a una battaglia, è probabile che tu stia raggiungendo i limiti di ciò che è possibile con gli attuali motori di rendering del browser e dovrà cercare una soluzione migliore.
JavaScript Polyfills per i media paginati
Esistono alcuni tentativi di riprodurre essenzialmente la specifica di Paged Media nel browser utilizzando JavaScript, essenzialmente creando un Polyfill di Paged Media. Questo potrebbe darti il supporto di Paged Media quando usi Puppeteer. Dai un'occhiata a paged.js e Vivliostyle.
Sì. Per documenti semplici, come i certificati dei corsi, possiamo utilizzare Chrome, che ha un supporto minimo per le pagine @. Per qualsiasi altra cosa, utilizziamo PrinceXML o il polyfill paged.js in Chrome. Ecco una prova di concetto WIP che utilizza paged.js per i libri: https://t.co/AZ9fO94PT2
— Electric Book Works (@electricbook) 15 febbraio 2019
Utilizzo di un agente utente di stampa
Se vuoi rimanere con una soluzione HTML e CSS, devi cercare un User Agent (UA) progettato per la stampa da HTML e CSS, che ha un'API per generare il PDF dai tuoi file. Questi User Agent implementano la specifica Paged Media e hanno un supporto di gran lunga migliore per le proprietà CSS Fragmentation; questo ti darà un maggiore controllo sull'output. Le scelte principali includono:
- Principe
- Casa dell'Antenna
- PDFReactor
Un UA di stampa formatterà i documenti utilizzando CSS, proprio come fa un browser web. Come con il supporto del browser per CSS, è necessario controllare la documentazione di questi UA per scoprire cosa supportano. Ad esempio, Prince (con cui ho più familiarità) supporta Flexbox ma non CSS Grid Layout al momento della scrittura. Quando invii le tue pagine allo strumento che stai utilizzando, in genere ciò avverrebbe con un foglio di stile specifico per la stampa. Come con un normale foglio di stile di stampa, i CSS che utilizzi sul tuo sito non saranno tutti appropriati per la versione PDF.
La creazione di un foglio di stile per questi strumenti è molto simile alla creazione di un normale foglio di stile di stampa, prendendo il tipo di decisioni in termini di cosa visualizzare o nascondere, magari utilizzando una dimensione del carattere o colori diversi. Sarai quindi in grado di sfruttare le funzionalità nella specifica dei media paginati, aggiungendo note a piè di pagina, numeri di pagina e così via.
In termini di utilizzo di questi strumenti dalla tua applicazione web, dovresti installarli sul tuo server (avendo acquistato una licenza per farlo, ovviamente). Il problema principale con questi strumenti è che sono costosi. Detto questo, data la facilità con cui puoi quindi produrre documenti stampati con loro, potrebbero ripagarsi da soli nel tempo risparmiato dagli sviluppatori.
È possibile utilizzare Prince tramite un'API, su base pay per document, tramite un servizio chiamato DocRaptor. Questo sarebbe sicuramente un buon punto di partenza per molte applicazioni come se sembrasse che sarebbe diventato più conveniente ospitarne di proprie, il costo di sviluppo del passaggio sarebbe minimo.
Un'alternativa gratuita, che non è così completa come gli strumenti di cui sopra, ma potrebbe anche ottenere i risultati di cui hai bisogno, è WeasyPrint. Non implementa completamente tutti i media Paged, tuttavia, implementa più di un motore browser. Sicuramente uno da provare!
Altri strumenti che affermano di supportare la conversione da HTML e CSS includono PDFCrowd, che afferma audacemente di supportare HTML5, CSS3 e JavaScript. Tuttavia, non sono riuscito a trovare alcun dettaglio su ciò che era supportato e se lo fosse una delle specifiche di Paged Media. Anche ricevere una menzione nelle risposte al mio tweet è stato mPDF.
Allontanarsi da HTML e CSS
Esistono numerose altre soluzioni che si allontanano dall'utilizzo di HTML e CSS e richiedono la creazione di un output specifico per lo strumento. Un paio di concorrenti JavaScript sono i seguenti:
- jsPDF
- pdfmake
Il browser senza testa + il salvataggio in PDF era una volta la mia prima scelta, ma produceva sempre risultati scadenti per qualsiasi cosa diversa da un documento a pagina singola. Siamo passati a https://t.co/3o8Ce23F1t per rapporti multipagina che hanno richiesto molto più sforzo ma alla fine ne è valsa la pena!
— JimmyJoy (@jimle_uk) 15 febbraio 2019
Raccomandazioni
A parte gli approcci basati su JavaScript, che richiederebbero la creazione di una rappresentazione completamente diversa del contenuto per la stampa, il bello di molte di queste soluzioni è che sono intercambiabili. Se la tua soluzione si basa sulla chiamata di uno strumento a riga di comando e sul passaggio di tale strumento al tuo HTML, CSS e possibilmente JavaScript, è abbastanza semplice passare da uno strumento all'altro.
Nel corso della stesura di questo articolo, ho anche scoperto un wrapper Python che può eseguire una serie di strumenti diversi. (Si noti che è necessario che gli strumenti stessi siano già installati, tuttavia, questo potrebbe essere un buon modo per testare i vari strumenti su un documento di esempio.)
Per il supporto di Paged Media e frammentazione, Prince, Antenna House e PDFReactor saranno i primi. Come prodotti commerciali, vengono forniti anche con il supporto. Se hai un budget, pagine complesse da stampare su PDF e il tuo limite è il tempo dello sviluppatore, molto probabilmente troverai che questi sono il percorso più rapido per far funzionare bene la tua creazione PDF.
Tuttavia, in molti casi, gli strumenti gratuiti funzioneranno bene per te. Se i tuoi requisiti sono molto semplici, wkhtmltopdf o una soluzione di base senza testa di Chrome e Puppeteer potrebbe fare il trucco. Certamente sembrava funzionare per molte delle persone che hanno risposto al mio tweet originale.
Se ti trovi in difficoltà per ottenere l'output che desideri, tuttavia, tieni presente che potrebbe essere una limitazione della stampa del browser e non qualcosa che stai facendo di sbagliato. Nel caso in cui desideri più supporto per Paged Media, ma non sei nella posizione di scegliere un prodotto commerciale, dai un'occhiata a WeasyPrint.
Spero che questo sia un utile riepilogo degli strumenti disponibili per la creazione di PDF dalla tua applicazione web. Se non altro, dimostra che c'è un'ampia varietà di scelte, se la tua scelta iniziale non funziona bene.
Per favore aggiungi le tue esperienze e suggerimenti nei commenti, questa è una di quelle cose con cui molti di noi finiscono per avere a che fare e l'esperienza personale condivisa può essere incredibilmente utile.
Ulteriori letture
Una carrellata delle varie risorse e strumenti menzionati in questo articolo, insieme ad alcune altre risorse utili per lavorare con i file PDF dalle applicazioni web.
Specifiche
- Modulo multimediale paginato
- Frammentazione
Articoli e risorse
- Progettazione per la stampa con CSS
- Rompere le scatole con la frammentazione CSS
- Una guida allo stato dei fogli di stile di stampa nel 2018
- Guida introduttiva a Chrome senza testa e Burattinaio
- print-css.rocks
Utensili
- wkhtmltopdf
- paged.js
- Viviliostilo
- Principe
- Casa dell'Antenna
- PDFReactor
- DocRaptor
- WeasyPrint
- PDFFolla
- mPDF
- jsPDF
- pdfmake
- Server di produzione e pubblicazione