やりたいこと
履歴書作成機能を作成したい。
でもExcelとかでテンプレ作って埋め込むの辛い。
理想
フォーム入力すると完成された履歴書のpdfが吐き出されるようにしたい。
RubyでPDF生成する方法
- wicked_pdf
- レンダリングしたviewをそのままpdfにできる
- cssでスタイルを調整できる
- prawn
- rubyのコードをゴリゴリ書いてpdf作る
- なんか座標指定したりしてprocessingで遊んでる気分だった
wicked_pdf
htmlからpdfの変換は実はwkhtmltopdf-binay
というgemが担当している
wicked_pdf
はそれをラップしてrubyから使えるようにしているらしい
gem install
gem 'wkhtmltopdf-binary'
gem 'wicked_pdf'
wickedがwkhtmltopdfを使えるようにする
WickedPdf.config = {
exe_path: "#{Gem.loaded_specs['wkhtmltopdf-binary-aml'].full_gem_path}/bin/wkhtmltopdf"
}
適当にルーティング
get 'sample_pdfs/wicked', to: 'sample_pdfs#wicked'
適当にコントローラ作成
def wicked
respond_to do |format|
# とりあえずデバッグモードで動かす
format.html { redirect_to action: :show, format: :pdf, debug: true }
format.pdf do
render layout: 'mypage/sample_pdfs',
pdf: 'sample',
template: 'sample_pdfs/show.html',
disposition: 'inline',
page_size: 'A4',
show_as_html: params.key?('debug')
end
end
end
適当にview作成
h1.title style="text-align: center; font-size: 100px;" wicked
p.date style="text-align: center; font-size: 50px;" = "#{l(DateTime.current)}"
table style="text-align: left; margin: auto; font-size: 50px;"
thead
tr
th 名前
th 年齢
th 性別
th 住所
tbody
tr
td 井上
td 22
td 男
td xxxx xxxx xxxx
div style="height: 500px; width: 500px; border: solid 1px red;"
出力
styleを直書きしているが、もちろんcssファイルを別にすることは可能
また画像を貼り付けたりも可能
ただし、imageタグやlinkタグなどをwicked_pdf独自のタグに書き換えなければならない
# js
wicked_pdf_javascript_include_tag "filename"
# css
wicked_pdf_stylesheet_link_tag "filename"
# image
wicked_pdf_image_tag 'filename'
正直これがかなりめんどくさい。
app/assetsの中しか読めないので、cssとかjsをassets:precompile
とかして出力したのをassetsで読んでいる場合はかなりめんどくさい
prawn
prawn
とprawn-table
をインストールする
prawn-table
は表組みの作成に必要
gem 'prawn'
gem 'prawn-table'
app以下にprawnディレクトリを作成してその中にpdf出力用のクラスを作る
class SamplePdf < Prawn::Document
def initialize
super()
# 座標を表示
stroke_axis
end
end
適当にルーティングきって適当にcontroller作って適当にviwe作成
def prawn
respond_to do |format|
format.html
format.pdf do
# PDF文書を作成
pdf = SamplePdf.new
# 画面にPDFを表示する
# disposition: "inline" によりPDFはダウンロードではなく画面に表示される
send_data pdf.render,
filename: "sample.pdf",
type: "application/pdf",
disposition: "inline"
end
end
end
座標が表示されたpdf出力される
履歴書っぽい雛形を作ってみる
class SamplePdf < Prawn::Document
def initialize
super()
# 座標を表示
stroke_axis
font 'app/assets/fonts/ipaexm.ttf'
move_down 10
create_title
create_profile
create_address
end
def create_title
table([
[
make_cell(content: '履歴書', width: 200, align: :left, size: 25),
make_cell(content: I18n.l(Date.current, format: :long), width: 200, align: :right, size: 10, valign: :bottom)
]
], width:400) do
row(0).borders = []
end
end
def create_profile
subtable = make_table([
[
make_cell(content: '生年月日', width: 70),
make_cell(content: 'xxxx年 x月 xx日', width: 200, align: :center),
make_cell(content: '性別', width: 50, align: :center),
make_cell(content: '男', width: 80, align: :center)
]
], width: 400)
kana_box = [
make_cell(content: 'かな', width: 50),
make_cell(content: 'xx xxxx', width: 350, align: :center)
]
name_box = [
make_cell(content: '氏名', width: 50),
make_cell(content: 'xx xxx', width: 350, height: 40, align: :center, valign: :center, size: 20)
]
data = [
kana_box,
name_box,
[{ content: subtable, colspan: 2 }]
]
table(data, position: :left, width: 400) do
row(0).column(0).borders = [:top, :left]
row(0).column(1).borders = [:right, :top]
row(1).column(0).borders = [:top, :left]
row(1).column(1).borders = [:top, :right]
row(2).column(0).borders = [:top, :left, :right]
row(1).border_lines = [:dashed, :solid, :solid, :solid]
end
end
def create_address
address_kana_box = [
make_cell(content: 'かな', width: 50),
make_cell(content: 'とうきょうとなかのくやよいちょう', width: 450, align: :center)
]
address_box = [
make_cell(content: '現住所', width: 50),
make_cell(content: 'xxxxxxxxxxxxxxxxxx', width: 450, align: :center, size: 15)
]
table([
address_kana_box,
address_box
], width: 500) do
row(0).column(0).borders = [:top, :left]
row(0).column(1).borders = [:right, :top]
row(1).column(0).borders = [:top, :left, :bottom]
row(1).column(1).borders = [:top, :right, :bottom]
row(1).border_lines = [:dashed, :solid, :solid, :solid]
end
end
end
結果
途中までだけど履歴書っぽい
比べてみて
wickedはレンダリングされたhtmlをそのままpdfにできるので通常ならこっちの方が柔軟にpdfを作成できそう
prawnはコードは長くなるが、表や画像, テキストなどを任意の座標に置けるので、履歴書などフォーマットの決まったものなら、こっちでも十分作れそう
おまけ
募集
最後になりますが、PORT株式会社では自社サービスを支えてくれる優秀なエンジニアを募集しています。
ぜひprawnで履歴書を作成して応募いただけると幸いです。
話を聞いてみたい、会社を見てみたいといった方は弊社で開催している勉強会にお越しいただけるとイメージが湧きやすいと思いますので、そちらもぜひよろしくお願いします。
もくもく会ページ
https://freestyle-mokumoku.connpass.com/
酒がないとページ
https://sakeganaito.connpass.com/