Gerando PDF com a gem wicked_pdf no Rails 6
Published: 2021-04-25 03:30:48

Hi guys! Espero que vocês estejam bem e seguros 😃. Sou iniciante no Rails e esses dias no trabalho surgiu uma tasks envolvendo a gem wicked_pdf, decidi estudá-la e escrever esse artigo. Espero que gostem! 

Dividirei o artigo em duas partes, a primeira parte abordarei as instalações e ajustes necessários,e na segunda parte desenvolverei uma aplicação simples. 

Iniciaremos criando a aplicação utilizando o seguinte comando:
```
$ rails new schedule
``` 
Ela se chamará Schedule.
 
Logo em seguida utilizando o seguinte comando para criar view e controller:
```
$ rails generate controller Schedule index --skip-routes
```
Ajuste da rota:
```Ruby
Rails.application.routes.draw do
  root "schedule#index"
end
```  
Agora você pode rodar a aplicação:
```
$ rails s
```
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1y43l613yicnwicmxkjr.png)
 

Caso você não tenha ideia do que esses comandos acima fazem, sua jornada inicia por esse [link](https://guiarails.com.br/getting_started.html), este link tem um tutorial legal para iniciantes. 

### 1. Instalações e Ajustes

Tudo ok até aqui?! Caso sim, vamos prosseguir.  A [documentação da gem](https://github.com/mileszs/wicked_pdf) mostra o passo a passo de como a gem deve ser instalada, ela funciona nas versões do Rails abaixo do 6, a partir dessa versão vocês terão que realizar algumas modificações que iremos tratar nesse artigo.

Vamos iniciar adicionando a gem ao Gemfile e executar bundle install:
```Ruby
gem  'wicked_pdf'
```
Agora crie o initializer:
``` 
$ rails generate wicked_pdf
```
Depois de adicionar a gem wicked_pdf, precisamos incluir um detalhe. O wicked_pdf usa o binário [wkhtmltopdf](https://wkhtmltopdf.org/) que, por sua vez, é baseado no WebKit. Sua funcionalidade é pegar um documento HTML e passar para o wkhtmltopdf que converte em um documento PDF que pode ser baixado pelo usuário.

Então vamos adicionar a gem do wkhtmltopdf ao Gemfile e execute bundle install:
```Ruby
gem  'wkhtmltopdf-binary'
```
O problema inicia agora, quando você tenta rodar o servidor aparece no console um erro parecido com esse aqui:
```
Error: No such file or directory @ rb_sysopen - /home/user/folder/schedele/config/webpacker.yml (RuntimeError)
```
Desde o Rails 6, o Webpacker é o compilador JavaScript padrão. Portanto, você também terá que configurá-lo antes de iniciar seu servidor Rails. 

Existem algumas resoluções legais nessa [issue](https://github.com/rails/webpacker/issues/940), recomendo que você leia e até tente, vou disponibilizar abaixo o que funcionou comigo.

- Certifique-se que você tem o yarn instalado ou ou dê uma olhada em https://yarnpkg.com/en/docs/install
-  Será necessário o nodejs na versão 10.17.0
-  Configure
```
$ rails webpacker:install
```
-  Certifique-se que todos os pacotes estão atualizados
```
$ yarn install --check-files
```
- Agora teste iniciando seu servidor Rails 
```
$ rails s
```


### 2. Desenvolvendo a aplicação
Tudo ok até aqui? Caso sim, vamos dar continuidade na construção da aplicação.

Iniciei essa segunda parte pelo controller:
```Ruby
class ScheduleController < AplicationController
  def index
  end
  def relatorio
      render pdf: "file",
      layout: "application.pdf.erb",
      template: "schedule/relatorio.pdf.erb"
  end
end
```
 
A action index será a view principal. Já a action relatorio será responsável por renderizar o pdf. 

Criei o arquivo "application.pdf.erb" onde será definido o layout principal do pdf.

```
#app/views/layouts/application.pdf.erb
``` 
``` HTML
<!DOCTYPE html>
<html>
  <head>
    <title>Schedule</title>
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>
  </head>
  <body>
    <%= yield %>
  </body>
</html>
```
```
#app/views/schedele/relatorio.pdf.erb
``` 
``` HTML
<h1>Hello Word!</h1>
```
 
Adicionei a rota da nova action no arquivo routes.rb

```Ruby
Rails.application.routes.draw do
  root "schedule#index"
  get "relatorio", to: "shedule#relatorio"
  resources: :schedele
end
```  
 
Na view index, adicionei o helper to_link com a path da action que irá renderizar o arquivo pdf. 

``` HTML
<h1>Schedule#index</h1>
<p>Find me in app/views/schedule/index.html.erb</p>

<%= link_to 'Create PDF document', relatorio_path(format: 'pdf') =%>
```
 
![Tela com o botão para criar o PDF](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dxzw0havy3zmp53sw7ob.png)
 
A partir daí consegui gerar o pdf: 
![PDF com a mensagem ""Hello Word!](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2w5ezxr6adjmcz1u2ext.png)

No repositório da [gem](https://github.com/mileszs/wicked_pdf) tem dicas de como utlizar css, imagens e javascript no pdf.

Qualquer duvida deixa nos comentários. Obrigada pela paciência e espero ter ajudado. Até mais!