在Rails中,如何提交表格并请求CSV格式的页面



我有一些解决方案的部分,但是我很难将它们放在一起。

我有一个带有两个文本字段的页面(以form_tag为单位(,其中我将输入一个DateTime字符串,其中我想以CSV表单下载的记录的开始和结束日期。

我可以使用submit_tag并获取两个日期,但是我不知道如何获取视图来告诉控制器我想要CSV,所以。我可以使用link_to,但是随后访问了参数。

我试图弄清楚这些东西应该如何一起工作时,视图和控制器看起来有些奇怪。例如,我不会同时运送链接和按钮。我还根据需要删除/更改了简洁/隐私。

show.html.erb:

<%= form_tag do %>    
  <br/><br/>
  <%= label_tag :start_date, "From:" %>
  <%= text_field_tag :start_date, nil, size: 40 %>
  <%= label_tag :end_date, "To:" %>
  <%= text_field_tag :end_date, nil, size: 40 %>
  <br/>
  <%= link_to "Export Report", report_path(:csv) %>
  <%= submit_tag("Generate .CSV", format: :csv) %><br/><br/>
<% end %>

report_controller.rb:

require 'csv'
class ReportController < ApplicationController
  def show
    if params[:start_date]          
      @data = get_data(params[:start_date], params[:end_date])
      respond_to do |format|
        format.html
        format.csv
      end
    end
  end
  def build_csv_enumerator(header, data)
    Enumerator.new do |y|
      CSVBuilder.new(header, data, y)
    end
  end
  def download
    if params[:start_date]
      @data = get_data(params[:start_date], params[:end_date])
      respond_to do |format|
        format.html
        format.csv
      end
    end
    redirect_to action: "show"
  end
  private def csv_filename
    "report-#{Time.now.to_s}.csv"
  end
end
class CSVBuilder
  attr_accessor :output, :header, :data
  def initialize(header, data, output = "")
    @output = output
    @header = header
    @data = data
  end
  def build
    output << CSV.generate_line(header)
    data.each do |row|
      output << CSV.generate_line(row)
    end
    output
  end
end

download.csv.erb:

<%- headers = ["name", "email", "created_at"] -%>
<%= CSV.generate_line(headers) %>
<%- @data.each do |line| -%>
  <%- row = line.values_at(*headers) -%>
  <%= CSV.generate_line(row) %>
<%- end -%>

,因为要下载csv,请求应为 GET请求。

您的链接应该看起来像<a download href="/reports/1.csv?from=2017-01-01&to=2017-12-31">Download</a>。我建议您在浏览器上构建此URL(这意味着使用JavaScript,而不是Rails(。

您的导轨应用程序必须了解扩展名.csv。这可以在config/initializers/mime_types.rb

中配置
Mime::Type.register "text/csv", :csv

现在您可以将CSV发送到浏览器

class ReportsController < ApplicationController
  def show
    respond_to do |format|
      # ...
      format.csv do
        @csv = ...
        send_data @csv.to_s  # what you send must be a string
      end
    end
  end
end

链接是独立的;提交按钮(通常(将表格(带有所有非disabledname-保存值(提交表单的操作URL(除非您通过JavaScript进行提交,否则显然您可以做任何您想做的事,显然(。

因此,您未在submit_tag上指定URL,而是在form_tag上指定它:

启动一个表单标签,将操作指向用url_for_options配置的URL,就像ActionController::Base#url_for一样。

作为提到的答案之一,您需要在form_tag上指定format。它可能会变得棘手,因为需要在url_options中设置format,而不是在其他form_tag选项中设置。例如:

<%= form_tag({controller: 'my_controller', method: 'my_method', format: 'csv'}, method: "get") do %>
  ...fields
  <%= submit_tag 'Submit' %>
<% end %>

最新更新