LoginSignup
0
1

More than 1 year has passed since last update.

Thinreportsでの帳票作成をより手軽に

Last updated at Posted at 2021-09-11

rubyで手軽に帳票が作成できるThinreports

Thinreportsを使用した帳票作成ステップは以下の通りです。

  • Thinreports-editorでレイアウトファイルを作る
  • rubyで
    • レイアウトの各項目に値を設定
    • generateメソッドでPDFを出力

今回はレイアウトファイルの情報を利用して各項目への設定ロジックのひな型を作成します。

レイアウトファイル(.tlf)はJSON

Thinreports-Editorで作成されるレイアウトファイルはJSONなので、
情報を取り出してみます。

レイアウトファイルの構造(の雰囲気)は以下の通りです。

  • items
    • item
      • id
      • type "text-block"
    • item
      • id
      • type "list"
      • items
      • detail
        • items
          • item

今回のお題として簡単な帳票(collection_list.tlf)を作成しました。
collection_list.png

tlfから情報を取り出そう(1) text-block

可変テキストを設定するのはtype: text-block なので、このIDを取り出します。

require 'json'

@layout="collection_list.tlf"

File.open(@layout) do |j|
    tlf = JSON.load(j)

    @text_blocks = []

    tlf["items"].each do |item|
        if item["type"] == "text-block"
            @text_blocks.push item["id"]
        end
    end

    @text_blocks.each do |i|
        puts i
    end
end

実行してみます。

PS thinreports> ruby .\extract_text_block.rb
name
birthday

まずはベタなtext-blockのIDが取り出せました。

tlfから情報を取り出そう(2) listのtext-block

次にリストの中のtype: text-block を取り出します。
リストの項目は取り扱いを変えたいので別の配列に格納します。

require 'json'
@layout="collection_list.tlf"

File.open(@layout) do |j|
    tlf = JSON.load(j)

    @text_blocks = []
    @list_text_blocks = []

    tlf["items"].each do |item|

        if item["type"] == "text-block"
            @text_blocks.push item["id"]
        end

        if item["type"] == "list"
            item["detail"]["items"].each do |l_item|
                if l_item["type"] == "text-block"
                  @list_text_blocks.push l_item["id"]
                end
            end
        end

    end

    @text_blocks.each do |i|
        puts i
    end

    @list_text_blocks.each do |i|
        puts i
    end
end
PS thinreports> ruby .\extract_text_block.rb
name
birthday
item_name
date
shop

リストの中のtext-blockもOKです。

erbでrubyソース生成

ではソース生成に参りましょう。
erbを作成します。

リスト内のtext-blockはCSVを読み込んで値を設定するように組みました。

require 'thinreports'
require 'csv'

Thinreports::Report.generate filename: 'result.pdf', layout: '<%= @layout %>' do

  start_new_page

% @text_blocks.each do |item|
  page.item(:<%= "#{item}" %>).value = ""
% end

  CSV.foreach("data.csv") do |csv_row|
    page.list.add_row do |row|
%   @list_text_blocks.each_with_index do |l_item,i|
      row.item(:<%= "#{l_item}" %>).value = csv_row[<%= "#{i}" %>]
%   end
    end
  end
end

rubyにはerbでの生成ロジックを追加

require 'json'
require 'erb'

@layout="collection_list.tlf"

# 省略

erb = ERB.new(IO.read("./extract_text_block.erb"), nil, "%" )
File.open("./src.rb", "w" ) { |f|
  f.write( erb.result(binding) )
}

実行するとこんなソースが生成されました。

require 'thinreports'
require 'csv'

Thinreports::Report.generate filename: 'result.pdf', layout: 'collection_list.tlf' do

  start_new_page

  page.item(:name).value = ""
  page.item(:birthday).value = ""

  CSV.foreach("data.csv") do |csv_row|
    page.list.add_row do |row|
      row.item(:item_name).value = csv_row[0]
      row.item(:shop).value = csv_row[1]
      row.item(:date).value = csv_row[2]
    end
  end
end

さあ、PDFの時間だ

データとなるdata.csvを用意して(ヘッダは要りません)

アイテム ショップ 日付
タイタン ○○屋 197X
スパイマジシャン △△屋 197X
コマンド □屋 197X

src.rbを実行すると・・・!

pdf.png

一部設定してないところもありますが、簡単にPDFが作成できました。
コーディングだけでなくドキュメント作成等にも応用できると思います。
(ドキュメント作成は標準装備されてます)

テンプレート処理は面白いです。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1