Export and Import excel file in Ruby on Rails framework - Phần 2
Bài đăng này đã không được cập nhật trong 3 năm
I. TÓM TẮT PHẦN MỘT
Như phần một đã giới thiệu export, import dữ liệu từ hệ thống lưu trữ dữ liệu ra các định dạng file khác nhau như xls, csv là chức năng cơ bản và cần thiết nhất của mỗi ứng dụng. Trong phần trước chúng ta đã tìm hiểu hai phương pháp export excel file.
- Export excel file bằng thiết kế XML
- Export excel file bằng gem "to_xls-Rails"
Mỗi một phương pháp đều có ưu điểm và nhược điểm riêng phù hợp với từng yêu cầu chức năng mà lập trình viên mong muốn. Trong phần này xin tiếp tục giới thiệu một phương pháp export excel file sử dụng gem axlsx
có đầy đủ các chức năng từ cơ bản tới phức tạp.
II. EXPORT EXCEL FILE BẰNG GEM AXLSX
Hướng dẫn cài đặt
Việc cài đặt gem axlsx
trên framework Ruby on Rails cũng đơn giản và tương tự như các gem khác.
- Build một project RoR với lệnh
rails new project_name
- Add
gem axlsx
vàoGemfile
gem "axlsx"
- Run
bundle install
Vậy là chúng ta đã thành công cài đặtgem axlsx
và sẵn sàng sử dụng.
Xây dựng chương trình demo
1. Create model
class CreateStudents < ActiveRecord::Migration
def change
create_table :students do |t|
t.string :name
t.integer :age
t.string :phone_number
t.string :email
t.integer :class_room_id
t.timestamps null: false
end
end
end
class CreateClassRooms < ActiveRecord::Migration
def change
create_table :class_rooms do |t|
t.string :name
t.timestamps null: false
end
end
end
2. Create controller home để hiển thị dữ liệu
- Xây dựng
app/views/home/index.html
<div class="row">
<div class="container">
<table class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>Student Name</th>
<th>Student Age</th>
<th>Student Phone Number</th>
<th>Student Email</th>
<th></th>
</tr>
</thead>
<tbody>
<% @students.each do |student| %>
<tr>
<td><%= student.id %></td>
<td><%= student.name %></td>
<td><%= student.age %></td>
<td><%= student.phone_number %></td>
<td><%= student.email %></td>
<td><%= link_to "Download", axlsx_index_path(id: student.try(:id)) %></td>
</tr>
<% end %>
</tbody>
</table>
</div>
<div class="container">
<p>
Download:
<%= link_to "Excel_By_Xml", xml_index_path(format: "xls") %>
<br>
Download:
<%= link_to "Excel_By_Gem_To_Xls", to_xls_path(format: "xls") %>
<br>
Download:
<%= link_to "Excel_By_Gem_Axlsx", axlsx_index_path %>
</p>
</div>
</div>
-
Cho giao diện như sau.
-
Xây dựng controller
AxlsxController
xử lý xuất dữ liệu của mộtstudent
khi click vào buttondownload
class AxlsxController < ApplicationController
require "axlsx"
def index
student = Student.find_by id: params[:id]
send_xls student
end
private
def send_xls student
book = Axlsx::Package.new
workbook = book.workbook
sheet = workbook.add_worksheet name: "StudentInformation"
sheet.add_row ["Attributes", "Values"]
create_data(student).each_with_index do |item|
sheet.add_row [item.first, item.last]
sheet.add_data_validation("B2", {type: :list, formula1: "MasterData!$A$3:$A$7"})
end
send_excel_file book
end
def send_excel_file book
tmp_file_path = "#{Rails.root}/tmp/#{rand(36**50).to_s(36)}.xlsx"
book.serialize tmp_file_path
filename = "Aloha-#{Time.zone.now}.xlsx"
file_content = File.read(tmp_file_path)
send_data file_content, filename: filename
File.delete tmp_file_path
end
def create_data student
[["class_room", student.class_room_name], ["name", student.name],
["age", student.age], ["phone_number", student.phone_number], ["email", student.email]]
end
end
- Kết qủa
- Giao diện file excel.
- Giải thích một số
key word
trong fileapp/controllers/axlsx_controller.rb
require "axlsx"
: Thêm thư viện của gem axlsx vào controller để sử dụng.workbook
: Object đại diện cho file excel được tạo ra từ classAxlsx::Package
của gemaxlsx
workbook.add_worksheet name: "StudentInformation"
tạo ra sheet trong file excel với name làStudentInformation
.add_row
method thêm một hàng vào trong file excel.book.serialize
: Khởi tạo file excel với đường path định sẵn.send_data
method để send file excel đã khởi tạo.File.delete
xóa file đã được gửi.
Tìm hiểu một số chức năng nâng cao
Về thiết kế chúng ta sẽ thêm một sheet thứ hai chứa data master là dữ liệu được hiển thị trong dropdown class room
.
1. Thêm dropdown để chọn dữ liệu
- Thêm method
make_pulldown
trong methodsend_xls
private
def send_xls student
book = Axlsx::Package.new
workbook = book.workbook
sheet = workbook.add_worksheet name: "StudentInformation"
info_sheet = book.workbook.add_worksheet name: "MasterData"
make_pulldown sheet, info_sheet, student
send_excel_file book
end
- Nội dung private method
make_pulldown
def make_pulldown sheet, info_sheet, student
info = {class_room: ClassRoom.pluck(:name)}
base = [*1..info.values.to_a.map(&:size).max]
info_sheet_data = base.each_with_index.inject([]) do |info_sheet_data, (item, index)|
info_sheet_data << info.values.map{|item| item[index]}.unshift(item)
end
info_sheet.add_row info.keys.map{|item| "List All Class Room"}
info_sheet.add_row [""]
info_sheet_data.each do |data|
info_sheet.add_row data[1..-1], types: Array.new(data.length, nil)
end
sheet.add_row ["Attributes", "Values"]
create_data(student).each_with_index do |item|
sheet.add_row [item.first, item.last]
sheet.add_data_validation("B2", {type: :list, formula1: "MasterData!$A$3:$A$7"})
end
end
Trong đó:
info_sheet
: Thêm một sheet khác trong file excel để chứa dữ liệu master.info_sheet_data
: Dữ liệu master data có dạng một mảng.- Thêm dữ liệu master dưới dạng mảng.
info_sheet_data.each do |data|
info_sheet.add_row data[1..-1], types: Array.new(data.length, nil)
end
- Thêm thông tin của student và định nghĩa data trong pull down được lấy từ sheet thứ hai.
sheet.add_row ["Attributes", "Values"]
create_data(student).each_with_index do |item|
sheet.add_row [item.first, item.last]
sheet.add_data_validation("B2", {type: :list, formula1: "MasterData!$A$3:$A$7"})
end
Kết qủa:
Dữ liệu master trong sheet thứ hai:
2. Custom Styles của file excel
Những style như font chữ, màu sắc, độ rộng cột ... đều được cung cấp và dễ dàng sử dụng.
- Customer method
make_pulldown
def make_pulldown workbook, student
sheet = workbook.add_worksheet name: "StudentInformation"
info_sheet = workbook.add_worksheet name: "MasterData"
info = {class_room: ClassRoom.pluck(:name)}
base = [*1..info.values.to_a.map(&:size).max]
info_sheet_data = base.each_with_index.inject([]) do |info_sheet_data, (item, index)|
info_sheet_data << info.values.map{|item| item[index]}.unshift(item)
end
info_sheet.add_row info.keys.map{|item| "List All Class Room"}
info_sheet.add_row [""]
info_sheet_data.each do |data|
info_sheet.add_row data[1..-1], types: Array.new(data.length, nil)
end
style = workbook.styles
black_cell = style.add_style bg_color: "00", fg_color: "FF", sz: 14, alignment: {horizontal: :center}
blue_cell = style.add_style bg_color: "0000FF", fg_color: "FF", sz: 20, alignment: {horizontal: :center}
sheet.column_widths 30, 50
sheet.add_row ["Attributes", "Values"], :style => [black_cell, blue_cell]
create_data(student).each_with_index do |item|
sheet.add_row [item.first, item.last]
sheet.add_data_validation("B2", {type: :list, formula1: "MasterData!$A$3:$A$7"})
end
end
- Trong đó:
style = workbook.styles
: Khởi tạo object để chứa các cài đặt style.add_style
: Method dùng để thêm style đã được khởi tạo vào trong file excel theo từng dòng.sheet.column_widths 30, 50
: Cài đặt độ rộng của từng cột tính theo px.- Các method như
bg_color, fg_color, sz, ...
đều được cung cấp đầy đủ dùng để định nghĩa các cài đặt style tới mức nhỏ nhất.
Kết qủa:
3. Một số chức năng nổi bật
- Thêm hình ảnh vào trong file.
- Thêm biểu đồ vào trong file.
- Thêm công thức vào trong từng ô của file.
- Customer kiểu dữ liệu trong từng ô của file.đều
- .....v v
Tất cả những cài đặt, cách sử dụng những chức năng trên đều được cũng cấp và hướng dẫn cụ thể trên trang chủ của gem axlsx
tại đây
4. Một số chức năng nổi bật
Có rất nhiều cách để import dữ liệu từ file excel tuy nhiên xin giới thiệu một cách đơn giản sử dụng gem roo
được hướng dẫn cụ thể tại đây.
IV. KẾT LUẬN
Có rất nhiều phương pháp để xây dựng chức năng này, mỗi một phương pháp đều có ưu điểm và nhược điểm riêng tùy theo yêu cầu mà chọn lựa cách hợp lý nhất. Bài viết chỉ đề xuất một vài phương án trong đó còn nhiều thiếu xót mong nhận được góp ý từ bạn đọc.
Thanks you for listening!!!
All rights reserved