Domanda

Ho una semplice tabella di database chiamato "Voci":

class CreateEntries < ActiveRecord::Migration
  def self.up
    create_table :entries do |t|
      t.string :firstName
      t.string :lastName
      #etc.
      t.timestamps
    end
  end

  def self.down
    drop_table :entries
  end
end

Come faccio a scrivere un gestore che verrà restituito il contenuto delle Voci della tabella in un file CSV (idealmente in modo che si aprirà automaticamente in Excel)?

class EntriesController < ApplicationController

  def getcsv
    @entries = Entry.find( :all )

    # ??? NOW WHAT ????

  end

end
È stato utile?

Soluzione

C'è un plugin chiamato FasterCSV che gestisce questo meravigliosamente.

Altri suggerimenti

FasterCSV è sicuramente il modo di andare, ma se si vuole servire direttamente dalla vostra applicazione Rails, è necessario impostare alcune intestazioni di risposta, troppo.

Ho un metodo per impostare il nome del file e header necessari:

def render_csv(filename = nil)
  filename ||= params[:action]
  filename += '.csv'

  if request.env['HTTP_USER_AGENT'] =~ /msie/i
    headers['Pragma'] = 'public'
    headers["Content-type"] = "text/plain" 
    headers['Cache-Control'] = 'no-cache, must-revalidate, post-check=0, pre-check=0'
    headers['Content-Disposition'] = "attachment; filename=\"#{filename}\"" 
    headers['Expires'] = "0" 
  else
    headers["Content-Type"] ||= 'text/csv'
    headers["Content-Disposition"] = "attachment; filename=\"#{filename}\"" 
  end

  render :layout => false
end

L'utilizzo che la rende facile per avere qualcosa di simile nel mio controller:

respond_to do |wants|
  wants.csv do
    render_csv("users-#{Time.now.strftime("%Y%m%d")}")
  end
end

E hanno una vista che assomiglia a questo:(generate_csv è da FasterCSV)

UserID,Email,Password,ActivationURL,Messages
<%= generate_csv do |csv|
  @users.each do |user|
    csv << [ user[:id], user[:email], user[:password], user[:url], user[:message] ]
  end
end %>

Ho accettato (e votato up!) @Brian risposta, per la prima indicarmi FasterCSV.Poi, quando ho cercato su google per trovare la gemma, ho trovato anche un esempio abbastanza completo questa pagina wiki.Metterli insieme, ho risolto il codice riportato di seguito.

A proposito, il comando per installare la gemma è:sudo gem install fastercsv (tutto minuscolo)

require 'fastercsv'

class EntriesController < ApplicationController

  def getcsv
      entries = Entry.find(:all)
      csv_string = FasterCSV.generate do |csv| 
            csv << ["first","last"]
            entries.each do |e|
              csv << [e.firstName,e.lastName]
            end
          end
          send_data csv_string, :type => "text/plain", 
           :filename=>"entries.csv",
           :disposition => 'attachment'

  end


end

Un altro modo per fare questo senza l'utilizzo di FasterCSV:

Richiedono ruby biblioteca csv in un file di inizializzazione, come config/inizializzatori/dipendenze.rb

require "csv"

Come background il codice riportato di seguito è basata fuori di Ryan Bate Avanzata Form di Ricerca che crea una risorsa di ricerca.Nel mio caso il metodo di presentazione di una ricerca risorsa dovrà restituire i risultati di una ricerca salvati in precedenza.Esso risponde al csv, e utilizza un modello di visualizzazione per il formato di output desiderato.

  def show
    @advertiser_search = AdvertiserSearch.find(params[:id])
    @advertisers = @advertiser_search.search(params[:page])
    respond_to do |format|
      format.html # show.html.erb
      format.csv  # show.csv.erb
    end
  end

Lo show.csv.erb file è simile al seguente:

<%- headers = ["Id", "Name", "Account Number", "Publisher", "Product Name", "Status"] -%>
<%= CSV.generate_line headers %>
<%- @advertiser_search.advertisers.each do |advertiser| -%>
<%- advertiser.subscriptions.each do |subscription| -%>
<%- row = [ advertiser.id,
            advertiser.name,
            advertiser.external_id,
            advertiser.publisher.name,
            publisher_product_name(subscription),
            subscription.state ] -%>
<%=   CSV.generate_line row %>
<%- end -%>
<%- end -%>

La versione html della pagina del report ho un link per esportare il report che l'utente sta visualizzando.Il seguente è il link_to che restituisce il csv versione del report:

<%= link_to "Export Report", formatted_advertiser_search_path(@advertiser_search, :csv) %>

Prendere uno sguardo in FasterCSV gemma.

Se avete bisogno di excel di supporto, si potrebbe anche prendere in considerazione la generazione di un file xls direttamente.(Vedere Il Foglio Di Calcolo:Excel)

gem install fastercsv
gem install spreadsheet-excel

Trovo queste opzioni bene per l'apertura di un file csv in Windows Excel:

FasterCSV.generate(:col_sep => ";", :row_sep => "\r\n") { |csv| ... }

Come per il ActiveRecord parte, qualcosa di simile a questo sarebbe fare:

CSV_FIELDS = %w[ title created_at etc ]
FasterCSV.generate do |csv|
  Entry.all.map { |r| CSV_FIELDS.map { |m| r.send m }  }.each { |row| csv << row }
end

È necessario impostare l'intestazione Content-Type in una tua risposta, quindi inviare i dati.Content_Type:application/vnd.ms-excel dovrebbe fare il trucco.

Si potrebbe anche voler impostare l'intestazione Content-Disposition in modo che appaia come un documento di Excel, e il browser preleva un ragionevole nome di file predefinito;che qualcosa come Content-Disposition:allegato;filename="#{suggested_name}.xls"

Io suggerisco di usare il fastercsv rubino per generare il tuo file CSV, ma c'è anche un builtin csv.Il fastercsv codice di esempio (da gemma documentazione) assomiglia a questo:

csv_string = FasterCSV.generate do |csv|
  csv << ["row", "of", "CSV", "data"]
  csv << ["another", "row"]
# ...
end

I seguenti avvicinato funzionato bene per il mio caso e fa sì che il browser per aprire l'applicazione appropriata per il CSV tipo dopo il download.

def index
  respond_to do |format|
    format.csv { return index_csv }
  end
end

def index_csv
  send_data(
    method_that_returns_csv_data(...),
    :type => 'text/csv',
    :filename => 'export.csv',
    :disposition => 'attachment'
  )
end

provare un bel gioiello per generare CSV Rotaie https://github.com/crafterm/comma

Date un'occhiata al CSV Shaper gemma.

https://github.com/paulspringett/csv_shaper

Ha un bel DSL e funziona davvero bene con Guide modelli.Gestisce inoltre le intestazioni di risposta e permette di nome di file di personalizzazione.

Se hai semplicemente voglia di ottenere il csv database manualmente dalla console è possibile farlo in poche righe

tags = [Model.column_names]
rows = tags + Model.all.map(&:attributes).map(&:to_a).map { |m| m.inject([]) { |data, pair| data << pair.last } }
File.open("ss.csv", "w") {|f| f.write(rows.inject([]) { |csv, row|  csv << CSV.generate_line(row) }.join(""))}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top