DEV Community

Cover image for How to create download button for CSV and PDF using Ruby on Rails
Alef Ojeda de Oliveira
Alef Ojeda de Oliveira

Posted on • Edited on

9

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

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

Top comments (1)

Collapse
 
kamkara profile image
kamate vakaramoko

thank for great post.

Heroku

Build apps, not infrastructure.

Dealing with servers, hardware, and infrastructure can take up your valuable time. Discover the benefits of Heroku, the PaaS of choice for developers since 2007.

Visit Site

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay