Export multiple excel and zip files in Rails
Bài đăng này đã không được cập nhật trong 10 năm
I. Introduction
Exporting excel file and zip files is not somethings new, but sometimes we must to integrate both. So today, I want to share my task.
II. Installation
Firstly, we need to install gem axslx to customize our file easily:
- Add to
Gemfile
gem "axlsx"
- Run command
bundle install
III. Services
In this example, each team had many member who have a unique budget, and we want to download budget of all teams or members. Then, to be clear, we need to create 2 services: export excel files and export file zip:
1. Export Excel files
For exporting excel service, we have some function:
app/services/budget/export_xls.rb
- Initialize attributes:
TITLE_COLUMN = ["ID", "Name", "Birthday"]
def initialize_attributes
budget_dates = []
@deadlines = []
@files = []
(Date.today.cweek..Date.today.end_of_year.cweek).to_a.map do |d|
deadlines << Date.commercial(Date.today.year, d, 7)
date = Date.commercial(Date.today.year, d, 1)
budget_dates << date.date.to_s
end
@first_row = [*TITLE_COLUMN, *budget_dates]
end
- Create temporally files
def create_files
BudgetType.pluck(:name).each_with_index do |file_name, index|
package = Axlsx::Package.new
workbook = package.workbook
workbook.add_worksheet(name: file_name) do |sheet|
sheet.add_row first_row
end
files << package
end
end
- Add data for these files by customize format
def add_data_to_files object
budgets = object.budgets.deadlines_in deadlines
info = [object.id, object.name, object.birthday]
files.each do |file|
row = [*info, *budgets]
file.workbook.worksheets.first.add_row row
end
end
- Save temporally files
def save_file
files.each do |file|
file.serialize "#{file.workbook.worksheets.first.name}.xls"
end
end
- Finally, in
perform, we use those methods as:
def perform
initialize_attributes
return unless create_file
Team.each do |team|
add_data_to_files team
team.members.each do |member|
add_data_to_files member
end
end
save_file
end
2. Export file zip
In zip files service, we need to create temporally zip file, add created excel files to zip and delete all temporally excel files:
app/services/budget/zip_budgets.rb
def perform files
begin
temp = Tempfile.new FILE_NAME
Zip::File.open(temp.path, Zip::File::CREATE) do |zipfile|
files.each do |file|
zipfile.add "#{file}.xls", "#{Rails.root}/#{file}.xls"
end
end
files.each do |file|
File.delete "#{file}.xls"
end
rescue Errno::ENOENT, IOError => e
Rails.logger.error e.message
temp.close
end
temp
end
IV. Controller and view
- To download zip file, we need to return this file in controller:
app/controllers/export/budgets_controller.rb
def index
if Budget::ExportXls.perform
zip = Budget::ZipBudgets.perform BudgetType.pluck(:name)
send_file zip.path, type: "application/zip", x_sendfile: true,
disposition: "attachment", filename: "Budgets.zip"
end
end
- Finally, we add button download to view:
app/views/budgets/index.html.erb
<%= link_to export_budgets_path do %>
<%= button_tag "Download" %>
<% end %>
V. Conclusion
This is a good way to export multiple excel and zip files in rails. I hope you find this article useful. Thanks for reading!
All rights reserved