点击一个按钮,生成一份csv文件,这个csvs生成过程很耗时,要放到后台执行,生成完了之后,还要把文件发送到客户端,这个采用ajax定时请求,去判断文件是否生成成功
1、页面上按钮
<%= button_to_remote "CSV", {:url => {:action => 'get_csv'},
:confirm => "Are u sure?"},
:class => "btn_red" %>
2、接受请求的action
def get_csv
spawn do # backgroud job
begin
# generating csv
# more code here
rescue Exception => e
pp e
Rails.cache.write("csv_#{Process.pid}", 'error')
Rails.cache.write("csv_#{Process.pid}_error", e)
return
end
# mark the csv generated completed
Rails.cache.write("csv_#{Process.pid}", true)
end
flash[:notice] = "Generating csv"
render :update do |page|
page.replace_html "promote", :partial => "/common/messages"
page.insert_html :top,
"progress_ajax",
periodically_call_remote(:url => {:action => "csv_task_progress"},
:frequency => 5)
end
end
3、定时请求的js和action
def periodically_call_remote(options = {})
variable = options[:variable] ||= 'poller'
frequency = options[:frequency] ||= 10
code = "#{variable} = new PeriodicalExecuter(function()
{#{remote_function(options)}}, #{frequency})"
javascript_tag(code)
end
def csv_task_progress
if Rails.cache.read("csv_#{Process.pid}").eql?('error')
# csv generating occurred error
Rails.cache.write("sbps_#{Process.pid}", nil)
flash[:error] = Rails.cache.read("csv_#{Process.pid}_error")
render :update do |page|
page << "poller.stop();"
page.replace_html "promote", :partial => "/common/messages"
end
return
elsif Rails.cache.read("csv_#{Process.pid}").blank?
# return if the csv file have not generated completely
return (render :text => nil)
end
# prevent the later request download csv
Rails.cache.write("csv_#{Process.pid}", false)
flash[:notice] = "CSV Generated yet"
download_url = "/admin/exact_count/download_csv"
render :update do |page|
js = <<-EOF
poller.stop(); // stop the periodically call
var elemIF = document.createElement("iframe");
elemIF.src = '#{download_url}';
elemIF.style.display = "none";
document.body.appendChild(elemIF);
EOF
page << js
page.replace_html "promote", :partial => "/common/messages"
end
end
4、下载csv的action
def download_csv
send_file("#{RAILS_ROOT}/tmp/csv.csv", :type=>'text/csv', :filename=>"csv.csv")
end
至此就可以完成这个需求了
1、页面上按钮
<%= button_to_remote "CSV", {:url => {:action => 'get_csv'},
:confirm => "Are u sure?"},
:class => "btn_red" %>
2、接受请求的action
def get_csv
spawn do # backgroud job
begin
# generating csv
# more code here
rescue Exception => e
pp e
Rails.cache.write("csv_#{Process.pid}", 'error')
Rails.cache.write("csv_#{Process.pid}_error", e)
return
end
# mark the csv generated completed
Rails.cache.write("csv_#{Process.pid}", true)
end
flash[:notice] = "Generating csv"
render :update do |page|
page.replace_html "promote", :partial => "/common/messages"
page.insert_html :top,
"progress_ajax",
periodically_call_remote(:url => {:action => "csv_task_progress"},
:frequency => 5)
end
end
3、定时请求的js和action
def periodically_call_remote(options = {})
variable = options[:variable] ||= 'poller'
frequency = options[:frequency] ||= 10
code = "#{variable} = new PeriodicalExecuter(function()
{#{remote_function(options)}}, #{frequency})"
javascript_tag(code)
end
def csv_task_progress
if Rails.cache.read("csv_#{Process.pid}").eql?('error')
# csv generating occurred error
Rails.cache.write("sbps_#{Process.pid}", nil)
flash[:error] = Rails.cache.read("csv_#{Process.pid}_error")
render :update do |page|
page << "poller.stop();"
page.replace_html "promote", :partial => "/common/messages"
end
return
elsif Rails.cache.read("csv_#{Process.pid}").blank?
# return if the csv file have not generated completely
return (render :text => nil)
end
# prevent the later request download csv
Rails.cache.write("csv_#{Process.pid}", false)
flash[:notice] = "CSV Generated yet"
download_url = "/admin/exact_count/download_csv"
render :update do |page|
js = <<-EOF
poller.stop(); // stop the periodically call
var elemIF = document.createElement("iframe");
elemIF.src = '#{download_url}';
elemIF.style.display = "none";
document.body.appendChild(elemIF);
EOF
page << js
page.replace_html "promote", :partial => "/common/messages"
end
end
4、下载csv的action
def download_csv
send_file("#{RAILS_ROOT}/tmp/csv.csv", :type=>'text/csv', :filename=>"csv.csv")
end
至此就可以完成这个需求了