<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Synthesis: How to generate CSV files in Rails</title>
    <link>http://www.synthesis.sbecker.net/articles/2007/06/07/how-to-generate-csv-files-in-rails</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>by Scott Becker</description>
    <item>
      <title>How to generate CSV files in Rails</title>
      <description>&lt;p&gt;A while back someone posted on rubyonrails-talk asking how to export to &lt;span class="caps"&gt;CSV&lt;/span&gt; from Rails.  I posted a solution, and people seemed to dig it, so I&amp;#8217;ll share it again here.&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://synthesis.sbecker.net/articles/2007/06/07/how-to-generate-csv-files-in-rails"&gt;&lt;img src="http://synthesis.sbecker.net/files/csv-storage-engine.png" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;h2&gt;Use FasterCSV&lt;/h2&gt;


	&lt;p&gt;Get the &lt;a href="http://fastercsv.rubyforge.org/"&gt;FasterCSV gem.&lt;/a&gt; Why? It&amp;#8217;s faster, and easier to use. Once you&amp;#8217;ve got it, require it in environment.rb. Here&amp;#8217;s an abbreviated version of my working controller method. Copy/paste/modify. And you&amp;#8217;re done!&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;
&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;export_to_csv&lt;/span&gt;
  &lt;span class="attribute"&gt;@users&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;User&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;find&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:all&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;

  &lt;span class="ident"&gt;csv_string&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;FasterCSV&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;generate&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;csv&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
    &lt;span class="comment"&gt;# header row&lt;/span&gt;
    &lt;span class="ident"&gt;csv&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;id&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;first_name&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;last_name&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;]&lt;/span&gt;

    &lt;span class="comment"&gt;# data rows&lt;/span&gt;
    &lt;span class="attribute"&gt;@users&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;each&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;user&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
      &lt;span class="ident"&gt;csv&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="ident"&gt;user&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;id&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;user&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;first_name&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;user&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;last_name&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="comment"&gt;# send it to the browsah&lt;/span&gt;
  &lt;span class="ident"&gt;send_data&lt;/span&gt; &lt;span class="ident"&gt;csv_string&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;
            &lt;span class="symbol"&gt;:type&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;text/csv; charset=iso-8859-1; header=present&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt;
            &lt;span class="symbol"&gt;:disposition&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;attachment; filename=users.csv&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;h2&gt;&lt;span class="caps"&gt;HTML&lt;/span&gt; or &lt;span class="caps"&gt;CSV&lt;/span&gt;, have it your way&lt;/h2&gt;


	&lt;p&gt;Now, if we wanted to get all clever about it, we could go further and serve both html and &lt;span class="caps"&gt;CSV&lt;/span&gt; data with only one action, using respond_to. This also requires that you add a RESTful route (map.resources :users) to your routes.rb file:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;index&lt;/span&gt;
  &lt;span class="attribute"&gt;@users&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;User&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;find&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:all&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;

  &lt;span class="ident"&gt;respond_to&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;wants&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
    &lt;span class="ident"&gt;wants&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;html&lt;/span&gt;
    &lt;span class="ident"&gt;wants&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;csv&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
      &lt;span class="ident"&gt;csv_string&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;FasterCSV&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;generate&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;csv&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
        &lt;span class="comment"&gt;# header row&lt;/span&gt;
        &lt;span class="ident"&gt;csv&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;id&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;first_name&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;last_name&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;]&lt;/span&gt;

        &lt;span class="comment"&gt;# data rows&lt;/span&gt;
        &lt;span class="attribute"&gt;@users&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;each&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;user&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
          &lt;span class="ident"&gt;csv&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="ident"&gt;user&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;id&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;user&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;first_name&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;user&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;last_name&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;
      &lt;span class="keyword"&gt;end&lt;/span&gt;

      &lt;span class="comment"&gt;# send it to the browsah&lt;/span&gt;
      &lt;span class="ident"&gt;send_data&lt;/span&gt; &lt;span class="ident"&gt;csv_string&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;
                &lt;span class="symbol"&gt;:type&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;text/csv; charset=iso-8859-1; header=present&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt;
                &lt;span class="symbol"&gt;:disposition&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;attachment; filename=users.csv&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Now if the user requests:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;/users &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;she&amp;#8217;ll get &lt;span class="caps"&gt;HTML&lt;/span&gt;. If she requests:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;/users.csv&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;You get the point.&lt;/p&gt;</description>
      <pubDate>Thu, 07 Jun 2007 16:21:00 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:5b2d2c11-6e14-42ad-a58b-5dba39c2ab4e</guid>
      <author>sbecker</author>
      <link>http://www.synthesis.sbecker.net/articles/2007/06/07/how-to-generate-csv-files-in-rails</link>
      <category>Ruby on Rails</category>
      <category>Web Development</category>
      <category>rails</category>
      <category>csv</category>
      <category>export</category>
    </item>
    <item>
      <title>"How to generate CSV files in Rails" by Kevin</title>
      <description>&lt;p&gt;This was very helpful thank you for posting it.  I now have a csv I can use to create a time sheet. :)&lt;/p&gt;</description>
      <pubDate>Thu, 03 Sep 2009 16:22:33 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:d1f9545f-079f-4162-af5e-0e6cf9e3e136</guid>
      <link>http://www.synthesis.sbecker.net/articles/2007/06/07/how-to-generate-csv-files-in-rails#comment-8833</link>
    </item>
    <item>
      <title>"How to generate CSV files in Rails" by Kevin</title>
      <description>&lt;p&gt;Though this is a bit old it helped me get the basis for my time sheet going.  This was very helpful, thanks for posting it.&lt;/p&gt;</description>
      <pubDate>Thu, 03 Sep 2009 16:17:52 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:cee94829-3fe5-4b0e-b093-c4a7f09f7175</guid>
      <link>http://www.synthesis.sbecker.net/articles/2007/06/07/how-to-generate-csv-files-in-rails#comment-8832</link>
    </item>
    <item>
      <title>"How to generate CSV files in Rails" by Tim</title>
      <description>&lt;p&gt;thanks a lot.
exactly what i needed, written clean and easy to copy.
cheers, tim&lt;/p&gt;</description>
      <pubDate>Wed, 18 Mar 2009 15:38:28 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:65654b9f-1166-4fda-8098-5b7e1d255b06</guid>
      <link>http://www.synthesis.sbecker.net/articles/2007/06/07/how-to-generate-csv-files-in-rails#comment-7969</link>
    </item>
    <item>
      <title>"How to generate CSV files in Rails" by curlysue282002@yahoo.com</title>
      <description>&lt;p&gt;Would this work for those who must use version Rails 0.14.1?  Also how would I call this in my view&lt;/p&gt;</description>
      <pubDate>Fri, 12 Dec 2008 15:10:33 -0800</pubDate>
      <guid isPermaLink="false">urn:uuid:28b64834-e678-43b7-b009-4031cc669755</guid>
      <link>http://www.synthesis.sbecker.net/articles/2007/06/07/how-to-generate-csv-files-in-rails#comment-7946</link>
    </item>
    <item>
      <title>"How to generate CSV files in Rails" by Renne</title>
      <description>&lt;p&gt;Nice tool Joel. Very useful, thanks.&lt;/p&gt;</description>
      <pubDate>Tue, 16 Sep 2008 01:54:34 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:4790fdac-023b-4802-bb93-4caa8ecbfcb7</guid>
      <link>http://www.synthesis.sbecker.net/articles/2007/06/07/how-to-generate-csv-files-in-rails#comment-7912</link>
    </item>
    <item>
      <title>"How to generate CSV files in Rails" by Joel Chippindale</title>
      <description>&lt;p&gt;Thanks Scott.&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;ve made this into a simple &lt;a href="http://github.com/econsultancy/csv_builder/tree/master"&gt;CSV Builder plugin&lt;/a&gt; to make this even easier.&lt;/p&gt;</description>
      <pubDate>Mon, 04 Aug 2008 22:35:58 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:7b11aa86-4284-4c2c-89fe-1c36080b4142</guid>
      <link>http://www.synthesis.sbecker.net/articles/2007/06/07/how-to-generate-csv-files-in-rails#comment-7899</link>
    </item>
    <item>
      <title>"How to generate CSV files in Rails" by Gregory Brown</title>
      <description>&lt;p&gt;Using Ruport:&lt;/p&gt;


&lt;pre&gt;
class User &amp;lt; ActiveRecord::Base
  acts_as_reportable :only =&amp;gt; ["id, "first_name", "last_name"]
end

# in controller
def export_to_csv
   User.report_table.to_csv
end

&lt;/pre&gt;

	&lt;p&gt;Of course, maybe overkill if that&amp;#8217;s all you need, but Ruport + acts_as_reportable also handles all associations and whatnot.  (And uses FCSV under the hood)&lt;/p&gt;</description>
      <pubDate>Wed, 27 Jun 2007 07:27:50 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:f9baffdb-43b6-42cd-b48b-cd51779198eb</guid>
      <link>http://www.synthesis.sbecker.net/articles/2007/06/07/how-to-generate-csv-files-in-rails#comment-7457</link>
    </item>
    <item>
      <title>"How to generate CSV files in Rails" by Meekish</title>
      <description>&lt;p&gt;Now that&amp;#8217;s hot :)&lt;/p&gt;</description>
      <pubDate>Fri, 08 Jun 2007 07:32:09 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:7b0c95f9-efdd-4cd2-a06e-e07974f60213</guid>
      <link>http://www.synthesis.sbecker.net/articles/2007/06/07/how-to-generate-csv-files-in-rails#comment-7381</link>
    </item>
    <item>
      <title>"How to generate CSV files in Rails" by Scott Becker</title>
      <description>&lt;p&gt;@Meekish &amp;#8211; Updated with a respond_to example.&lt;/p&gt;</description>
      <pubDate>Thu, 07 Jun 2007 21:45:04 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:abf52b8f-f79f-49c9-9e62-d36317691f7e</guid>
      <link>http://www.synthesis.sbecker.net/articles/2007/06/07/how-to-generate-csv-files-in-rails#comment-7380</link>
    </item>
    <item>
      <title>"How to generate CSV files in Rails" by Scott Becker</title>
      <description>&lt;p&gt;@Meekish &amp;#8211; Good idea. That would be more Rails 2.0ish, wouldn&amp;#8217;t it. Maybe I will post another example using respond_to soon.&lt;/p&gt;</description>
      <pubDate>Thu, 07 Jun 2007 20:57:38 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:c689e370-6c8b-4dbb-9924-d1311593d7eb</guid>
      <link>http://www.synthesis.sbecker.net/articles/2007/06/07/how-to-generate-csv-files-in-rails#comment-7379</link>
    </item>
    <item>
      <title>"How to generate CSV files in Rails" by Meekish</title>
      <description>&lt;p&gt;That&amp;#8217;s very nice.&lt;/p&gt;


	&lt;p&gt;How about making UsersController#index respond_to .csv instead of creating an entire action for it?&lt;/p&gt;</description>
      <pubDate>Thu, 07 Jun 2007 20:51:39 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:bca90599-29b6-45df-8ff9-26c65e8d5f38</guid>
      <link>http://www.synthesis.sbecker.net/articles/2007/06/07/how-to-generate-csv-files-in-rails#comment-7378</link>
    </item>
    <item>
      <title>"How to generate CSV files in Rails" by Jason Perry</title>
      <description>&lt;p&gt;I&amp;#8217;ve got a little &lt;a href="http://svn.ambethia.com/pub/ruby/reporter/lib/report.rb"&gt;ruby class&lt;/a&gt; that encapsulates to dumping of csv files out to disk. I use this to generate some regular reports.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;Report.create &amp;quot;District Participation&amp;quot; do
  data = District.find(:all, :order =&amp;gt; &amp;quot;number&amp;quot;).map do |district|
    profiles = district.profiles
    ratings  = profiles.collect { |p| p.ratings.size }
    [district.county, profiles.size, ratings.sum]
  end
  [[&amp;quot;District&amp;quot;, &amp;quot;Respondants&amp;quot;, &amp;quot;Ratings&amp;quot;]] + data
end

Report.create &amp;quot;Subject Area Participation&amp;quot; do
  data = Subject.find(:all, :order =&amp;gt; &amp;quot;area&amp;quot;).map do |subject|
    profiles = subject.profiles
    ratings  = profiles.collect { |p| p.ratings.size }
    [subject.area, profiles.size, ratings.sum]
  end
  [[&amp;quot;Subject Area&amp;quot;, &amp;quot;Respondants&amp;quot;, &amp;quot;Ratings&amp;quot;]] + data
end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;It needs somework, to clean up the way reports are defined, but it works well.&lt;/p&gt;</description>
      <pubDate>Thu, 07 Jun 2007 20:11:25 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:5c44222d-3d97-4e77-994c-3d57d038c7e8</guid>
      <link>http://www.synthesis.sbecker.net/articles/2007/06/07/how-to-generate-csv-files-in-rails#comment-7377</link>
    </item>
  </channel>
</rss>
