To save database information as a csv, we will need to require the rails csv library in the controller we are going to use it in. You also need to add the format in your view method you need it in.
# UsersController.rb
require 'csv'
def index
# Your Code
@users = User.all
respond_to do |format|
format.html
format.csv
end
end
Then in your index.csv.erb view file, you will need to add in the rows and columns you want to be displayed in the csv file.
# index.csv.erb
# This first line will be the column headers
["First Name", "Last Name", "Join Date", "Login Count"].to_csv
# This loop iteration will then be all the rows
<% @users.each do |user| %>
<%= [user.first_name, user.last_name, user.join_date, user.login_count].to_csv %>
<% end %>
Then in your users index.html.erb add the following line.
# users/index.html.erb
<%= link_to "CSV", users_path(format: "csv") %>
Another way of doing it would be to add a self.to_csv method in your model, and then call it directly from the controller when its path is called.
# UsersController.rb
def index
@users = User.all
respond_to do |format|
format.html
format.csv { send_data @users.to_csv }
end
end
# models/user.rb
def self.to_csv(options = {})
CSV.generate(options) do |csv|
csv << column_names
all.each do |user|
csv << user.attributes.values_at(*column_names)
end
end
end
To convert your data to XLS, you'll need to add an xls view file to your users directory. Then paste the following code inside.
# users.xls.erb
<?xml version="1.0"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
<Worksheet ss:Name="Sheet1">
<Table>
<Row>
<Cell><Data ss:Type="String">First Name</Data></Cell>
<Cell><Data ss:Type="String">Last Name</Data></Cell>
<Cell><Data ss:Type="String">Join Date</Data></Cell>
<Cell><Data ss:Type="String">Login Count</Data></Cell>
</Row>
<% @users.each do |user| %>
<Row>
<Cell><Data ss:Type="Number"><%= user.first_name %></Data></Cell>
<Cell><Data ss:Type="String"><%= user.last_name %></Data></Cell>
<Cell><Data ss:Type="String"><%= user.join_date %></Data></Cell>
<Cell><Data ss:Type="Number"><%= user.login_count %></Data></Cell>
</Row>
<% end %>
</Table>
</Worksheet>
</Workbook>
After you do that, then add the file format in its controller.
# UsersController.rb
def index
# Your code
respond_to do |format|
# Append the following line to this method
format.xls
end
end
All that's left now is to add the link to your view file you need it in.
<%= link_to "Excel", users_path(format: "xls") %>
Another way to accomplish this is through the AXLSX Rails Gem. The method below will also create a new sheet in and workbook for each user. You would want to add in additional information for perhaps user posts, comments, pictures, or whatever needs to be included.
# controllers/users_controller.rb
def index
@users = User.all
respond_to do |format|
format.xlsx
end
end
# views/user/index.xlsx.axlsx
@wb = xlsx_package.workbook
@users.each do |user|
@wb.add_worksheet(name: user.name) do |sheet|
sheet.add_row ["First Name", "Last Name", "Join Date", "Login Count"]
sheet.add_row [user.first_name, user.last_name, user.join_date, user.login_count]
# User posts?
# user.posts.each do |post|
# sheet.add_row [post.topic, post.title, post.body, post.comment_count]
# end
sheet.column_widths 10, nil, nil, nil
end
end
An additional guide can be found here.
To get started we will be using Wicked PDF. We will first need to add this to our gemfile.
# Gemfile
gem 'wicked_pdf'
The next step is optional, you can add this mime type to your config/initializers/mime_types.rb.
# config/initializers/mime_types.rb
Mime::Type.register "application/pdf", :pdf
You can also turn any page into a pdf without a view file by adding middleware to your config/application.rb.
# config/application.rb
config.middleware.use WickedPdf::Middleware
Next, we will need to add the pdf format to our respond_to method in the controller we want to use it in.
# controllers/UsersController.rb
class UsersController < ApplicationController
def index
@users = User.all
respond_to do |format|
format.html
format.pdf do
render :pdf => "report", :layout => 'pdf.html.slim'
end
end
end
end
Next we can also create a layout file to use for when our pdfs are called using Wicked PDFs helpers.
# app/views/layouts/pdf.html.slim
doctype html
head
title My Rails Pdf
= wicked_pdf_stylesheet_link_tag "application", :media => "all"
= wicked_pdf_javascript_include_tag "application"
= csrf_meta_tags
body
== yield
We will then need to create a view file in the view directory we need it in.
# app/views/users/index.pdf.slim
.container
.row
= wicked_pdf_image_tag('my-logo.png')
.row
.col-xs-6
h3
My Cool Header
p
Some cool stuff
.col-xs-6
h3
Your header
p
Some paragraph text
.row
table.table.table-striped
thead
th #
th Name
th Join Date
tbody
- @users.each do |user|
tr
td
= user.id
td
= user.name
td
= user.join_date
In the above code block, it is obvious we are using Wicked PDFs helpers instead of the normal rails helpers. This is because if we were to use the rails helpers, the application would hang upon request until completed, and also any img helpers would not be loaded.
A little side note apart from this is that wkhtmltopdf is run outside our rails application. If we need to add any files to it, it needs to be an absolute path of that file or it will not be found.
If you need to send it in a mailer, you can use the below line in your *_mailer.rb.
def mailer_method(*args)
attachments["name.pdf"] = WickedPdf.new.pdf_from_string(render_to_string(pdf: "method_name", template: "path/to/template.pdf.html.slim"))
mail(:to => "", :from => "", :subject => "")
end
Lets start off by creating our .vcf view file and add some code into it.
# users.vcf.erb
<% @users.each do |user| %>
<%= "BEGIN:VCARD" %>
<%= "VERSION:4.0" %>
<%= "N:#{user.first_name};#{user.last_name};;;"%>
<%= "FN:#{user.full_name}" %>
<%= "PHOTO;TYPE=uri:#{user.avatar}" %>
<%= "EMAIL;TYPE=work,internet;PREF=1:#{user.email}" %>
<%= "item1.URL:#{user.website_url}" %>
<%= "item1.LABEL:#{user.website_type}" %>
<%= "END:VCARD" %>
<% end %>
Now that we have that finished, all we need to do is add this to our controller index method in the respond_to method.
# UsersController.rb
def index
# Your code
respond_to do |format|
# Append the following line to this method
format.vcf
end
end
Setup all the information you need to export to a view in your controller and then add the following line to its method.
# controllers/pages_controller.rb
def xml_sitemap
@blogs = Blog.all
respond_to do |format|
format.xml
end
end
Then add this to your view file.
# views/pages/xml_sitemap.xml.slim
doctype xml
urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"
url
loc
| https://www.samwholst.com/
priority
| 1.00
url
loc
| https://www.samwholst.com/blog
priority
| 0.80
- @blogs.each do |blog|
url
loc
= blogs_url(blog)
priority
| 0.70