その他
    ホーム 技術発信 DoRuby Rubyでどう書く?:RubyでPDF履歴書を作成する

    Rubyでどう書く?:RubyでPDF履歴書を作成する

    この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

    KBMJがZDnetで連載している記事を紹介します。コメントなどありましたらそちらでお願いします。

    Rubyでどう書く?:RubyでPDF履歴書を作成する   高倉利明(KBMJ)

    第2回目のテーマは「RubyでPDF文書を作成する」と題しまして、RubyでPDFの文書を作成する方法について解説したいと思います。

     問題

     Webアプリケーションを開発していると、「PDF文書を作成してほしい」との要望をクライアントから頂くことがあります。しかし、Rubyの実際のサービスでPDFを出力しているものはあまりありませんでした。

     ここでは以前、私が行った開発を元にノウハウを紹介したいと思います。

    仕様

    • Ruby on Railsを使用(実際に必要になるケースはRoRプロジェクトがほとんどと考えました)
    • Rfpdfプラグインを使用(インストール方法はRoR Wiki 翻訳 Wiki – Rfpdfを参照)
    • 出力するフォーマットは図1のイメージ

    図1 イメージ画像 図1 イメージ画像

    回答例

    class Resume

      class << self
        # PDF出力メソッド
        def output
          pdf = Pdf.new(“高倉 利明”, “タカクラ トシアキ”)
          file = File.open(“C:\\resume.pdf”, “wb”)
          file.write(pdf.generate)
        end
      end

      # pdf作成クラス
      class Pdf

        IC_SJIS = Iconv.new(‘SJIS’, ‘UTF-8’)

        def initialize(name, kana)
          # 出力データ
          @name, @kana = name, kana
          # マージン
          @lm, @tm = 10, 10
          # 基本となる罫線の横、縦サイズ
          @width, @height = 120, 20

          @pdf = FPDF.new
          @pdf.extend(PDF_Japanese)
          @pdf.AddSJISFont
        end

        # PDF(バイナリデータ)を作成
        def generate
          @pdf.SetMargins(@lm, @tm)
          @pdf.AddPage
          drow_format(@lm, @tm)
          drow_data(@lm, @tm)
          return @pdf.Output
        end

        # フォーマット描画
        def drow_format(left, top)
          @pdf.SetXY(left, top)
          setBoldLine
          @pdf.Cell(@width, @height, ”, 1)
          @pdf.SetXY(left, top)
          setThinLine

          # 氏名(フリガナ)欄
          @pdf.SetXY(left, top)
          @pdf.SetFont(‘SJIS’,”, 8)
          @pdf.Cell(20, 5, ic(‘フリガナ ’), ‘B’, 0)
          @pdf.Cell(@width – 20, 5, ”, ‘B’, 1)

          # 氏名欄
          y = @pdf.GetY
          setBoldLine
          @pdf.Cell(@width, 15, ”, ‘B’, 0)
          @pdf.SetXY(left, y)
          @pdf.SetFont(‘SJIS’,”, 8)
          @pdf.Cell(20, 5, ic(‘氏名 ’), 0, 2)
          @pdf.Cell(20, 10, ”, 0, 0)
          @pdf.SetXY(left + 20, y)
          @pdf.Cell(@width – 20, 15, ”, 0, 1)
        end

        # データ描画
        def drow_data(left, top)
          @pdf.SetXY(left, top)
          write_string(left + 25, top + 3, 10, @kana)
          write_string(left + 25, top + 13, 14, @name)
        end

        def write_string(left, top, font_size, string)
          @pdf.SetXY(left, top)
          @pdf.SetFont(‘SJIS’,”, font_size)
          @pdf.Write(0, ic(string))
        end

        def setBoldLine
          @pdf.SetLineWidth(0.3)
        end

        def setThinLine
          @pdf.SetLineWidth(0.1)
        end

        def ic(str)
          IC_SJIS.iconv(str)
        end

      end
    end

     本ソースをresume.rbとしてRoRプロジェクトののmodelディレクトリに配置し、以下のコマンドを実行することで「C:\resume.pdf」で出力されます。ruby script/runner Resume.output

    解説

    本サンプルでは、

    1. マージン、枠の縦横サイズの初期化「initialize」「generate」
    2. 罫線などのフォーマットを描画「drow_format」
    3. 各項目の値を描画「drow_data」

     というステップにわけて処理をしています。

     RFPDFライブラリを使用する場合は、

    1. FPDF.newでオブジェクト生成
    2. 日本語が扱えるようにextendやAddSJISFontメソッドで指定
    3. AddPageメソッドでページを追加
    4. ページに表示する内容を描画
      • 座標:SetXY、SetX、SetY、GetX、GetYなどを利用
      • 文字フォント:SetFontで指定
      • 罫線サイズ:SetLineWidthで指定
      • 罫線:Cellメソッドで描画(第三引数に文字列を指定することで、同時に文字の描画も可能)
      • 文字:Writeメソッドで描画
    5. Outputメソッドでバイナリを出力

     という流れとなります。

     日本語を出力する際は、Iconvを使用してSJISに変換しています(ソースをUTF8で書いているため)。

     なお、RFPDFの詳しい使用方法は、FPDFのWebサイト「FPDF」を参考にしてください。

    最後に──

     駆け足で説明しましたが、いかがだったでしょうか?

     実際のところ、RFPDFは1年近く更新されておらず、また日本語を扱う上でまだバグが見られるのが現状です。

     また、罫線などの枠線をプログラムで引いている関係上、直観的ではない作りになってしまうのが欠点です。

     もっと良い方法があれば、コメント (コメントはこちら)やbuilderブログなどで是非教えていただきたいと思います。