Exporting CSV from Rails

Exporting table data as excel and google spreadsheet-friendly csv is easy with ruby's CSV library. Let's walk through an example in just a few steps:

1. Require the CSV library

At the top of your confic/application.rb file, add require 'csv'

2. Enable your controller to respond to requests for .csv formatting

In whatever action renders the view that holds your data of data that you're looking to export, add the following:

def my_results
  @results = Result.where(user_id: current_user.id)
  respond_to do |format|
    format.html
    format.csv { send_data @results.to_csv }
  end
end

Let's break down what's going on there.
*format.csv allows the controller to respond to requests for csv data. Meaning that if a user attempts to visit www.example.com/myresults.csv, the controller can send back csv data.
*format.csv takes a block. The send_data method in the block creats a download of the csv data returned by our my_results controller method. Then, we call .to_csv on our results array to actually do the work of converting an array of ruby ojbects into csv data. This is not a native method offered to us by the CSV library, we have to define it ourself in our Result model:

3. Define a method that converts ruby objects into CSV data

def self.to_csv
    CSV.generate do |csv|
      csv << column_names
      all.each do |result|
        csv << result.attributes.values_at(*column_names)
      end
    end
  end

CSV.generate is a method offered by the csv library to creates empty CSV fields. We then populate those fields with the attributes of each ruby object. We call values_at on each attribute of the ruby object and pass it an argument of (*column_names) to ensure that the attributes will match up to the column headers of our table.

We're almost done. Now we just need a friendly way for our users to request the csv document. Let's make a button:

4. Create an 'export' button in your view

<a href="/myresults.csv"><button class="btn btn-success">export all</button></a>

Our button is wrapped in a link with the .csv extension, so clicking the button will fire a request to www.example.com/myresults.csv, which we've already taught our my_results method in the contoller to respond to.

And that's it! For further reference, check out this awesome rails cast!

subscribe and never miss a post!

Blog Logo

Sophie DeBenedetto

comments powered by Disqus
comments powered by Disqus