Rails 3 - 在respond_to中设置文件名

时间:2012-10-15 18:48:44

标签: ruby-on-rails-3 ruby-on-rails-3.2

这似乎应该很简单,但我似乎无法找到一个直接的答案。

我添加了一个csv mime-type,以下似乎可行,除了后,下载的文件总是命名为“report.csv”。

在我的控制器中:

def report
  respond_to do |format|
    format.html
    format.csv do
      render :template => "summary/report.csv.erb",
             :filename => "foo" #doesn't work
    end
  end
end

我认为它使用默认渲染器(我没有实现替代渲染器),但我似乎无法找到有关可用选项的完整文档。

是不是有像“文件名”选项或我可以使用的东西?有更好的方法吗?

3 个答案:

答案 0 :(得分:35)

我得到了它,感谢this answer的一些帮助。

format.csv do
  response.headers['Content-Disposition'] = 'attachment; filename="' + filename + '.csv"'
  render "summary/report.csv.erb"
end

首先在响应标头中设置文件名,然后调用render

render的模板参数是可选的,但就我而言,我需要它。)

答案 1 :(得分:6)

您可以将文件名传递给send_data,让它处理Content-Disposition标头。

# config/initializers/csv_support.rb
ActionController::Renderers.add :csv do |csv, options|
  options = options.reverse_merge type: Mime::CSV
  content = csv.respond_to? :to_csv ? csv.to_csv : csv.to_s
  send_data content, options
end

# app/controllers/reports_controller.rb
respond_to do |format|
  format.html ...
  format.csv { render csv: my_report, filename: 'my_report.csv' }
end

然后将to_csv方法添加到my_report或传递预生成的CSV字符串。

答案 2 :(得分:4)

或者,您可以使用send_data和render_to_string的组合(因为您有CSV模板)。

def report
  respond_to do |format|
    format.html
    format.csv do
      send_data render_to_string(:template => "summary/report.csv.erb"),
             :filename => "foo"
    end
  end
end