bcparanj-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
2007-Jun-16 01:24 UTC
CSV Download of any given model
I found sample code from the archives of this list to make CSV
download of a model. It works fine. I am wondering if it is possible
to generalize the code posted by François on his blog to handle any
given model.
class ReportController < ApplicationController
def report
@models = Model.find(:all, :conditions => [''...''])
report = StringIO.new
CSV::Writer.generate(report, '','') do |csv|
csv << %w(Title Total)
@models.each do |model|
csv << [model.title, model.total]
end
end
report.rewind
send_data(report.read,
:type => ''text/csv; charset=iso-8859-1;
header=present'',
:filename => ''report.csv'')
end
end
TIA.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---
I''m curious on this as well... my code is a little different then that
of the blog post referenced:
class SignaturesController < ApplicationController
def export
require ''csv''
content_type = if request.user_agent =~ /windows/i
''application/vnd.ms-excel''
else
''text/csv''
end
CSV::Writer.generate(output = "") do |csv|
csv << Signature.column_names
Signature.find(:all).each do |signature|
csv << [signature.id, signature.firstname, signature.lastname]
end
end
send_data(output, :type => content_type, :filename =>
"#{controller_name}-export.csv")
end
end
I''m already using Model.column_names to get the header of the CSV
file. Is there a way to loop through Model.content_columns and grab
the name variable to include within the block rather then specifying
the column individually?
Thoughts from anyone? Thanks...
Tim
On Jun 15, 9:24 pm, "bcpar...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org"
<bcpar...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
wrote:> I found sample code from the archives of this list to makeCSV
> download of a model. It works fine. I am wondering if it is possible
> to generalize the code posted by François on his blog to handle any
> given model.
>
> class ReportController < ApplicationController
> def report
> @models = Model.find(:all, :conditions => [''...''])
> report = StringIO.new
> CSV::Writer.generate(report, '','') do |csv|
> csv<< %w(Title Total)
> @models.each do |model|
> csv<< [model.title, model.total]
> end
> end
>
> report.rewind
> send_data(report.read,
> :type => ''text/csv; charset=iso-8859-1;
header=present'',
> :filename => ''report.csv'')
> end
> end
>
> TIA.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---
I think you''ll find this simpler and more flexible. First,
you''ll
need to download the FasterCSV gem (''gem install fastercsv'').
Then
you can use:
class FasterCSVExport
require ''fastercsv''
def create_report( field_names = [], data_rows = [] )
FasterCSV.generate do |csv|
csv << field_names.map {|fn| fn.humanize.titleize }
data_rows.each {|row| csv << row }
end
end
end
I''ve given it to you as a stand-alone class but the create_report
method can also be added to each model directly or as part of a module
that gets mixed in (which is how I do it). Then in your controller
you can just have:
field_names = [''id'', ''firstname'',
''lastname'']
table_rows = YourModel.find(:all).collect {|item| [item.id,
item.firstname, item.lastname]
export_data = FasterCSVExport.create_report(field_names, table_rows)
send_data(export_data, :type => "text/csv; charset=utf-8;
header=present",
:disposition => ''attachment'', :filename =>
"exported_data.csv")
Even easier, you can pass your field_names to the "select" option when
performing the find to quickly have both the table header and the
table rows contain the same attributes. Something like:
field_names = [''id'', ''firstname'',
''lastname'']
table_rows = YourModel.find(:all, :select => field_names)
export_data = FasterCSVExport.create_report(field_names, table_rows)
send_data(export_data, :type => "text/csv; charset=utf-8;
header=present",
:disposition => ''attachment'', :filename =>
"exported_data.csv")
Or if you opt to put the ''create_report'' method into your
model
directly, you can push the find to the model too and let it handle
both steps at once.
export_data = YourModel.create_report([''id'',
''firstname'', ''lastname''])
send_data(export_data, :type => "text/csv; charset=utf-8;
header=present",
:disposition => ''attachment'', :filename =>
"exported_data.csv")
>From there you can start to add bells and whistles. Tim, something
like:
field_names = YourModel.column_names if field_names.blank?
might be what you want to grab all the column names.
(I''m typing this from scratch without testing it so it''s quite
possible I''ve typo''d something...)
HTH,
Kevin Skoglund
http://www.nullislove.com
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---
Thank you Kevin - that makes sense, I''ll check it out when I get back to the office tomorrow. Regards, Tim On Jul 27, 1:08 pm, Kevin Skoglund <ke...-WGmuFPN42W8gMxX8nMqP6gC/G2K4zDHf@public.gmane.org> wrote:> I think you''ll find this simpler and more flexible. First, you''ll > need to download the FasterCSV gem (''gem install fastercsv''). Then > you can use: > > class FasterCSVExport > require ''fastercsv'' > > def create_report( field_names = [], data_rows = [] ) > FasterCSV.generate do |csv| > csv << field_names.map {|fn| fn.humanize.titleize } > data_rows.each {|row| csv << row } > end > end > end > > I''ve given it to you as a stand-alone class but the create_report > method can also be added to each model directly or as part of a module > that gets mixed in (which is how I do it). Then in your controller > you can just have: > > field_names = [''id'', ''firstname'', ''lastname''] > table_rows = YourModel.find(:all).collect {|item| [item.id, > item.firstname, item.lastname] > export_data = FasterCSVExport.create_report(field_names, table_rows) > send_data(export_data, :type => "text/csv; charset=utf-8; > header=present", > :disposition => ''attachment'', :filename => "exported_data.csv") > > Even easier, you can pass your field_names to the "select" option when > performing the find to quickly have both the table header and the > table rows contain the same attributes. Something like: > > field_names = [''id'', ''firstname'', ''lastname''] > table_rows = YourModel.find(:all, :select => field_names) > export_data = FasterCSVExport.create_report(field_names, table_rows) > send_data(export_data, :type => "text/csv; charset=utf-8; > header=present", > :disposition => ''attachment'', :filename => "exported_data.csv") > > Or if you opt to put the ''create_report'' method into your model > directly, you can push the find to the model too and let it handle > both steps at once. > > export_data = YourModel.create_report([''id'', ''firstname'', ''lastname'']) > send_data(export_data, :type => "text/csv; charset=utf-8; > header=present", > :disposition => ''attachment'', :filename => "exported_data.csv") > > >From there you can start to add bells and whistles. Tim, something > > like: > field_names = YourModel.column_names if field_names.blank? > might be what you want to grab all the column names. > > (I''m typing this from scratch without testing it so it''s quite > possible I''ve typo''d something...) > > HTH, > Kevin Skoglund > > http://www.nullislove.com--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---