1

I am working on to allow download an excel file with the below code:

login     = Etc.getlogin
@dataFile = "C:/rails/#{login}data.csv"

csv1=CSV.open(@dataFile, 'w') do |csv|
  $data.each do |eachrow|
    csv << [eachrow.name+"@gmail.com"]
  end
end

send_file(@dataFile, :filename => "#{login}data", :type =>  "application/csv")

Using the above code, I am able to create a file and write the data.

Instead of this, how do i write the data in csv and get downloaded into users machine instead of saving in local/server.

ogirginc
  • 4,948
  • 3
  • 31
  • 45

1 Answers1

1

What you can do is generate a string with the CSV library, using CSV::generate instead of CSV::open.

Controller:

class DataController < ApplicationController
  def download
    respond_to do |format|
      format.csv { send_csv_download }
    end
  end

  private

  def send_csv_download
    string = CSV.generate do |csv|
      @data.each { |row| csv << ["#{row.name}@gmail.com"] }
    end

    send_data string, filename: 'foo.csv', type: :csv
  end

end

config/routes.rb:

get '/download', to: 'data#download'

View:

<%= link_to 'Download CSV', download_path(format: :csv) %>

Note: Obviously, I have no idea where you get your @data from, since it isn't specified in your question.

3limin4t0r
  • 19,353
  • 2
  • 31
  • 52
mityakoval
  • 888
  • 3
  • 12
  • 26
  • Tried with the above code, but still the file is not getting downloaded. – Mallela SriPrakash Jun 26 '18 at 11:52
  • @MallelaSriPrakash any errors? I tried it in rails 5.1.5 and it worked. – mityakoval Jun 26 '18 at 12:52
  • @Mark First we use CSV's `generate` method to make string that represents the comma-separated data. Then it is wrapped in a I/O stream object to be able to send it to the client. But now as I am writing this I think we can drop the StringIO and just send the string itself. – mityakoval Jun 26 '18 at 12:54
  • I dont see any file being downloaded. I am having ajax call on button click which calls the method from the controller. But, per this article https://stackoverflow.com/questions/17304407/how-to-make-a-div-with-a-rails-link-clickable it seems to be it wont work with ajax calls – Mallela SriPrakash Jun 26 '18 at 13:10
  • @MallelaSriPrakash Well, you should've mentioned the AJAX call in your question. As it is suggested here: https://stackoverflow.com/questions/16242359/how-to-trigger-download-with-rails-send-data-from-ajax-post/17526267 you might try rendering a partial that will download a file for you. But I would just do it without AJAX. – mityakoval Jun 26 '18 at 13:20
  • @mityakoval, apologies for not mentioning the same. Can you help me the sample code without ajax or by using – Mallela SriPrakash Jun 26 '18 at 13:24
  • @MallelaSriPrakash I've updated the answer. Obviously, I have no idea where you get your `@data` from. – mityakoval Jun 26 '18 at 14:18
  • @mityakoval, Really thanks for the above sample code. That worked. – Mallela SriPrakash Jun 26 '18 at 17:41
  • @mityakoval, sorry to bother you again. Can you tell me what is download_path(format: :csv) in the above code. Being novice, thought to clear the doubt – Mallela SriPrakash Jun 26 '18 at 18:02
  • @MallelaSriPrakash That will translate to the string `'/download.csv'`. The `download_path` helper is generated by setting the route `get '/download', to: 'data#download'`. See: http://guides.rubyonrails.org/routing.html – 3limin4t0r Jun 27 '18 at 08:46