matsuok’s diary

あくまでも個人的意見であり感想です

Ruby PDFを作成

Prawnを使ってPDFを作成

導入

gemでインストールし、requireするだけです。
帳票レイアウトを決める
帳票のサイズや向き、上下左右の余白はコンストラクタで指定します。

  Prawn::Document.new(:page_size => 'A4',
                      :page_layout => :portrait,
                      :top_margin => 40,
                      :bottom_margin => 30,
                      :left_margin => 20,
                      :right_margin => 10)

という書き方をします。

generate()はオブジェクトの生成と、指定したファイルパスへの保存を行います。
オプションの説明:
:page_size 帳票のサイズです。'A4'、'B5'といった規格の他、[100, 200]という指定もできます。[横, 縦]、単位はポイント(pt)です。
:page_layout 帳票の向きを縦 or 横で指定します。縦 = :portrait、横 = :landscape です。
:top_margin 上余白をptで指定します。
:bottom_margin 下余白をptで指定します。
:left_margin 左余白をptで指定します。
:right_margin 右余白をptで指定します。

帳票のレイアウトを決めたら、文字や線を描いていきます。

それらの処理は以下のようにblockで渡す形で書きます。

Prawn::Document.new(...) do |pdf|
	    pdf.foo ...
  end

座標を把握する

PrawnではX座標、Y座標をptで指定して、文字や線の出力位置を決めます。
Xの値は、印刷領域の左端が起点です。
印刷領域の右端は、
pdf.bounds.right
で取得できます。
Yの値は、印刷領域の下端が起点です。
印刷領域の上端は、
pdf.bounds.top
で取得できます。

うーん、面倒。

書式指定などユーテリテイはないのか…

ありました!

Thinreports PDF 形式の帳票を生成する Ruby 向けオープンソースソフトウェア

Thinreports は PDF 形式の帳票を生成する Ruby 向けのオープンソースソフトウェアです。 専用のレポートデザイナ Thinreports Editor と PDF ジェネレータ Thinreports Generator によって RubyRuby on Rails を使った帳票開発の負担を軽減 - thin - することを目指します。
http://www.thinreports.org/

Thinreports Editor は Thinreports で扱う帳票レイアウトを編集する専用のGUIツールです。 Editor を使うことによって、マウスやキーボードによる直感的な操作で業務システムで求められるような、 複雑な帳票レイアウトも簡単に作成することが可能です。 MacUbuntu(linux) 及び Windows プラットフォームをサポートしています。

Thinreports Generator は Thinreports Editor で作成したレイアウトを読み込み PDF データを生成する RubyGems です。 動的データの埋め込みやスタイルの操作などを Ruby コードで実装することができます。

必要なライブラリ
Thinreports Generator をインストールするにはいくつかのライブラリが必要です。 インストールを始める前にインストール先の環境に以下のライブラリがあることを確認して下さい。

Ruby or JRuby
RubyGems

Bundler でインストールする

gem 管理ツール Bundler を使ってインストールする場合は、まず Bundler をインストールします。
$ gem install bundler
そして、インストール gem を記述する Gemfile に以下のように追記します。
gem 'thinreports'
最後に、以下のコマンドでインストールを実行すれば完了です。
$ bundle install

RubyGems でインストールする

RubyGems でインストールする場合は、ターミナル上で以下のコマンドを実行すれば完了です。
$ gem install thinreports
アップデートする
$ gem update thinreports


リリースページ より、お使いの OS にあったを最新の Editor をダウンロードします。ダウンロードした zip ファイルを展開し、作成されたフォルダを任意の場所に配置してください。フォルダ内の実行ファイルを実行すると Editor が起動します。
アンインストール
フォルダごと削除してください。

Thinreports Editor0.10.0 以降インストール

https://github.com/thinreports/thinreports-editor#supported-platforms

Supported Platforms

Requirements

なお、下記は、MacOS 10.15.5,ruby 2.6.6で実行しました

# coding: utf-8
require 'thinreports'
# require 'bundler'
# Bundler.require
require "date"
require 'sqlite3' # sqlite3読み込み
puts "$0:#{$0}"
begin
  db = SQLite3::Database.new 'health.db'
rescue SQLite3::SQLException => e
  puts "open database return: "
  puts "#{e}\n"
end

report = Thinreports::Report.new layout: 'health_list.tlf'

table_name = "vwalking"
sql = "select wdate,walkingdistance,avgtemp,Weatherreport from vwalking;"
begin
  n = 0
  db.execute(sql) do |r|
    # Internaly #start_new_page() method is called,
    # the page break automatically.
    #
    # [NOTE] In thinreports < 0.7.5:
    #   report.page.list(:default).add_row do |row|
    #     :
    report.list.add_row do |row|
      row.item(:detail).value("#{r[0]}  #{r[1].round(3)}km, #{r[2].round(3)}")
      row.item(:weather).value(" | #{r[3]}")
    end
  end
rescue SQLite3::SQLException => e
  puts "#{sql} database return:}"
  puts "#{e}\n"
end
sql = "select count(wdate), max(wdate), min(wdate),avg(walkingdistance),avg(avgtemp),max(avgtemp),min(avgtemp) from vwalking;"
cnt = 0
fromdate = ""
todate = ""
avgdis = 0.0
avgtemp = 0.0
max = 0.0
min = 0.0
begin
  db.execute(sql) do |row|
    cnt = row[0]
    todate = row[1]
    fromdate = row[2]
    avgdis = row[3]
    avgtemp = row[4]
    max = row[5]
    min = row[6]
  end
rescue SQLite3::SQLException => e
  puts "#{sql} database return:}"
  puts "#{e}\n"
end
puts "record:#{cnt.to_s} #{sql} return\n}"
db.close
puts "database close return\n}"
puts 'start:' + fromdate + ' to:' + todate + "\n"
total_msg = "合計件数:#{cnt} 平均距離(km):#{avgdis.round(3)} 平均気温(℃):#{avgtemp.round(3)} MAX平均気温(℃):#{max.round(3)} MIN平均気温(℃):#{min.round(3)}\n"
puts total_msg
report.list.add_row do |row|
  row.item(:detail).value("合計件数:#{cnt} 平均距離(km):#{avgdis.round(3)} ")
  row.item(:weather).value("平均気温(℃):#{avgtemp.round(3)}")
end
report.list.add_row do |row|
  row.item(:detail).value("    :MAX平均気温(℃):#{max.round(3)}")
  row.item(:weather).value(":MIN平均気温(℃):#{min.round(3)}")
end

# [NOTE] In thinreports < 0.7.7:
#   report.generate_file 'basic_list.pdf'
report.generate filename: 'healthresult.pdf'

Thinreports Editor
Thinreports で扱う帳票レイアウト
Thinreports Editor
出力PDF 最終ページ
PDF 最終ページ