2010-10-18 6 views
7

Mam funkcję w kontrolerze, który pobiera pewne specyfikacje i generuje raport na ich temat. Ta funkcja user_report jest wywoływana w widoku:Trudność z send_data w Ruby on Rails w połączeniu z wtyczką Arkusza kalkulacyjnego

<% = submit_to_remote 'przycisk przesyłania', "Eksportuj raport do Excela",: url =>:: user_report,:: print_state => 'print'}%>

In reports_controller Używam wtyczki Spreadsheet do generowania pliku Excela w funkcji user_report. Chcę użyć send_data, aby przesłać plik strumieniowo do użytkownika, nie tworząc go najpierw na serwerze. Przeprowadzone przeze mnie badania pokazują, że używanie StringIO jest drogą do zrobienia, jak pokazano poniżej. Frustrating, nic nie dzieje się, gdy dzwonię send_data. Wydaje się, że wtyczka dobrze działa, tworząc plik i zapisując go na serwerze, ale nie robi nic, gdy używam send_file, sugerując, że problem nie leży w wtyczce. Ale co ja robię źle z send_file/send_data?

Sama funkcja wygląda tak:

def user_report

if request.post? 
    unless params[:reports][:userid].blank? 
    @userid=params[:reports][:userid] 
    end 
    if params[:print_state]=='print' 

    report = Spreadsheet::Workbook.new 
    info = report.create_worksheet :name => 'User Information' 
    info.row(1).push 'User ID', @userid 

    @outfile = "Report_for_#{@userid}.xls" 

    require 'stringio' 
    data = StringIO.new '' 
    report.write data 
    send_data data.string, :type=>"application/excel", :disposition=>'attachment', :filename => @outfile 
    end 

    respond_to do |format| 
    format.js { } 
    end 
end 

koniec

Plik dziennika odczytuje 2010-10-18 14:13 : 59 INFO - Przesyłanie danych Report_for_jjohnson.xls , ale pobieranie nie rozpoczyna się w przeglądarce. Udało mi się już użyć send_data w tej aplikacji, co jest mylące.

Używam Rails v2.3, Ruby v1.8.7 i Spreadsheet v6.4.1 w spreadsheet.rubyforge.org.

Odpowiedz

6

Wystarczy zmienić linię:

send_data data.string, :type=>"application/excel", :disposition=>'attachment', :filename => @outfile 

do:

send_data data.string.bytes.to_a.pack("C*"), :type=>"application/excel", :disposition=>'attachment', :filename => @outfile 
+3

Jest to stary pytanie ... Ale mam ochotę zauważyć, że 'data.string.force_encoding („binarny”)' u mnie działa i wygląda nieco lepiej. – scaryzet

0

Chociaż nie lubię pisać i usuwać, ale z arkusza kalkulacyjnego wydaje się jedynym rozwiązaniem.


# write the file 

book.write "Employee_History_#{ params[:id]}.xls" 

# send the file 

send_file "Employee_History_#{ params[:id]}.xls", :type => "application/vnd.ms-excel", :filename => "data.xls", :stream => false 

# and then delete the file 

File.delete("Employee_History_#{ params[:id]}.xls")