CSVファイルをダウンロード可能にする。
CSVサーバーは、管理部門の担当者がCSVファイルをアップロードすることで、path列に設定した権限のユーザーがweb上で閲覧可能になる。そうすると、閲覧しているユーザーから、すぐにこんな連絡が入りそう。「CSVファイルはダウンロードできないの?」と。
自然な要望ですね。おそらく閲覧しているユーザーは単に見るだけでなく、独自に情報を加工して分析もしたくなる。そんな時、データをCSVファイルとしてダウンロード出来れば、きっと嬉しいはず。
webの画面を見て手入力していたり、コピー&ペーストしていたり、というのはちょっと気の毒だ。そんなことにならないように、以下のようにやってみた。
ダウンロードリンクの追加
- ajax_scaffoldでCSVファイルの内容を表示するページの1行目に、「CSVファイルとしてダウンロード」というリンクを作成した。
- ダウンロードリンクをクリックすると、exportアクションが呼び出される。
- app/views/displays/component.rhtml
- ビュー
<% if @show_wrapper %> <div class="export"> <%= link_to 'CSVファイルとしてダウンロード', :action => 'export', :table => params[:table] %> </div> ...(以下省略)...
ダウンロード処理の実装
- exportアクションでは、カンマ区切りの文字列を作成して、それをsend_dataで処理することでファイルとしてダウンロード可能になる。
- app/controllers/displays_controller.rb
- コントローラー
class DisplaysController < ApplicationController ...(途中省略)... def export Display.with_scope(login_user) do csv_text = FasterCSV.generate do |csv| csv << Display.column_names Display.find(:all).each do |item| #csv << item.attributes.values #上記では、ハッシュは順序を持たないので問題あり。 csv << Display.column_names.map {|column| item.send(column)} end end send_data(csv_text, :type => 'text/csv', :filename => "download.csv") end end ...(途中省略)...
- Display.with_scope(login_user) doにより、自分が閲覧できる情報だけがダウンロードされる。login_userメソッドは、以下のように定義済み。
# 閲覧制限をかけるため、with_scopeのオプション設定を返す。 # 例:ログインユーザーが、営業1部1課を担当している場合、以下のようなハッシュを作成して返す。 # {:find => {:conditions => path LIKE '%/株式会社RAILS/営業1部/営業1課/%' OR path=''} def login_user sql = current_paths.inject("path=''") do |result, item| %{path LIKE '#{item}%' OR path LIKE "'#{item}%" OR path LIKE '"#{item}%' OR } + result end if session[:user].admin? {} else {:find => {:conditions => sql}} end end
解決しない問題
CSVライブラリが利用できない
いつの頃からか、ruby標準添付のCSVライブラリが利用できなくなってしまった。csv_text = CSV.generate do |csv|とやると、uninitialized constant CSVというエラーが...。require 'csv'を宣言しても結果は同じ。なぜだろう...。しかし、FasterCSVを利用しているので問題ないのだが、それにしても気になる。
ファイル名の文字化け
本当は、ダウンロードした時のファイル名にテーブル名を利用したいのだが、どうも日本語が交じると文字化けしてしまう...。具体的には以下のような文字化け。(config/environment.rbで、$KCODE = 'u' require 'jcode'の設定ありの環境)
_200704_利益管理表_csv → _200704_å©ç管ç表_csv
KconvやIconvを使ってエンコードを変換してみたが、日本語としては表示できなかった。仕方なく、"download.csv"というファイル名に固定した。でもやっぱり日本語ファイル名を使いたい...。解決策はあるのだろうか?
とりあえずは、ダウンロード可能になった。