2010-10-29 12 views
22

Ich bin mit diesem Spreadsheet gem xls-Datei zu exportieren.Direkt eine xls-Datei herunterzuladen, ohne sie in das Verzeichnis von Tabellenkalkulations gem Schreiben

Ich habe die folgenden Codes in meinem Controller:

def export 
    @data = Data.all 

    book = Spreadsheet::Workbook.new 
    sheet = book.create_worksheet :name => "data" 

    contruct_body(sheet, @data) 

    book.write "data.xls" 
end 

Auf diese Weise kann ich in den Daten füllen und sie in dem Root-Verzeichnis speichern.

Aber ich möchte es herunterladen, anstatt es zu speichern. Wie kann ich den Code so ändern, dass der Benutzer aufgefordert wird, sein lokales Verzeichnis zum Speichern der Datei auszuwählen? (Besser, wenn ohne eine Kopie in der Server-Seite zu speichern)

Bitte um Hilfe!

Antwort

46

Sie können sie an den Browser senden, ohne es als eine lokale Datei an allen zu Speichern als

spreadsheet = StringIO.new 
book.write spreadsheet 
send_data spreadsheet.string, :filename => "yourfile.xls", :type => "application/vnd.ms-excel" 
+0

Es funktioniert wirklich gut. Vielen Dank! – PeterWong

+0

@DanSingerman können Sie mir helfen, das gleiche mit CSV zu tun? – RAJ

+0

@RAJ eine neue Frage SO schaffen und ich werde einen Blick – DanSingerman

2

Sie könnten versuchen, diesen Code

book.write "data.xls" 

send_file "/path/to/data.xls", :type => "application/vnd.ms-excel", :filename => "data.xls", :stream => false 

# and then delete the file 

File.delete("path/to/data.xls") 

Passing :stream => false zu send_file wird Rails anweisen, die gesamte Datei in den Speicher zu kopieren, bevor das Streaming, so File.delete unmittelbar nach send_file Verwendung wäre in Ordnung, da send_file kehrt sofort, ohne auf die Warte Download zum Abschluss. Bei sehr großen Dateien sehen Sie je nach verfügbarem Speicher möglicherweise Engpässe.

HTH

+0

Bravo! Tatsächlich habe ich am Nachmittag genau das gleiche herausgefunden, warte aber auf weitere Tests. Deine Antwort gab mir Selbstvertrauen, also denke ich, dass ich mir keine Sorgen mehr machen muss ^^ Danke! – PeterWong

+0

Ich bin froh, dass ich helfen konnte :) –

+0

Das scheint nicht mehr zu funktionieren (ich habe gerade eine App geerbt, die diese Lösung verwendet ...). Wenn ich den 'File.delete' Teil entferne, funktioniert das. Ich habe versucht, die Datei in einem Nachfilter zu löschen, aber es funktioniert auch nicht. Wie ich es verstehe, ist 'stream: false' für diese Methode keine Option mehr und die Datei wird NICHT zwischengespeichert ... Irgendeine Einsicht? oder sollte ich send_data verwenden? –

0

Der Fall auf mybody passieren folgt. Ich habe die Ajax-Anfrage von remote :: true verwendet, um die Excel-Datei zu exportieren. Im Browser wird nichts angezeigt, ohne dass eine Fehlermeldung auf der Konsole erscheint. Löschen Sie die Remote-Parameter aus dem Formular, es funktioniert gut.