簡體   English   中英

在 Rails 中,如何提交表單並請求 csv 格式的頁面?

[英]In Rails, how can I submit a form and request a csv formatted page?

我有解決方案的幾個部分,但我無法將它們組合在一起。

我有一個包含兩個文本字段(在 form_tag 中)的頁面,我將在其中輸入一個日期時間字符串,其中包含我想以 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

下載.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)。

您的 rails 應用程序必須理解擴展名.csv 這可以在config/initializers/mime_types.rbconfig/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

鏈接是獨立的; 提交按鈕(通常)將表單(帶有所有非disabled 、具有name值)提交到表單的操作 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 %>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM