8

Rails 3.1.0.rc8 と Chromium 15.0.874.102 を使用しています。

CSV ダウンロードのファイル名を設定したい。私はこのSO ソリューションfilenameに従っていますが、Content-Dispositionヘッダーの を変更できないことがわかりました。

これが私のコードです:

module ActionController 
  module CSVHelper

    def render_csv options={}
      if request.env['HTTP_USER_AGENT'] =~ /msie/i
        headers['Pragma'] = "public"
        headers['Content-Type'] = "text/plain"
        headers['Cache-Control'] = "no-cache, must-revalidate, post-check=0, pre-check=0"
        headers['Expires'] = "0"
      else
        headers['Content-Type'] = "text/csv"
      end

      filename = generate_filename options.delete(:basename)
      headers['Content-Disposition'] = "attachment; filename=#{filename}"
    end

    def generate_filename basename=nil, suffix="csv"
      filename = basename || params[:action]
      filename << ".#{suffix}"
      filename
    end

  end
end    

そして私のコントローラーで:

respond_to do |format|
  format.html
  format.csv do
    render_csv(:basename => "my_filename")
    Rails.logger.debug "HEADERS: #{headers.to_s}"
  end
end  

私のログでは:

[2011-11-28 12:25:49.611] DEBUG - HEADERS: {"Content-Type"=>"text/csv", "Content-Disposition"=>"attachment; filename=my_filename.csv"}

Chromium ネットワーク インスペクター ツールで、応答ヘッダーに次のように表示されます。

Content-Type: text/plain
Content-Disposition: attachment; filename=index.csv

Content-Typeを のようなものに変更するとfoo/bar、変更がネットワーク インスペクタ ツールに表示されます。を何に設定しfilenameても、そのままですindex.csv

ありがとう、マックス

4

4 に答える 4

11

HTTP/1.1 仕様の付録の Content-Disposition セクションによると、ファイル名は引用符で囲まれた文字列でなければなりません:

   filename-parm = "filename" "=" quoted-string
   ...

例は

   Content-Disposition: attachment; filename="fname.ext"

したがって、おそらく次の変更を行う必要があります (引用符に注意してください)。

headers['Content-Disposition'] = "attachment; filename=\"#{filename}\""
于 2012-11-26T21:10:53.947 に答える
2

私のチームがcsv_builder gemを使用していることがわかりました。これにより、コントローラーで設定することにより、ダウンロードしたファイルの名前を調整できます@filename。OPで説明されている動作を取得した理由を説明できる人には、引き続き正しい答えを与えます。

于 2011-11-28T18:30:14.607 に答える
1

出力を実際に送信/レンダリングしている場所がわかりません...それは.csv.erbファイルか何かにありますか? または csv_builder を他の回答として使用しますか? それがトリックかもしれません。

.xlsx 出力をレンダリングするのと同じことを思いつきました。ファイルをディスクに保存したら、次のようにします。

def example
  respond_to do |format|
    format.xlsx do
      path = some_method_generating_xlsx_file
      headers['Content-Disposition'] = "attachment; filename=test.xlsx"
      render :text => File.binread(path), :content_type => XLSX_MIME_TYPE
    end
  end
end

私のコントローラーで、それはうまくいきました。おそらく、テンプレートのレンダリングによってヘッダーが上書きされていたのでしょう。

于 2012-11-24T08:58:33.047 に答える