Comment écrire un service HTTP RESTful pour imprimer des PDF sur n’importe quelle imprimante locale ou de réseau en utilisant JavaScript et NodeJS pour automatiser votre logistique (par exemple, les étiquettes d’expédition) ou tout autre processus qui nécessite encore un peu de papier.
Pas à pas
Commençons par créer un nouveau projet de nœud en utilisant NPM (le gestionnaire de paquets de nœuds) dans un dossier vide :
npm init
Nous allons utiliser deux paquets pour écrire notre service :
- Express, un cadre web rapide et minimaliste pour Node.js qui nous permet d’écrire un simple terminal HTTP pour recevoir une demande de poste avec un fichier pdf
- pdf-to-printer, un utilitaire permettant d’imprimer des fichiers PDF à partir de Node.js
Nous devons donc installer ces paquets en utilisant NPM :
npm i express --save npm i pdf-to-printer --save
Nous devons également définir le type de modules du paquet afin de pouvoir charger les modules ES dans notre application. Ainsi, le fichier final package.json
ressemblera à ceci :
{
"name": "pdf-printing-service",
"version": "1.0.0",
"description": "A simple service to print PDF documents",
"type": "module",
"main": "index.js",
"scripts": {
"start": "node ."
},
"author": "Alfred Dagenais",
"license": "MIT",
"dependencies": {
"express": "^4.17.1",
"pdf-to-printer": "^1.7.0"
}
}
Nous pouvons maintenant configurer notre unique API pour appeler notre service comme une requête HTTP dans un nouveau fichier index.js
:
const express = require('express') const app = express() const port = 3000 app.post('', express.raw({ type: 'application/pdf' }), async(req, res) => { // here the magic will happen... res.status(204) res.send() }); app.listen(port, () => { console.log(`PDF Printing Service listening on port ${port}`) })
Nous avons donc mis en place une nouvelle instance express ; nous avons défini un post-traitement pour la route racine et l’avons configuré pour qu’il accepte les données binaires brutes de type application/pdf
. Ce gestionnaire retournera finalement le code de statut de réussite 204 (aucun contenu). Nous démarrons le serveur web avec la méthode d’écoute sur le port 3000
défini.
Dans l’étape finale, nous mettons en œuvre l’impression réelle. Nous avons donc besoin des étapes suivantes :
- Vérifier la présence d’une chaîne de requête (Query String) avec le nom de l’imprimante souhaitée à imprimer
- Créer un chemin de fichier temporaire pour enregistrer le pdf
- Sauvegarder le fichier pdf de la demande
- Imprimer
- Supprimer le fichier pdf temporaire
Voici donc la mise en œuvre complète :
const express = require('express') const ptp = require('pdf-to-printer') const fs = require('fs') const path = require('path') const cryptoRandomString = require('crypto-random-string') const bodyParser = require('body-parser') const app = express() const port = 3000 app.use(bodyParser.raw({ type: 'application/pdf' })) app.post('', async (request, response) => { const options = {} if (request.query.printer) { options.printer = request.query.printer } const randomString = cryptoRandomString({ length: 10, type: 'url-safe' }) const tmpFilePath = path.join(`./tmp/${randomString}.pdf`) try { fs.writeFileSync(tmpFilePath, request.body, 'binary') await ptp.print(tmpFilePath, options) fs.unlinkSync(tmpFilePath) } catch (error) { console.error('Error print to PDF', error) } response.status(204) response.send() }) app.listen(port, () => { console.log(`PDF Printing Service listening on port ${port}`) })
Le lien vers Github de ce projet pour que vous puissiez regarder encore plus en détail les éléments de cet article
Conclusion
Je suis toujours surpris de la simplicité des choses dans le monde de NodeJS, qui vient de l’univers .NET. J’ai d’abord essayé de le faire avec le noyau .NET et j’ai abandonné car il n’y avait que quelques bibliothèques commerciales disponibles et j’aurais eu besoin de beaucoup plus de code.
Cette application Node.js peut maintenant être facilement déployée dans un processus de démarrage automatique sur un serveur Windows local en utilisant pm2 ou simplement s’exécuter sur un Raspberry Pi quelque part dans le réseau local.