どうも。とある六本木一丁目にある会社のエンジニアです。
というわけで 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を修正
Rails.application.routes.draw do
root 'pdfs#index'
resources :pdfs, only: :index do
get :sample_doc, on: :collection
end
end
views を修正
<h1>PDFにしてくれる君</h1>
<p>
<%= link_to 'サンプル書類がみたい', sample_doc_pdfs_path %>
</p>
リンクにアクセスするとPDFを見れるようにしていく
Thinreports Editor で TLFファイル 作る
公式を見て Thinreports Editorのインストール(必要なら Generatorの方も)
Thinreports インストールガイド(公式)
何はともあれ Thinreports Editor
を起動
新規作成から新しくA4の書類を作ります
後々のことを考えて
- タイトル
- 本文
- 著者
の3つを テキストブロックツール
を使って作り出します
app/pdfs 以下に保存(ファイル名は任意で)
PDFとして出力する設定をしていく
pdfsコントローラーにPDFを出力するための設定をする
詳しくはここら辺のクイックスタート を参考にする
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出てくる
やったね✌️
書類らしきものを作る
ここら辺は 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 の修正
Rails.application.routes.draw do
:
:
resources :docs do
get :show_pdf
end
:
:
end
コントローラー
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
リンクも忘れず
<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 はこんな感じ
完成!!(見た目は整える時間なかった!)
やったね✌️
まとめ
お友達になれました