からくりがてんこ

IT関連情報、プログラミングに関する作業ログや備忘録を記載していきます。

Rails:ダウンロードTSVファイルに複数行のCopyrightヘッダをつける!

"ExportFile"みたいなボタンを押下したらDB取得結果をTSV形式でウンロードできる機能を作ることになった。(複数行のファイルヘッダ付き)

2段階の手順で考える

  • TSVファイルのダウンロードを実現
  • 複数行のCopyrightをつける

TSVファイルのダウンロード

DBの結果をTSVファイルにしてダウンロードしたい!
調べてみると、CSVファイルダウンロードのセパレータをタブにするという対応がベストのようですね。

# CSVクラスのセパレータをタブに設定
def tsv_download
    entities = Model.all

    tsv_data = CSV.generate(:col_sep => "\t") do |tsv|
        columns = %W(ID NAME TEL MAIL)
       tsv << columns  #行頭にカラム名を追加
       entities.each do |model|
            tsv << model.values
        end
    end
    send_data tsv_data, type: 'text/tsv; charset=utf-8', filename: “tmpfile.tsv"
end

ポイントはCSV.generate(:col_sep => "\t")ですね。tsv_dataが結果で、send_dataでレスポンスとして返してます。
これでタブ区切りのデータダウンロードを実現!

複数行のCopyrightをヘッダにつける

利用規約
このファイルは云々カンヌンで〜。。
だからして〜〜。。

のようなヘッダ情報をTSVファイルに付与することになった。
なので、これらの情報をヒアドキュメントで定数(TSV_HEADER)に格納し、
ファイルの先頭に挿入することにした。

CSV.generateには、:headersって素敵なオプションがあるじゃん!ってことで

CSV.generate(:col_sep => "\t”, :headers => [TSV_HEADER])

という風にしてみた。(配列でないとダメみたいだから[]で囲っている)
すると、なんということでしょう。

利用規約
ID NAME TEL MAIL
1 taro 00-0000-0000 taro@test.com
2 jiro 11-1111-1111 jiro@test.com

匠の粋な計らいにより、TSV_HEADERの一行目だけ出力しているではありませんか。
…じゃダメなんです。
改行コードとか見てるんだろうな〜と思い。このオプション断念。

あれ?CSV.generateの戻りって文字列じゃん!
なので、文字列をただ連結してしまいましたとさ。

# CSVクラスのセパレータをタブに設定
def tsv_download
    entities = Model.all

    tsv_data = CSV.generate(:col_sep => "\t") do |tsv|
        columns = %W(ID NAME TEL MAIL)
       tsv << columns  #行頭にカラム名を追加
       entities.each do |model|
            tsv << model.values
        end
    end
    # TSVヘッダ項目を追加する
    tsv_data = TSV_HEADER + tsv_data
    send_data tsv_data, type: 'text/tsv; charset=utf-8', filename: “tmpfile.tsv"
end

美しくないけど、いいや。
他にスマートなやり方ないかな〜。