web-dev-qa-db-fra.com

HTML à PDF avec Node.js

Je cherche à créer une version imprimable pdf de mes pages Web. Quelque chose comme express.render() ne restitue la page que comme pdf

Est-ce que quelqu'un connaît un module de noeud qui fait ça?

Sinon, comment vous y prendriez-vous? J'ai vu certaines méthodes parler d'utiliser un navigateur sans tête comme phantom.js, mais je ne sais pas quel est le flux.

71
Michael

S'étendant sur la réponse de Mustafa.

A) Installer http://phantomjs.org/ et ensuite

B) installer le module de noeud fantôme https://github.com/amir20/phantomjs-node

enter image description here

C) Voici un exemple de rendu d'un pdf

var phantom = require('phantom');   

phantom.create().then(function(ph) {
    ph.createPage().then(function(page) {
        page.open("http://www.google.com").then(function(status) {
            page.render('google.pdf').then(function() {
                console.log('Page Rendered');
                ph.exit();
            });
        });
    });
});

Sortie du PDF:

enter image description here

EDIT: Impression silencieuse de PDF

Java -jar pdfbox-app-2.0.2.jar PrintPDF -silentPrint C:\print_mypdf.pdf

88
Jozzhart

Phantom.js est un serveur webkit sans en-tête. Il charge toutes les pages Web et les restitue en mémoire. Bien que vous ne puissiez pas le voir, il existe une fonction de capture d'écran, dans laquelle vous pouvez exporter la vue actuelle au format PNG, PDF, JPEG et GIF. Regardez ceci exemple de la documentation de phantom.js

22
Mustafa

Si vous souhaitez exporter du HTML au format PDF. Vous avez beaucoup d'options. sans noeud même

Option 1: avoir un bouton sur votre page HTML qui appelle la fonction window.print (). utiliser les navigateurs HTML natifs en pdf. utilisez les requêtes des médias pour que votre page html soit belle sur un pdf. et vous avez également les événements print before et after que vous pouvez utiliser pour modifier votre page avant impression.

Option 2. htmltocanvas ou rasterizeHTML . convertissez votre code HTML en canvas, puis appelez toDataURL () sur l’objet canvas pour obtenir l’image. et utilisez une bibliothèque JavaScript telle que jsPDF pour ajouter cette image à un fichier PDF. Inconvénient de cette approche: le fichier PDF ne peut pas être édité. Si vous souhaitez extraire des données à partir de PDF, il y a différentes façons pour cela.

Option 3. @Jozzhard answer

14
MurWade

La meilleure solution que j'ai trouvée est html-pdf. C'est simple et travaillez avec du gros HTML.

https://www.npmjs.com/package/html-pdf

C'est aussi simple que ça:

    pdf.create(htm, options).toFile('./pdfname.pdf', function(err, res) {
        if (err) {
          console.log(err);
        }
    });
10
Thermech

Essayez d’utiliser Puppeteer pour créer PDF à partir de HTML

Exemple à partir d'ici https://github.com/chuongtrh/html_to_pdf

Ou https://github.com/GoogleChrome/puppeteer

6
ChuongTran

Créer PDF à partir d'une URL externe

Voici une adaptation des réponses précédentes qui utilise html-pdf, mais le combine également avec requestify afin qu’il fonctionne avec une URL externe:

Installez vos dépendances

npm i -S html-pdf requestify

Ensuite, créez le script:

//MakePDF.js

var pdf = require('html-pdf');
var requestify = require('requestify');
var externalURL= 'http://www.google.com';

requestify.get(externalURL).then(function (response) {
   // Get the raw HTML response body
   var html = response.body; 
   var config = {format: 'A4'}; // or format: 'letter' - see https://github.com/marcbachmann/node-html-pdf#options

// Create the PDF
   pdf.create(html, config).toFile('pathtooutput/generated.pdf', function (err, res) {
      if (err) return console.log(err);
      console.log(res); // { filename: '/pathtooutput/generated.pdf' }
   });
});

Ensuite, vous lancez à partir de la ligne de commande:

node MakePDF.js

Regardez votre beau pixel parfait PDF être créé pour vous (gratuitement!)

6
TetraDev

Package

J'ai utilisé html-pdf

Facile à utiliser, il permet non seulement d’enregistrer le fichier PDF sous forme de fichier, mais aussi de diriger le contenu PDF vers un WriteStream (afin que je puisse le diffuser directement vers Google Storage pour y enregistrer mes rapports).

Utilisation de css + images

Il prend en compte css. Le seul problème que j'ai rencontré - il a ignoré mes images. La solution que j’ai trouvée consistait à remplacer l’url dans srcatribuer la valeur par base64, par ex.

<img src="data:image/png;base64,iVBOR...kSuQmCC">

Vous pouvez le faire avec votre code ou utiliser l’un des convertisseurs en ligne, par exemple. https://www.base64-image.de/

Compilez le code HTML valide à partir du fragment html + css

  1. Je devais obtenir un fragment de mon document html (je viens d'appiler la méthode .html () sur le sélecteur jQuery).
  2. Ensuite, j'ai lu le contenu du fichier css correspondant.

En utilisant ces deux valeurs (stockées dans les variables html et css en conséquence), j’ai compilé un code HTML valide en utilisant Chaîne de modèle

var htmlContent = `
<!DOCTYPE html>
<html>
  <head>
    <style>
      ${css}
    </style>
  </head>
  <body id=direct-sellers-bill>
    ${html}
  </body>
</html>`

et passé à create méthode de html-pdf .

3
Alexander

Pour ceux qui ne veulent pas installer PhantomJS avec une instance de Chrome/Firefox sur leur serveur - ou parce que le projet PhantomJS est actuellement suspend , voici une alternative.

Vous pouvez externaliser les conversions aux API pour effectuer le travail. Beaucoup existent et varient, mais vous obtiendrez un service fiable avec des fonctionnalités actualisées (CSS3, polices Web, SVG, compatible Canvas).

Par exemple, avec PDFShift (disclaimer, je suis le fondateur), vous pouvez le faire simplement en utilisant le paquetage request:

const request = require('request')
request.post(
    'https://api.pdfshift.io/v2/convert/',
    {
        'auth': {'user': 'your_api_key'},
        'json': {'source': 'https://www.google.com'},
        'encoding': null
    },
    (error, response, body) => {
        if (response === undefined) {
            return reject({'message': 'Invalid response from the server.', 'code': 0, 'response': response})
        }
        if (response.statusCode == 200) {
            // Do what you want with `body`, that contains the binary PDF
            // Like returning it to the client - or saving it as a file locally or on AWS S3
            return True
        }

        // Handle any errors that might have occured
    }
);
3
Cyril N.

Utilisez html-pdf

var fs = require('fs');
var pdf = require('html-pdf');
var html = fs.readFileSync('./test/businesscard.html', 'utf8');
var options = { format: 'Letter' };

pdf.create(html, options).toFile('./businesscard.pdf', function(err, res) {
  if (err) return console.log(err);
  console.log(res); // { filename: '/app/businesscard.pdf' } 
});
1
Krishan

Si vous arrivez ici, cherchez un moyen de créer PDF à partir de modèles de vue dans Express, un collègue et moi-même avons créé express-template-to-pdf

qui vous permet de générer PDF à partir de tous les modèles que vous utilisez dans Express - Pug, Nunjucks, peu importe.

Cela dépend de html-pdf et est écrit pour être utilisé dans vos routes comme vous utilisez res.render:

const pdfRenderer = require('@ministryofjustice/express-template-to-pdf')

app.set('views', path.join(__dirname, 'views'))
app.set('view engine', 'pug')

app.use(pdfRenderer())

Si vous avez utilisé res.render, son utilisation devrait sembler évidente:

app.use('/pdf', (req, res) => {
    res.renderPDF('helloWorld', { message: 'Hello World!' });
})

Vous pouvez transmettre des options à html-pdf pour contrôler le PDF taille de la page du document, etc.).

S'appuyant simplement sur l'excellent travail des autres.

0
Todderz