Excel への出力(その2)

昨日の続きです.修正したコントローラを再掲します.

  def show
    @export_excel = true # この行を追加
    @club, @ids = get_parameters_and_ids [ Club.gp(true) ]
    (省略)
    respond_to do |format|
      format.html # show.html.haml
      format.xls { output_excel('/teacher/clubs/show.html', "#{@club.name}_部員一覧.xls") }
      # 第一引数は自動で生成できそうな気がしてきた.後で修正するかも,第二引数は出力するファイル名です.
    end
  end

xls フォーマットの場合,format.xls {} 内が実行されます.ちなみに,xls フォーマットについては,config/initializers/mime_types.rb にて,

Mime::Type.register "application/vnd.ms-excel; charset=utf-8", :xls

と書いておくことで,Excel ファイルであることが認識されています.

app/controllers/application_controller.rb の抜粋

上記の output_excel は application_controller.rb に記載されています.基本は HAML template の内容を render_to_string で文字列に出力し,ファイル名を付けて,send_data しているだけです.ただし,Internet Explorer では正しくファイル名が展開できずファイル名が文字化けしてしまうため,CGI.escape しています.

  def IEpatch(fname)
    /MSIE/ =~ request.env['HTTP_USER_AGENT'] ? CGI.escape(fname) : fname
  end

  # excel で出力
  def output_excel(template, fname = nil)
    @excel_page = true
    options = fname ? { filename:IEpatch(fname)} : {}
    send_data(render_to_string(template:template, layout:'excel.html'), options)
  end

app/views/layouts/excel.html.haml

output_excel 内で指定しているレイアウトファイルです.ダウンロードされるファイルであり,外部の CSS にアクセスできる可能性が少ないため,%style の中に埋め込んでしまっています.

!!!
%html{ xmlns:"http://www.w3.org/1999/xhtml", "xml:lang" => "ja", lang:"ja" }
  %head
    %title #{ controller.class.name} : #{controller.action_name}
    %meta{ "http-equiv" => "content-type", content:"application/vnd.ms-excel; charset=utf-8" }
    %style
      -f = open(File.join(Rails.root, 'public/stylesheets/hogehoge.css'))
      =f.read
      -f.close
  %body
    =yield

view の中身

output_excel 内で @excel_page を true にしています.そのため,@excel_page をチェックすることで,Excel に出力したくない内容を除外することができます.

  -unless @excel_page
    Excel に出力したくない内容

P.S.
要望があったので,明日からは MaciOS 関係のことも書いてみます.