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.
.
Leave a Comment