2013-06-11 4 views
2

Je suivais cette vidéo railscast mais j'ai de sérieuses difficultés pour exporter mes données vers Excel (ou CSV pour cette question).Exportation au format CSV à partir d'une requête de rails complexes

J'utilise will_paginate dans certaines données que je montre sur frontend comme ceci:

sql = "select complex..." 
@data = paginate_by_sql([sql], 
       :per_page => params[:rows], 
       :page => params[:page]) 

donc, tel quel, je pensais que cela devrait fonctionner:

respond_to do |format| 
    format.html 
    format.xls { send_data @data.to_csv(:col_sep => "\t") } 
end 

et effectivement téléchargé un fichier xls correctement par le contenu est tout foiré, il montre une ligne par colonne et quelque chose comme ça comme contenu:

#<Product:0x00000004c83328>

PS -> en utilisant des rails dernière version

:: EDIT :: par une ligne par colonne je veux dire une seule ligne sur ma feuille Excel et sur cette ligne

COLONNE A = #<Product:0x00000004c83328>

cOLONNE B = #<Product:0x00000004c83329>

cOLONNE C = #<Product:0x00000004c8333> (30 colonnes)

UPDATE

a fait un exercice simple pour tester et mettre fin avec toutes les colonnes à nouveau dans une seule colonne:

csv_string = CSV.generate(:col_sep => ",") do |csv| 
    csv << ["row", "of", "CSV", "data"] 
    csv << ["another", "row"] 
end 

respond_to do |format| 
    format.html 
    format.csv { send_data csv_string, 
     :type => 'text/csv; charset=iso-8859-1; header=present', 
     :disposition => "attachment; filename=records.csv" } 
end 

(:col_sep => ",") est facultative, je suppose.

Résultat:

excel output

Répondre

0

ok, donc c'est ce que j'ai fait.

modifié le répondeur à cette ...

respond_to do |format| 
    format.xls 
end 

et créé un modèle appelé nameofmethod.xls.erb avec ce ...

<?xml version="1.0"?> 
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" 
    xmlns:o="urn:schemas-microsoft-com:office:office" 
    xmlns:x="urn:schemas-microsoft-com:office:excel" 
    xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" 
    xmlns:html="http://www.w3.org/TR/REC-html40"> 
    <Worksheet ss:Name="Sheet1"> 
    <Table> 
     <Row> 
     <% @data.first.attributes.keys.each do |column| %> 
     <Cell><Data ss:Type="String"><%=column%></Data></Cell> 
     <% end %> 
     </Row> 
    <% @data.each do |row| %> 
     <Row> 
     <% row.attributes.values.each do |column| %> 
     <Cell><Data ss:Type="String"><%= column %></Data></Cell> 
     <% end %> 
     </Row> 
    <% end %> 
    </Table> 
    </Worksheet> 
</Workbook> 

C'est assez dynamique pour tout type de ActiveRecord Objet. Pour le moment cela devra faire ...

0

Vous êtes presque là, vous avez juste besoin de la carte chacun de vos Product objets de modèle parce que vous appelez to_s sur eux, ce qui est indéfini.

Donc, si vous voulez juste une liste de titres, vous pouvez remplacer la méthode to_s sur votre modèle (app/models/product.rb) de faire quelque chose comme:

def to_s 
    title 
end 

Ou, pour générer une liste séparée, vous pouvez le faire par des virgules

def to_s 
    [title, price, availability].join(',') 
end 
+0

Je suis désolé, je ne comprenais pas ce que vous entendez par me appeler un 'to_s' ... Je suis juste appeler' paginate_by_sql'. Bien que je réalise que la sortie ressemble à un modèle converti en chaîne ... c'est bizarre. Je dois être proche ... – tostasqb

+0

Oui, si vous appelez to_s sur un modèle, comme 'Person', vous obtiendrez des résultats comme' # '. Quelle est la conversion de chaîne par défaut pour un modèle ActiveRecord. Donc, je vous suggère de remplacer cette méthode dans votre modèle en définissant une nouvelle méthode 'to_s'. – ipd

Questions connexes