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
- items
- detail
- item
今回のお題として簡単な帳票(collection_list.tlf)を作成しました。
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が作成できました。
コーディングだけでなくドキュメント作成等にも応用できると思います。
(ドキュメント作成は標準装備されてます)
テンプレート処理は面白いです。