- Streaming CSV Download from Rails 3.2 app
- class ExportsController < ApplicationController
- require 'fastercsv'
- require 'generic_agent'
- require 'generic_record'
- def listing
- @this_filepath = "../html/whatever/" << Time.now.strftime("%I:%M:%S_%d:%m:%y") << ".csv"
- @spawn_id = spawn(:nice => 1) do
- FasterCSV.open(@this_filepath, "w") do |csv|
- csv << [ "outbreak_id"]
- end
- end
- render :update do |page|
- page.replace_html 'export_status', :partial => 'export_status_partial'
- end
- end
- def send_export
- @this_filepath = params[:with]
- csv_file = File.open(@this_filepath.to_s, 'r')
- csv_string = ""
- csv_file.each_line do |line|
- csv_string << line
- end
- send_data csv_string, :filename => "export.csv",
- :type => 'text/csv; charset=iso-8859-1; header=present',
- :disposition => "attachment; filename=export.csv"
- #send_file @this_filepath.to_s, :stream => false, :type=>"text/csv", :x_sendfile=>true
- #send_data csv_string, :filename => export.csv
- #File.delete(@this_filepath.to_s)
- end
- def export_checker
- filename_array = params['filename'].split(///)
- @file_found = 0
- @file_ready = 0
- @file_size = File.size(params['filename'])
- @this_filepath = params['filename']
- if File.exists?(params['filename'])
- release_time = Time.now - 5.seconds
- if File.mtime(params['filename']).utc < release_time.utc
- @file_found = 1
- @file_ready = 1
- @file_access_time = File.mtime(params['filename'])
- @file_release_time = release_time
- @file_size = File.size(params['filename'])
- else
- @file_found = 1
- @file_ready = 0
- @file_size = File.size(params['filename'])
- end
- else
- @file_found = 0
- @file_ready = 0
- @file_size = File.size(params['filename'])
- end
- render :action => "export_checker"
- end
- end
- if @file_found == 1 && @file_ready == 1 && @file_size > 0
- page.replace_html 'link_to_file', :partial => "export_ready"
- if @file_release_time
- page.replace_html 'notice', "<div>Completed #{@file_release_time.strftime("%I:%M:%S %A %d %B %Y")} :: file size #{@file_size.to_s}</div>"
- end
- page.visual_effect :highlight, 'link_to_file', :endcolor => '#D3EDAB'
- elsif @file_found == 1
- page.replace_html 'link_to_file', "<div> File found, but still being constructed.</div><div>#{@this_filepath.to_s}</div>"
- page.visual_effect :highlight, 'link_to_file', :endcolor => '#FF9900'
- else
- page.replace_html 'link_to_file', "<div> File not found @file_found #{@file_found.to_s} @file_ready #{@file_ready.to_s}</div>"
- page.visual_effect :highlight, 'link_to_file', :endcolor => '#FF0000'
- end
- format.csv {
- @entries = Entry.all
- @columns = ["First Name", "Last Name"].to_csv
- @filename = "entries-#{Date.today.to_s(:db)}"
- self.response.headers["Content-Type"] ||= 'text/csv'
- self.response.headers["Content-Disposition"] = "attachment; filename=#{@filename}"
- self.response.headers["Content-Transfer-Encoding"] = "binary"
- self.response_body = Enumerator.new do |y|
- @entries.each_with_index do |entry, i|
- if i == 0
- y << @columns
- end
- y << [entry.first_name, entry.last_name].to_csv
- end
- end
- }