フォームに名前を入力するとPDF化された印鑑を出力するアプリを作ろう②（PrawnによるPDFファイルのカスタム）

# 初めに
この記事は`フォームに名前を入力するとPDF化された印鑑を出力するアプリを作ろう`の後半です。
[フォームに名前を入力するとPDF化された印鑑を出力するアプリを作ろう①（Ruby on RailsでPDFファイルを作成）](https://qiita.com/eityamo/items/ff327fec918d882e25f6)

前回まででPDFファイルを出力するところまで実装できました。今回はPrawnのGemによる基本的なカスタム方法について説明していきます。

# PrawnによるPDFのカスタム
Prawnの基本機能は`Text`、`Graphics`、`Bounding Box`の3つです。
それぞれについて説明しながら印鑑を実装していきます。

実装する準備としてPDFに座標を表示します。

```ruby:stamp_pdf.rb
class StampPdf < Prawn::Document
  def initialize(user)
    super(page_size: 'A4')
    # 座標を表示
    stroke_axis
    # font指定
    font "app/assets/fonts/SourceHanSans-Bold.ttc"
  end
end
```

**PDF画面**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520341/a9e9b110-4d6a-d45f-846a-db166c8befca.png)

## Text

早速、`Text`を使っていきます。
このPDFのタイトルを中央揃えで表示させます。

```ruby:stamp_pdf.rb
class StampPdf < Prawn::Document
  def initialize(user)
    super(page_size: 'A4')
    # 座標を表示
    stroke_axis
    # font指定
    font "app/assets/fonts/SourceHanSans-Bold.ttc"
    # タイトル（追記箇所）
    text_box "印鑑のPDF化", at: [0, 700], align: :center, size: 20
  end
end
```

座標`[x, y] = [(0と最大値（A4の場合523）の中央値), 700]`にフォントサイズ`20`の印鑑のPDF化という文字が表示されます。

**PDF画面**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520341/ab9bc7f0-ab4e-f9cd-35a7-aadf0150d806.png)

## Graphics

次に`Graphics`を使っていきます。
印鑑の外枠部分を表示させます。

```ruby:stamp_pdf.rb
class StampPdf < Prawn::Document
  def initialize(user)
    super(page_size: 'A4')
    # 座標を表示
    stroke_axis
    # font指定
    font "app/assets/fonts/SourceHanSans-Bold.ttc"
    # タイトル
    text_box "印鑑のPDF化", at: [0, 700], align: :center, size: 20
    # 図形の色（追記箇所）
    stroke_color 'ce3337'
    # 円（追記箇所）
    stroke_circle [260, 550], 50
  end
end
```

円の中心座標`[x, y] = [260, 600]`に半径`50`、輪郭の色が`ce3337`の円が表示されます。

**PDF画面**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520341/d76bdaa8-55c4-620a-ce7c-1cb9dc2bfdf1.png)

## Bounding Box

最後に`Bounding Box`を使っていきます。
一旦、円を消して`Box化`を可視化してみます。

```ruby:stamp_pdf.rb
class StampPdf < Prawn::Document
  def initialize(user)
    super(page_size: 'A4')
    # 座標を表示
    stroke_axis
    # font指定
    font "app/assets/fonts/SourceHanSans-Bold.ttc"
    # タイトル
    text_box "印鑑のPDF化", at: [0, 700], align: :center, size: 20
    # 図形の色
    stroke_color 'ce3337'
    # 円
    # stroke_circle [260, 550], 50
    # Bounding Boxのブロック（追記箇所）
    bounding_box([235, 600], width: 50, height: 100) do
      # boxの描画
      stroke_bounds
    end
  end
end
```

座標`[x, y] = [235, 600]`の右下に横`50`、縦`100`の`Bounding Box`が表示されます。
`Bounding Box`は描画範囲を指定することができるので、rubyのブロックと相性がいいです。

**PDF画面**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520341/dc083910-fa9d-6bc2-1a84-717e20ab62ee.png)

追記した`Bounding　Box`のブロック中に印鑑の輪郭と名前を入れてみます。

```ruby:stamp_pdf.rb
class StampPdf < Prawn::Document
  def initialize(user)
    super(page_size: 'A4')
    # 座標を表示
    stroke_axis
    # font指定
    font "app/assets/fonts/SourceHanSans-Bold.ttc"
    # タイトル
    text_box "印鑑のPDF化", at: [0, 700], align: :center, size: 20
    # 図形の色
    stroke_color 'ce3337'
    # テキストの色
    fill_color 'ce3337'
    # Bounding Boxのブロック
    bounding_box([235, 600], width: 50, height: 100) do
      # boxの描画
      stroke_bounds
      # 円（追記箇所）
      stroke_circle [25, 50], 50
      # テキスト（追記箇所）
      text_box "#{user.name}", at: [5, 90], size: 40
    end
  end
end
```

少しややこしいんですが、このブロック中の原点がわかれば簡単です。
原点は長方形ブロックの左下の頂点`[x, y] = [235, 500（600ー100）]`です。
ということで、描写される円の中心は`[x, y] = [260(235+25), 550(500+50)]`、半径`40`となり、
テキストは座標`[x, y] = [240(235+5), 590(500+90)]`の右下へフォント`40`の文字が表示されます。
＊テキストは右上から左下に表示され、デフォルトでブロックの幅を超えると改行する仕様です。この性質を使って縦書きを表現しています。

**PDF画面**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520341/fda62007-612e-049b-9de1-1870c22409d8.png)

最後に座標とブロックの描写を取り除き、コンポーネント化して完成！！！

```ruby:stamp_pdf.rb
class StampPdf < Prawn::Document
  # userにモデルなどのデータを渡します
  def initialize(user)
    # superで初期設定を指定 新規PDF作成
    super(page_size: 'A4')

    # 座標を表示
    # stroke_axis
    # font指定
    font "app/assets/fonts/SourceHanSans-Bold.ttc"
    # box化
    create_title
    create_stamp(user)
  end

  # タイトル
  def create_title
    text_box "俺の印鑑", at: [0, 700], align: :center, size: 20
  end

  # 印鑑
  def create_stamp(user)
    bounding_box([235, 600], width: 50, height: 100) do
      # boxの描画
      # stroke_bounds
      # 図形の色
      stroke_color 'ce3337'
      # 円
      stroke_circle [25, 50], 50
      # テキストの色
      fill_color 'ce3337'
      # テキスト
      text_box "#{user.name}", at: [5, 90], size: 40
    end
  end
end
```

**PDF画面**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520341/a809baa2-bc32-c3ab-13ad-2ce2f175ae4d.png)

今回は印鑑実装で図形を扱うので`Prawn`というGemを用いてPDF化をしましたが、`wicked_pdf`などのGemもあります。これから用途に合わせて使っていきたいです。最後まで読んでいただきありがとうございます。

## 参考文献
- [Github PrawnPDF](https://github.com/prawnpdf)
- [manual](https://prawnpdf.org/manual.pdf)