Rails3 axlsx でxlsxファイルを作成しダウンロードする
前の記事で課題だった部分を別のライブラリ(axlsx)を使って解決。
ただし、axlsxはエクセルの読み込みはできないため、都度書式等を作成することになる。
axlsxの日本語での情報が少ないので、参考になればと。
作成したコードの一部抜粋・改変のため、コピペでは動くかは確認していません。
機能
・Rails でDBのデータをエクセルに帳票として出力
・ファイルはダウンロードできる
・エクセルはxlsx形式
・axlsxを利用
・スタイルの定義はモジュール化
- index.html.rb
# coding: utf-8 # remote => true にするとこのままだと、ファイル選択ダイアログが表示されない。 <%= form_tag(url_for(:controller => 'export', :action => 'download'), :remote => false) do %> <%= submit_tag('ダウンロード') %> <% end %>
- export_controller.rb
# coding: utf-8 class ExportController < ApplicationController require 'axlsx' include TableStyle def download package = Axlsx::Package.new # 横幅の自動調整無効 package.use_autowidth = false workbook = package.workbook # 印刷設定 # fit_to_width:次のページ数に合わせて印刷(横) # orientation:印刷の向き 横 # paper_size:紙の種類。数値はGitHub参照。9はA4 setup = {:fit_to_width => 1, :orientation => :landscape, :paper_size => 9} # ワークシートの追加(name:シート名、page_setup:ページ設定) worksheet = workbook.add_worksheet(:name => "Example01", :page_setup => setup) # 列の横幅 worksheet.column_widths(5, 5, 5, 15) # スタイルの定義(モジュール参照) cst = create_style(workbook) # 行の追加(関数も指定可) worksheet.add_row(["ABCD", nil, nil, "=SUM(D1:D2)"], :style => cst) # セル結合 worksheet.merge_cells("A1:C1") file_name = "example.xlsx" # ファイルデータのダウンロード send_data(package.to_stream.read, :type => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", :disposition => 'attachment', :filename => file_name) end end
- table_style.rb(lib/)
# coding:utf-8 module TableStyle def create_style(workbook) top_left = nil # 書式設定 # bg_color:背景色 # b:太字 # u:下線 # sz:文字サイズ # border:枠線 # edges:枠線を引く箇所。配列。複数指定化。(top,bottom,right,left) # style:線種(thin:実践, medium:太線, dashed:破線 etc・・・) # color:線の色。FFXXXXXX。 # alignment:文字配置。(horizontal:横位置, vertical:縦位置) base = {:bg_color => "FF98fb98", :u => true, :b => true, :sz => 11, :border => {:edges => [:bottom], :style => :thin, :color => "FF333333"}, :alignment => {:horizontal => :center, :vertical => :center}} workbook.styles do |worksheet| top_left = worksheet.add_style(base) # 上下左右で異なる枠線を引く場合(そういうケースが多いのに方法が複雑・・・他に良い方法ありませんか?)。 # 先の[border]-[edges]と被るとファイルが開けなくなる。 lth = worksheet.borders[worksheet.cellXfs[top_left].borderId] lth.prs << Axlsx::BorderPr.new(:name => :left, :color => Axlsx::Color.new(:rgb => '333333'), :style => :medium) lth.prs << Axlsx::BorderPr.new(:name => :top, :color => Axlsx::Color.new(:rgb => '333333'), :style => :medium) end # 配列でadd_rowするセル各々に異なるスタイルを適用できる。(例A〜C列のセルにのみスタイル適用) return [top_left, top_left, top_left, nil] end end
- mime_types.rb(config/initializers/)
# 追記 Mime::Type.register 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', :xlsx
- application.rb(config/)
# lib/ に置いたモジュールを読み込ませるために追記 config.autoload_paths += %W(#{config.root}/lib)
- Gemfile
# 追記 gem 'axlsx'