やりたかったこと
スコープ(ActiveRecord::Relation)やActiveRecordインスタンスの配列を、Excel(スプレッドシート)に出力するっていう処理は、管理画面まわりではちょいちょい必要になりますよね。それを簡単に済ませたいと思ってgemを作ってみました。
Spreadsheetable 使い方
githubのREADMEに書いたあっさり説明で分かると思うのですが、こんな感じで使います。
Gemfile
gem 'spreadsheetable'
> bundle
# スコープかactive_recordの配列に使えます
scope = AModel.all
# 1. 拡張して
scope.extend Spreadsheetable
# 2. Excelに出力したいプロパティを指定して
scope.sheet_columns = %w(id name other parent_model.name)
# 3. xlsかto_spreadsheetでTempfileに保存されます。あらヤダ簡単
xls_file = scope.xls
- 出力列はparent_model.name のような指定もできますが、改善の余地あり(後述)
- ヘッダ行はI18n対応しています
検索条件に応じたExcelファイルを出力するアクションも、こんな感じでOKです。(諸々目を瞑れば)
hoges_controller.rb
# 極簡単に済ませれば
def easy_xls
result = Model.where(params).extend(Spreadsheetable)
result.sheet_columns = %w(id name other)
send_download_file result.xls, "easy.xls"
end
# 現実的にはこんな感じかな
def search
@result = Model.where(params.slice(:property_a, :property_b))
respond_to do |format|
format.html
format.xls{
@result.extend(Spreadsheetable)
@result.sheet_columns = %w(id name other)
send_download_file(@result.xls, "search_result.xls")
}
end
end
TODO
依存しているSpreadsheetが0.9系なのを差し置いてV1.0.0をリリースしていますが、以下のように直したいところがあります。 「こんなことも出来てないのか、しょうがねぇな。直してやるか」 ってな方いましたら、是非pull reqお願いしますー。
- 大量データ時の考慮として、スコープの時はfind_each使う。
- 列指定(#sheet_columns)に合わせて、スコープの時はselectしてあげる。
- 列指定(#sheet_columns)で parent_model.name のようにすると ParentModel があれば解決できるけど、classifyしているだけなのでfirstやクラス名と紐づかない名前だとダメ。これを直す。
- decoratorと連携したテストを書いてダメなら直す。