rails ruby-on-rails csv

ruby-on-rails - rails import csv



en rieles, cómo devolver registros como un archivo csv (10)

Acepté (¡y voté!) La respuesta de @ Brian, por primera vez me indicó FasterCSV. Luego, cuando busqué en Google para encontrar la gema, también encontré un ejemplo bastante completo en esta página wiki . Poniéndolos juntos, me decidí por el siguiente código.

Por cierto, el comando para instalar la gema es: sudo gem install fastercsv (todo en minúsculas)

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

Tengo una tabla de base de datos simple llamada "Entradas":

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

¿Cómo escribo un controlador que devolverá los contenidos de la tabla de entradas como un archivo CSV (idealmente de forma que se abra automáticamente en Excel)?

class EntriesController < ApplicationController def getcsv @entries = Entry.find( :all ) # ??? NOW WHAT ???? end end


Debe configurar el encabezado Content-Type en su respuesta, luego envíe los datos. Content_Type: application / vnd.ms-excel debería hacer el truco.

Es posible que también desee configurar el encabezado Content-Disposition para que se vea como un documento de Excel, y el navegador elija un nombre de archivo predeterminado razonable; eso es algo como Content-Disposition: attachment; filename = "# {suggested_name} .xls"

Sugiero usar la gema ruby ​​fastercsv para generar su CSV, pero también hay una csv incorporada. El código de ejemplo de fastercsv (de la documentación de la gema) se ve así:

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


Echa un vistazo a la gema CSV Shaper.

https://github.com/paulspringett/csv_shaper

Tiene un buen DSL y funciona muy bien con los modelos de Rails. También maneja los encabezados de respuesta y permite la personalización del nombre de archivo.


Echa un vistazo a la gema de FasterCSV .

Si todo lo que necesita es soporte de excel, también puede buscar generar un xls directamente. (Ver hoja de cálculo :: Excel)

gem install fastercsv gem install spreadsheet-excel

Encuentro estas opciones buenas para abrir el archivo csv en Windows Excel:

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

En cuanto a la parte ActiveRecord, algo como esto sería:

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


El siguiente enfoque funcionó bien para mi caso y hace que el navegador abra la aplicación apropiada para el tipo CSV después de la descarga.

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


Hay un complemento llamado FasterCSV que maneja esto maravillosamente.


Otra forma de hacerlo sin usar FasterCSV:

Requerir la biblioteca csv de ruby ​​en un archivo de inicializador como config / initializers / dependencies.rb

require "csv"

Como antecedentes, el siguiente código se basa en el formulario de búsqueda avanzada de Ryan Bate que crea un recurso de búsqueda. En mi caso, el método show del recurso de búsqueda devolverá los resultados de una búsqueda previamente guardada. También responde a csv y usa una plantilla de vista para formatear el resultado deseado.

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

El archivo show.csv.erb tiene el siguiente aspecto:

<%- 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 -%>

En la versión html de la página del informe, tengo un enlace para exportar el informe que el usuario está viendo. El siguiente es el link_to que devuelve la versión csv del informe:

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


Si simplemente desea obtener la base de datos csv desde la consola, puede hacerlo en unas pocas líneas

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(""))}



FasterCSV es definitivamente el camino a seguir, pero si desea servirlo directamente desde su aplicación Rails, también querrá configurar algunos encabezados de respuesta.

Guardo un método para configurar el nombre de archivo y los encabezados necesarios:

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

Usar eso hace que sea fácil tener algo como esto en mi controlador:

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

Y tenga una vista que se vea así: ( generate_csv es de 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 %>