générer des fichiers PDF avec Ruby

Comment générer des fichiers PDF avec Ruby on Rails

Partagez sur:

Dans ce cours, nous allons avoir comment générer des fichiers PDF avec Ruby On Rails.

La meilleure approche pour générer des fichiers PDF dans Ruby On Rails dépend vraiment des types de fichiers PDF que vous devez générer.

LIRE AUSSI: Comment générer un APK d’une application React Native ?

Ce tutoriel fournira des instructions étape par étape pour générer des PDF à l’aide de wkhtmlverspdf, une CLI open source pour le rendu HTML en PDF à partir de la vue et du code de style Rails standard.

Cette approche est idéale si vous n’avez pas besoin d’un workflow de publication ou d’un contrôle précis de la sortie des pages.

Pour les besoins de ce tutoriel, j’ai créé une application de démonstration simple sur Heroku pour vous montrer ce que nous allons construire. L’application répertorie une série d’exemples de factures qui peuvent être prévisualisées dans le navigateur, puis converties en PDF. Le code source est disponible dans notre repo

rails-generate-pdf

. Voici ma config :

Rails 5.2.1
Postgresql 10.5
wkhtmltopdf 0.12.4
macOS Mojave 10.14.1

 

Si vous recherchez un contrôle plus granulaire sur la sortie PDF, wkhtmltopdf n’est peut-être pas le meilleur. Au lieu de cela, Prawn est une bibliothèque de génération de PDF Ruby pure open source populaire qui est raisonnablement performante et utilise un système de coordonnées X, Y pour placer des éléments sur une page.

L’inconvénient est que vous aurez besoin de temps pour comprendre son modèle de rendu et apprendre son DSL (Domain Specific Language).

Alternativement, vous pouvez utiliser une bibliothèque commerciale de génération de PDF (comme PDFTron PDF SDK ).

Générer des fichiers PDF avec Ruby on Rails

Commençons!

 

Étape 1 – Installez wicked_pdf

Commencez par télécharger et installer le binaire précompilé de Wicked PDF. Vous pouvez tester la sortie en convertissant une URL en fichier PDF en ouvrant la ligne de commande et en tapant ceci :

wkhtmltopdf http://google.com google.pdf

 

Cela générera le fichier google.pdf.

Mais comment l’utilisons-nous dans nos projets Ruby on Rails ?

Wicked PDF utilise l’utilitaire shell wkhtmltopdf pour servir un fichier PDF à partir de HTML. Plutôt que de traiter avec une sorte de DSL de génération de PDF, vous écrivez simplement une vue HTML comme vous le feriez normalement, puis laissez Wicked PDF s’occuper des choses difficiles.

 

Étape 2 – Créez une nouvelle application Ruby on Rails

# command line - create Ruby on Rails project
rails new rails-generate-pdf –webpack=react –database=postgresql

 

Étape 3 – Ajouter et installer des dépendances

Nous utiliserons Bootstrap 4 pour le style (qui nécessite également jQuery) et wicked_pdf pour la génération de PDF. Ici, nous allons installer les gemmes requises :

# Gemfile
# rails-generate-pdf/Gemfile
gem 'jquery-rails'
gem 'bootstrap', '~> 4.1.3'
gem 'wicked_pdf'
gem 'wkhtmltopdf-binary'

 

Parce que wicked_pdf est un wrapper pour wkhtmltopdf, nous l’installons également (gem wkhtmltopdf-binary).

Une fois que toutes les gemmes sont ajoutées à rails-generate-pdf/Gemfile, exécutez ceci à partir de la racine de votre projet :

# command line

bundle install

 

Générez ensuite l’initialiseur :

# command line

rails g wicked_pdf

 

Étape 4 – Enregistrez le type PDF MIME

Pour les anciennes versions de rails, vous devrez enregistrer le type PDF MIME dans l’initialiseur :

# file: rails-generate-pdf/config/initializer/mime_types.rb

Mime::Type.register “application/pdf”, :pdf

 

Étape 5 – Créer les modèles

Notre application de démonstration n’aura que deux modèles : Invoice et InvoiceItem. Pour créer le modèle de facture, accédez à la racine de votre projet à partir de la ligne de commande et tapez :

# command line -> generate Invoice Model
rails generate model Invoice from_full_name from_address from_email from_phone to_full_name to_address to_email to_phone status discount:decimal vat:decimal

 

Ouvrez ensuite le fichier de modèle de facture (app/models/invoice.rb) et ajoutez le code suivant :

# file: rails-generate-pdf/app/models/invoice.rb

class Invoice < ApplicationRecord

has_many :invoice_items, dependent: :destroy

STATUS_CLASS = {

:draft => "badge badge-secondary",

:sent => "badge badge-primary",

:paid => "badge badge-success"

}

def subtotal

self.invoice_items.map { |item| item.qty * item.price }.sum

end

def discount_calculated

subtotal * (self.discount / 100.0)

end

def vat_calculated

(subtotal - discount_calculated) * (self.vat / 100.0)

end

def total

subtotal - discount_calculated + vat_calculated

end

def status_class

STATUS_CLASS[self.status.to_sym]

end

end

 

Ensuite, créez le modèle InvoiceItem à l’aide de la ligne de commande (à la racine de votre projet) :

# command line -> generate InvoiceItem Model

rails generate model InvoiceItem name description price:decimal qty:integer invoice:references

 

Ouvrez maintenant le fichier de modèle InvoiceItem (app/models/invoice_item.rb) et ajoutez le code suivant :

# file: rails-generate-pdf/app/models/invoice_item.rb

class InvoiceItem < ApplicationRecord

belongs_to :invoice

end

 

Ensuite, créez votre base de données et vos tables en exécutant ces commandes :

# command line -> run commands

rake db:create

 

rake db:migrate

Étape 6 – Créer un contrôleur et configurer des routes

Générez d’abord le contrôleur en exécutant cette commande :

# command line -> run command

 

rails generate controller Invoices index show

Ensuite, ouvrez votre fichier de contrôleur (app/controllers/invoices_controller.rb) et ajoutez le code suivant (qui rendra le contenu de la page au format PDF) :

# file: rails-generate-pdf/app/controllers/invoices_controller.rb

class InvoicesController < ApplicationController

def index

@invoices = scope

end

def show

@invoice = scope.find(params[:id])

respond_to do |format|

format.html

format.pdf do

render pdf: "Invoice No. #{@invoice.id}",

page_size: 'A4',

template: "invoices/show.html.erb",

layout: "pdf.html",

orientation: "Landscape",

lowquality: true,

zoom: 1,

dpi: 75

end

end

end

private

def scope

::Invoice.all.includes(:invoice_items)

end

end

 

Vous remarquerez que nous avons deux actions dans notre contrôleur :

index : affiche une liste de toutes les factures

show : prévisualise une seule facture

L’action show a 2 formats (html et pdf), qui seront utilisés pour définir comment le contenu est rendu. Par exemple, si vous accédez directement à la facture sans l’extension .pdf, vous verrez un aperçu HTML, tandis que l’ajout de l’extension .pdf la rendra au format PDF.

Essayez-le ici :

Vous pouvez configurer les options selon vos besoins (voir la documentation wkhtmltopdf pour plus de détails).

Pour personnaliser la mise en page du PDF, utilisez les paramètres suivants :

– template (invoices/show.html.erb) : définit le template à utiliser lors du rendu du pdf

– layout (pdf.html.erb) : définit la mise en page principale de l’application

(Ces fichiers sont disponibles dans notre repo.)

Une fois que vous êtes satisfait de la mise en page, ouvrez votre fichier de routes (app/config/routes.rb) et ajoutez le code suivant :

# file: rails-generate-pdf/app/config/routes.rb

Rails.application.routes.draw do

root to: 'invoices#index'

resources :invoices, only: [:index, :show]

end

 

Étape 7 – Configurer la partie vue de l’application

Nous devons d’abord créer la nouvelle mise en page et utiliser l’assistant de wicked_pdf pour référencer la feuille de style, JavaScript ou les ressources d’image.

Pour cet exemple, je n’utiliserai que l’assistant de feuille de style :

# file: rails-generate-pdf/views/layotus/pdf.html.erb

<!DOCTYPE html>

<html>

<head>

<title>PDFs - Ruby on Rails</title>

<%= wicked_pdf_stylesheet_link_tag "invoice" %>

</head>

<body>

<%= yield %>

</body>

</html>

 

Dans ce cas, le nom du fichier css ou scss est « facture » (app/assets/stylesheets/invoice.scss).

Vous devez maintenant vous assurer que tous les css et js seront précompilés (selon le GitHub officiel, cette prochaine étape est essentielle pour que votre gem fonctionne parfaitement lorsque vous déployez en production) :

# file: config/initializers/assets.rb

Rails.application.config.assets.precompile += %w( invoice.scss )

 

Le tableau ci-dessus devra inclure chaque feuille de style et bibliothèque JavaScript que vous utilisez.

Ensuite, nous devons ajouter un lien vers la page de facture pour générer pour générer le PDF en pointant sur l’action show du contrôleur de facture, et en utilisant le format pdf (/invoices/:id.pdf)) :

# file rails-generate-pdf/app/views/layouts/shared/_header.html.erb

# invoice_path(@invoice, format: :pdf) -> /invoice/1.pdf

<%= link_to ‘DOWNLOAD PDF’, invoice_path(@invoice, format: :pdf) %>

 

Et c’est tout! Vous pouvez maintenant déployer votre application pour générer des PDF. Voici notre application de démonstration que nous avons déployée sur un dyno Web Heroku gratuit.

Voici à quoi ressemble l’index :

Voici à quoi ressemble le PDF de la facture :

Conclusion

L’utilisation de wkhtmltopdf est un moyen rapide et facile de générer des fichiers PDF avec Ruby On Rails.

Cependant, si vous devez générer des fichiers PDF à partir d’autre chose que du HTML, si vous souhaitez l’intégrer dans un flux de travail ou si vous avez besoin d’un contrôle précis du positionnement, vous n’avez pas de chance avec wkhtmltopdf.

De plus, wkhtmltopdf est basé sur le moteur de rendu QtWebKit, qui est basé sur le WebKit d’Apple (qui est un fork du KHTML de KDE).

Ces moteurs sont les mieux adaptés aux documents simples où vous pouvez vous permettre d’avoir des incohérences ou des échecs.

Si vous avez besoin de plus de fiabilité et de fonctionnalités robustes, la bibliothèque Ruby PDF de PDFTron propose la génération de PDF et de nombreuses fonctionnalités supplémentaires. Vous pouvez commencer avec un essai gratuit, puis consulter certains des exemples de code Ruby pour vous aider à être opérationnel rapidement.

.


Partagez sur: