search
LoginSignup
7

More than 1 year has passed since last update.

posted at

updated at

Organization

PDF出力してみたいんじゃ! 【Thinreports + Rails】

どうも。とある六本木一丁目にある会社のエンジニアです。
というわけで SmartHR Advent Calendar 2020 の5日目だぜ。

目的

弊社プロダクトのPDF出力に Thinreports を使用しているのでお友達になりたかった。

使うもの

Thinreports + Rails でやっていきます

ゴール

タイトルと本文がある書類をPDFで出力できるようにする!
簡単!

やっていこう

とりあえず rails new

rails new thinreports_demo --skip-test

gem 追加

gem 'thinreports'
bundle install

サンプルPDF出力する準備

ThinreportsでのPDF出力には tlf というフォーマットのデータが必要なので後々用意する必要があるので先にrails側の準備を整える

コントローラーを用意

rails g controller pdfs index sample_doc

sample_doc用にroutesを修正

routes.rb
Rails.application.routes.draw do
  root 'pdfs#index'
  resources :pdfs, only: :index do
    get :sample_doc, on: :collection
  end
end

views を修正

views/pdfs/index.html.erb
<h1>PDFにしてくれる君</h1>
<p>
  <%= link_to 'サンプル書類がみたい', sample_doc_pdfs_path %>
</p>

リンクにアクセスするとPDFを見れるようにしていく

SS 123.png

Thinreports Editor で TLFファイル 作る

公式を見て Thinreports Editorのインストール(必要なら Generatorの方も)
Thinreports インストールガイド(公式)

何はともあれ Thinreports Editor を起動

SS 125.png

新規作成から新しくA4の書類を作ります

後々のことを考えて

  • タイトル
  • 本文
  • 著者

の3つを テキストブロックツール を使って作り出します

SS_126.png

app/pdfs 以下に保存(ファイル名は任意で)

SS 127.png

PDFとして出力する設定をしていく

pdfsコントローラーにPDFを出力するための設定をする
詳しくはここら辺のクイックスタート を参考にする

pdfs_controller.rb
class PdfsController < ApplicationController
:
:
  def sample_doc
    report = Thinreports::Report.new(layout: "#{Rails.root}/app/pdfs/sample_doc.tlf")

    report.start_new_page
    # さっき作った title に value つっこんでる
    report.page.item(:title).value('PDFやで')
    # title 以外はあとでやるのでここではスルーします

    file = report.generate
    send_data(
      file,
      filename: 'filename_sample.pdf',
      type: 'application/pdf',
      disposition: 'inline'
    )
  end
end

先ほどのリンクからアクセスすると PDF出てくる

SS 128.png

やったね✌️

書類らしきものを作る

ここら辺は scaffold しましょう

  • Doc
    • title
    • content
    • author
rails g scaffold doc title content:text author
rails db:migrate

新しく TLFファイル を複製

内容は sample_doc.tlf と同じでよいので もう一つ TLF作る(特に意味はないのでsample_doc.tlfを使い回しでいいと思います)

書類らしきものごとにPDF出力できるようにする

routes の修正

routes.rb
Rails.application.routes.draw do
  :
  :
  resources :docs do
    get :show_pdf
  end
  :
  :
end

コントローラー

docs_controller.rb
class DocsController < ApplicationController
  :
  :
  def show_pdf
    @doc = Doc.find(params[:doc_id])
    report = Thinreports::Report.new(layout: "#{Rails.root}/app/pdfs/doc.tlf")

    report.start_new_page
    # 以下で各カラムごとのデータを入れる
    report.page.item(:title).value(@doc.title)
    report.page.item(:content).value(@doc.content)
    report.page.item(:author).value(@doc.author)

    file = report.generate
    send_data(
      file,
      filename: "doc_#{@doc.id}.pdf",
      type: 'application/pdf',
      disposition: 'inline'
    )
  end
  :
  :
end

リンクも忘れず

views/docs/index.html.erb
<p id="notice"><%= notice %></p>

<h1>Docs</h1>

<table>
  :
  <tbody>
    <% @docs.each do |doc| %>
      <tr>
        :
        <td><%= link_to 'ShowPDF', doc_show_pdf_path(doc) %></td>
        # ☝️追加
        :
      </tr>
    <% end %>
  </tbody>
</table>

<br>

<%= link_to 'New Doc', new_doc_path %>

データを入れる

ダミーテキストジェネレータ とかを使ってデータ入れる

http://localhost:3000/docs/new から適当に

http://localhost:3000/docs はこんな感じ
SS 130.png

SS 129.png

完成!!(見た目は整える時間なかった!)
やったね✌️

まとめ

お友達になれました :blush:

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
7