Thursday, October 6, 2016

Using Ruby CSV Library to Export CSV File in Rails Apps - Template Approach

Using Ruby CSV Library to Export CSV File in Rails Apps - Template Approach
When we need to export data to a file in CSV format, we don’t need an extra gem to do so. The standard ruby library has included this functionality. All we need is to require it in application.rb
app/config/application.rb
require 'csv'  <== add this line
require 'rails/all'
  :
Now, I need to have a download button on the show page of the model Order. First, I have to add code to the show action of the order controller.
At this point, there are two ways to do the job. One is template approach, the other is send_data method approach.
(send_data method approach is in another article: here )

Template Approach

Template approach using XXX.csv.erbas a template to generate data to CSV file. Utilization of CSV commands exists in the template file.
app/controllers/orders_controller.rb
def show
     :
     :
  respond_to do |format|
    format.html
    fn = "order_#{@order.po_number}_#{Time.now.strftime("%Y-%m-%d %H:%M:%S")}.csv"
    format.csv do
      headers['Content-Disposition'] = "attachment; filename =" + fn
      headers['Content-Type'] ||= 'text/csv'
    end
  end
end
Second, a new template file show.csv.erb should be added and written in CSV format.
app/views/orders/show.csv.erb
<%- headers = ['PO Number','Model Name', 'Size', 'Color', 'Price (USD)', 'Quantity', 'Total'] -%>
<%= CSV.generate_line headers -%>
<%- @orderdetails.each do |orderdetail| -%>
  <%= CSV.generate_line([
    orderdetail.order.po_number,
    orderdetail.model.name,
    orderdetail.size.name,
    orderdetail.color.name,
    orderdetail.price,
    orderdetail.quantity,
    orderdetail.total_amount
    ]) -%>
<%- end -%>
Note that <%- -%>prevents the app from generating a line break in the CSV file.
While typing the url below in the browser, it downloads the CSV file instantly.
http://localhost:3000/orders/1.csv
Here is the exported CSV file.
File name: order_1234_2016-10-05 23-38-27.csv
PO Number,Model Name,Size,Color,Price (USD),Quantity,Total
1234,PINEROLO AL SE 0.2 TIG welded Sora 18 Carbon/Alloy Fork,700C X 48CM,Gloss Red,365.42,106,38734.52
1234,PINEROLO AL SE 0.2 TIG welded Sora 18 Carbon/Alloy Fork,700C X 48CM,Gloss Black,365.42,2,730.84
1234,PINEROLO AL SE 0.2 TIG welded Sora 18 Carbon/Alloy Fork,700C X 50CM,Gloss Red,365.42,2,730.84
1234,PINEROLO AL SE 0.2 TIG welded Sora 18 Carbon/Alloy Fork,700C X 50CM,Gloss Black,365.42,2,730.84
The last step is to make a link somewhere in the order show page.
app/views/orders/show.html.erb
<%= link_to 'Export to CSV', order_path(@order, format: :csv) %>
Done!
By the way, there are excellent articles about Ruby CSV library, highly recommended!
A Guide to the Ruby CSV Library, Part I
A Guide to the Ruby CSV Library, Part II

No comments:

Post a Comment