How to create download button for CSV and PDF using Ruby on Rails

nemuba

Alef Ojeda de Oliveira

Posted on November 20, 2021

How to create download button for CSV and PDF using Ruby on Rails

Hey Guys !

Let's cut to the chase, hands on code !

  • First generate scaffold
rails g scaffold Note title
Enter fullscreen mode Exit fullscreen mode
  • run db:migrate
rails db:migrate
Enter fullscreen mode Exit fullscreen mode
  • now we are going to install the gem to generate PDF, we will use the gem 'prawn' and the 'prawn-table':
bundle add prawn prawn-table
Enter fullscreen mode Exit fullscreen mode
  • now we're going to add the route and buttons for downloads nor csv and pdf format:
# add route in file config/routes.rb
resources :notes
root 'notes#index'
post 'download/notes', to: 'notes#download'

# add method downlod in controller app/controllers/notes_controller.rb
def download
    respond_to do |format|
      format.csv { send_data Note.to_csv, filename: "notes-#{Date.today}.csv" }
      format.pdf { send_data Note.to_pdf, filename: "notes-#{Date.today}.pdf" }
    end
end

# adds concerns to the note model to export the data
class Note < ApplicationRecord
  include ExportCsv
  include ExportPdf
end

# now let's create the modules in app/models/concerns
# first export_csv.rb
# frozen_string_literal: true

# module ExportCSV
module ExportCsv
  extend ActiveSupport::Concern

  # module ClassMethods
  module ClassMethods
    def to_csv
      require 'csv'
      options = { col_sep: ';', encoding: 'utf-8' }
      headers = %i[id title]

      CSV.generate(headers: true, **options) do |csv|
        csv << headers

        all.each do |note|
          csv << [note.id, note.title]
        end
      end
    end
  end
end

# second export_pdf.rb
# frozen_string_literal: true

# module ExportPdf
module ExportPdf
  extend ActiveSupport::Concern

  # module ClassMethods
  module ClassMethods
    def to_pdf
      require 'prawn'
      require 'prawn/table'

      options = { position: :center, column_widths: [300, 300], width: 600 }

      header = %w[ID Title]
      data = all.map { |note| [note.id, note.title] }
      Prawn::Document.new do
        text 'All Notes', align: :center, size: 18, style: :bold
        table([header, *data], header: true, **options)
      end.render
    end
  end
end

# and finally add the links on the app/views/notes/index.html.erb page
<%= button_to "Download CSV", download_notes_path(request.params.merge(format: :csv)), data: {turbo: :false} %>
<%= button_to "Download PDF", download_notes_path(request.params.merge(format: :pdf)), data: {turbo: :false} %>


Enter fullscreen mode Exit fullscreen mode

And that's it, we're done!

Github source: https://github.com/nemuba/import_export_file_rails

💖 💪 🙅 🚩
nemuba
Alef Ojeda de Oliveira

Posted on November 20, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related