2010-10-29 36 views
22

J'utilise cette gemme Spreadsheet pour exporter le fichier xls.Téléchargement direct d'un fichier xls sans l'écrire dans le répertoire par Spreadsheet gem

J'ai les codes suivants dans mon contrôleur:

def export 
    @data = Data.all 

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

    contruct_body(sheet, @data) 

    book.write "data.xls" 
end 

De cette façon, je peux remplir les données et l'enregistrer dans le répertoire racine.

Mais je veux le télécharger au lieu de le sauvegarder. Comment pourrais-je modifier le code afin que l'utilisateur invite à sélectionner son répertoire local pour enregistrer le fichier? (préférable si vous n'enregistrez pas de copie côté serveur)

Aidez-nous!

Répondre

46

Vous pouvez l'envoyer au navigateur sans l'enregistrer comme un fichier local tout comme suit

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

Ça marche vraiment bien. Merci! – PeterWong

+0

@DanSingerman pouvez-vous m'aider à faire de même avec csv? – RAJ

+0

@RAJ créer une nouvelle question SO et je vais jeter un oeil – DanSingerman

2

Vous pouvez essayer ce 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") 

Passant :stream => false à send_file ordonnera-Rails pour copier le fichier en mémoire avant le streaming, donc l'utilisation File.delete immédiatement après send_file serait bien car send_file retourne immédiatement sans attendre la télécharger pour compléter. Cela dit, avec de très gros fichiers, vous pouvez voir des goulots de mémoire en fonction de la quantité de mémoire disponible.

HTH

+0

Bravo! En fait, je viens de découvrir exactement la même chose dans l'après-midi, mais en attendant d'autres tests. Votre réponse m'a donné confiance, alors je pense que je n'ai plus besoin de m'inquiéter ^^ Merci! – PeterWong

+0

Content de pouvoir aider :) –

+0

Cela ne semble plus fonctionner (j'ai juste hérité d'une application qui utilise cette solution ...). Si je supprime la partie 'File.delete', cela fonctionne. J'ai trieed pour supprimer le fichier dans un filtre après, mais cela ne fonctionne pas non plus. Si je comprends bien, 'stream: false' n'est plus une option pour cette méthode, et le fichier ne sera pas mis en cache ... Un aperçu? ou devrais-je utiliser send_data? –

0

Le cas se produire sur body défini. J'ai utilisé la requête ajax par remote :: true pour exporter le fichier Excel, rien ne s'affiche sur le navigateur sans message d'erreur sur la console. Supprimez les paramètres distants du formulaire, cela fonctionne bien.