Ruby
Rails
PDF
prawn

Rails prawnを使ってPDFを作成する

はじめに

RailsアプリケーションでPDFを作成する僕の中のノウハウを軽くですが公開します。
Webから帳票を作成する機能って案外需要あると思うんですよねー。
特に業務系のアプリケーションでは必須と言っても過言ではないのではないでしょうか?

その割にはあまり情報が転がっていないのが現状です...

今回は、prawnの導入方法と、
これくらい扱えたら割と形にできる?というサンプルを紹介しようと思います。

プローンて読むらしいですよ?エビですって。
シュリンプはエビの総称、プローンは中形のエビらしいです。どうでもいいです。

prawnの導入

gem

Gemfileに以下の2つを追加します。

Gemfile
gem 'prawn'
gem 'prawn-table'

prawn-tableはテーブルの描画に必要なgemです。

日本語フォント

当たり前なのですが日本語フォントを使用しないと日本語の描画でエラーが出ます。
こちらからダウンロードして適当なフォルダに置いてください。
https://ipafont.ipa.go.jp/

controller

/test.pdfにアクセスするとPDFが画面に表示されるようにします。

test_contoroller.rb
class TestController < ApplicationController
  def index
    respond_to do |format|
      format.pdf do
        test_pdf = TestPdf.new.render
        send_data test_pdf,
          filename:    'test.pdf',
          type:        'application/pdf',
          disposition: 'inline' # 画面に表示
      end
    end
  end
end

ちなみにdisposition: 'inline'を消したらダウンロードになります。

class

Prawn::Documentを継承したクラスを作成します。
ここにPDFに描画する内容をガンガン書いていきます。
とりあえず手始めにPDFの座標を表示するstroke_axisだけ書いておきます。

test_pdf.rb
class TestPdf < Prawn::Document
  def initialize
    super()
    # 座標を表示
    stroke_axis
  end
end

出力

/test.pdfにアクセスするとこんなPDFができます。
test.jpg
なんかそれっぽいですね。

サンプル

準備が整ったところで、サンプルです。

test_pdf.rb
class TestPdf < Prawn::Document
  def initialize
    super()

    # 日本語フォントを使用しないと日本語使えません
    font_families.update('Test' => { normal: 'vendor/fonts/ipaexm.ttf', bold: 'vendor/fonts/ipaexg.ttf' })
    font 'Test'

    # 座標を表示
    stroke_axis

    # 単純なテキストの表示
    text 'Hello Prawn'

    # 単純なテーブルの表示
    # テーブルの要素は2次元配列で定義する
    rows = [
      ['1-1', '1-2'],
      ['2-1', '2-2'],
      ['3-1', '3-2']
    ]
    table rows

    # 下に20
    move_down 20

    # 複雑なテーブルの表示
    rows = [
      [{ content: '1×2の横長', colspan: 2 }, '1-3'],
      [{ content: '2×1の縦長', rowspan: 2 }, '2-2', '2-3'],
      ['3-2', '3-4'],
      [{ content: '2×2のワガママ', colspan: 2, rowspan: 2 }, '4-3'],
      ['5-3']
    ]
    # セルの高さ30、左上詰め詰め
    table rows, cell_style: { height: 50, width: 200, padding: 0 } do
      # 枠線なし
      cells.borders = []
      # 文字サイズ
      cells.size = 20
      # 枠線左と上だけ
      cells.borders = %i[left top]
      # 1行目はセンター寄せ
      row(0).align = :center
      # 1行目の背景色をff7500に
      row(0).background_color = 'ff7500'
      # 1列目の横幅を30に
      columns(0).width = 100
      # 行列の最終の文字を小さく
      columns(-1).row(-1).size = 5
      # 行列の枠は四方固める
      columns(-1).row(-1).borders = %i[top bottom left right]
      # 行列の枠線は点線で
      columns(-1).row(-1).border_lines = %i[dotted]
    end

    # 第一引数の座標にボックスを作る
    bounding_box([100, 350], width: 200, height: 100) do
      # 周りに枠線をつける
      transparent(1) { stroke_bounds }
      font_size 16
      text '太文字', style: :bold
      text 'このボックスの使い勝手はかなりいい'
    end

    # 座標を指定して画像を表示する
    image 'app/assets/images/me.jpg', at: [10, 200], width: 100
    image 'app/assets/images/pote.jpg', at: [150, 200], width: 150

    # 座標を指定してテキストを表示する
    draw_text 'ネコと和解せよ', at: [160, 50], size: 30
  end
end

こんな出力になります。
test (11).jpg

終わりに

PDF作成なんてクソムズイやろ!!と思っていましたが、思ったより簡単にできますね。
画面サイズなど気にしなくていいので結構とっつきやすかったです。

もっと細かい扱い方は公式マニュアルで確認してください!
http://prawnpdf.org/manual.pdf
http://prawnpdf.org/prawn-table-manual.pdf

ブログでみたい方はこちら
Rails prawnを使ってPDFを作成する