axlsx (gem) で xlsx ファイルをダウンロード
axlsx v1.3.4
いい加減そろそろ Excel2003 形式 (.xls) で出力し続ける理由がなくなってきてしまったので(^_^;、ようやく重い腰をあげて Excel2007 形式 (.xlsx) で出力に移行することにしました。使えそうなライブラリはないかと gem を探してみました。とりあえず目についた以下の3つをさわってみました。
3つを試してみた印象
roo は xls と xlsx の両対応という触れ込みで、No.1候補か!?と思ったんですが、xls部は spreadsheet に丸投げのようで、xls部とxlsx部とで書き方の作法がまるで違って、別々のものを使っても大して変わらない… さらに独自に作成されたxlsx部は、cell, row, column といったクラスがなく常に番地(行番号・列番号)でアクセスするという具合で、なんかかっちょ悪い感じがしました。(使用者の感想です)
他の2つ、acts_as_xlsx と axlsx は同じ作者によるライブラリのようで rails で使うなら acts_to_xlsx がおすすめと書いてありました。たとえば
Posts.where(created_at > Time.now-30.days).to_xlsx
みたいに、モデルからfindした結果をそのまま xlsx 化する場合には便利なようです。
ただ今回の自分の用途としては、表のヘッダー(表頭・表側)に色をつけたり複数のセルの結合 (merge) をしたりしたかったので axlsx でいくことにしました。
※ グラフを書いたりピボットテーブルを作ったりといったこともできるみたいです。
axlsx で xlsx ファイルを書き出す
基本的な使い方は、
- 新しいpackageを作り
- packageの中のworkbookに新しいworksheetを追加
- worksheetに1行ずつ追加
- package.to_stream.readで得られるデータをsend_dataで書き出す
といった感じです。
pkg = Axlsx::Package.new pkg.workbook do |wb| wb.add_worksheet(:name => 'シート名') do |ws| # シート名の指定は省略可 ws.add_row ['a', 1] ws.add_row ['b', 2] end end send_data(pkg.to_stream.read, :type => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", :filename => "test.xlsx")
実際にダウンロードさせる際にはMIMEタイプの設定(config/initializers/mime_types.rb)も必要ですので忘れずに。
Mime::Type.register 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', :xlsx
もうちょっと細かく出力データを調整する
書式を指定する
書式の指定は、シート毎に add_style でスタイルを登録して、add_row する際に登録したスタイルを一緒に指定します。追加する行まとめて1つの書式を指定することもできますし、配列で1セルずつ指定してセル毎に書式を変えることも可能です。書式を指定しないか nil を指定するとデフォルトの書式になります。
my_style = ws.styles.add_style :fg_color=> "FF00000", :bg_color => "FFF0E6BE", :b => true, :sz => 14, :border => {:style => :thin, :color => "FF333333"}, :alignment => {:horizontal => :center, :vertical => :center} # 1行まとめて書式設定 ws.add_row ['a', 'b', 'c'], :style => my_style # セルごとに書式設定 ws.add_row ['d', 'e', 'f'], :style => [my_style, nil, nil]
色の指定について
色は16進数でのRGB表示の頭に "FF" をつけて指定する。赤(#FF0000) ⇒ "FFFF0000"、黒: #000000 ⇒ "FF000000" といった具合。ちなみにRGBの各値が同じ場合は2桁の数字で省略できる。
my_style = ws.styles.add_style :fg_color=> "FF000000", :border => {:style => :thin, :color => "33"} # "FF333333"と同じ
0パディングを維持する(セルの型を設定する)
セルの型は何も指定しないとデフォルトで Excel の「標準」型になります。基本的にはデータの値にあわせて自動的に型を判別してくれます。
date_format = ws.styles.add_style :format_code => 'YYYY-MM-DD' time_format = ws.styles.add_style :format_code => 'hh:mm:ss' ws.add_row ["Date", "Time", "String", "Boolean", "Float", "Integer"] ws.add_row [Date.today, Time.now, "value", true, 0.1, 1], :style => [date_format, time_format]
ただし、"0016" など0でパディングされた数字列は数字として解釈されてしまい、そのまま add_row すると 16 となってしまいます。そんなときは add_row をするときに types を一緒に設定すればOKです。
ws.add_row ['0016'] # ws.rows.last.cells[0].value = 16 ws.add_row ['0016'], types => [:string] # ws.rows.last.cells[0].value = "0016"
types は styles とは別に指定します。
date_format = ws.styles.add_style :format_code => 'YYYY-MM-DD' ws.add_row ['2013/03/20'], styles => date_format, types => :date
型として使用できる値は :date、:time、:float、:integer、:string、:boolean の6つです。