61
How to create download button for CSV and PDF using Ruby on Rails
- First generate scaffold
rails g scaffold Note title
- run db:migrate
rails db:migrate
- 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
- 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} %>
And that's it, we're done!
Github source: https://github.com/nemuba/import_export_file_rails
61