Importing & Exporting CSV / Excel
Bài viết này giới thiệu tới các bạn cách Import và Export file CSV/Excel đơn giản bằng Ruby on the Rails. #CSV Đầu tiên, trong file config/application.rb thêm require: require 'csv' Ví dụ ta sẽ import/export database bảng User. I. Importing CSV Tạo đường dẫn ...
Bài viết này giới thiệu tới các bạn cách Import và Export file CSV/Excel đơn giản bằng Ruby on the Rails.
#CSV
- Đầu tiên, trong file config/application.rb thêm require:
require 'csv'
Ví dụ ta sẽ import/export database bảng User.
I. Importing CSV
- Tạo đường dẫn import_users_path trong routes.rb
resources :users do collection { post :import } end
- Thêm method import trong models/user.rb
class << self def import(file) CSV.foreach(file.path, headers: true) do |row| User.create!(row.to_hash) end end end
Thêm headers: true để bỏ qua dòng đầu tiên trong file csv(column_names). Với mỗi dòng tiếp theo tạo user tương ứng vào trong database.
- Trong users_controller.rb gọi method import trong model ra.
def index @users = User.all end def import User.import(params[:file]) redirect_to root_path, notice: "Imported." end
- Trong view:
<h2>Import</h2> <%= form_tag import_users_path, multipart: true do %> <%= file_field_tag :file %> <%= submit_tag 'Import' %> <% end %> <h2>Users</h2> <table style='awidth:400px'> <tr> <th>Name</th> <th>Code</th> </tr> <% @users.each do |user| %> <tr> <td><%= user.name %></td> <td><%= user.code %></td> </tr> <% end %> </table>
- File csv minh họa users.csv
code,name B120010,Lê Hoài Phương B120011,Nguyễn Thị Minh Ngọc B120012,Lê Duy Khánh B120013,Nghiêm Tuấn Minh B120016,Trần Ngọc Thắng B120017,Nguyễn Văn Ngọc B120018,Đinh Thanh Tâm B120022,Phạm Ngọc Tâm B120024,Vũ Ngọc Anh
- Kết quả dữ liệu bảng User sau khi import:
II. Exporting CSV
- Để export dữ liệu ra file csv phải thêm format: csv trong users_controller.rb
def index @users = User.all respond_to do |format| format.html format.csv { render text: @users.to_csv } end end
-Trong models/user.rb method to_csv được mô tả:
class << self def to_csv CSV.generate do |csv| csv << column_names all.each do |user| csv << user.attributes.values_at(*column_names) end end end end
Đầu tiên là thêm các column_name vào dòng đầu. Các dòng tiếp theo là giá trị các trường tương ứng với dòng đầu của mỗi user trong database.
- Trong view:
<%= link_to 'Export', users_path(format: 'csv') %>
- Kết quả sau khi click vào link sẽ xuất ra file users.csv
id,name,code 52,Lê Hoài Phương,B120010 53,Nguyễn Thị Minh Ngọc,B120011 54,Lê Duy Khánh,B120012 55,Nghiêm Tuấn Minh,B120013 56,Trần Ngọc Thắng,B120016 57,Nguyễn Văn Ngọc,B120017 58,Đinh Thanh Tâm,B120018 59,Phạm Ngọc Tâm,B120022 60,Vũ Ngọc Anh,B120024
#Excel
I. Importing Excel
- Để import file Excel có nhiều gem hỗ trợ, ở đây sử dụng gem 'roo'. Thêm gem vào Gemfile rồi bundle install.
gem 'roo'
-
File routes.rb, controller và view tương tự như import file csv.
-
Đối với file models/user.rb, method import có thể mở cả file csv, excel do sử dụng thư viện roo.
class << self def import(file) spreadsheet = open_spreadsheet(file) header = spreadsheet.row(1) (2..spreadsheet.last_row).each do |i| row = Hash[[header, spreadsheet.row(i)].transpose] user = find_or_initialize_by(code: row['code']) user.update_attributes!(row.to_hash) end end def open_spreadsheet(file) case File.extname(file.original_filename) when '.csv' then Roo::Csv.new(file.path, file_warning: :ignore) when '.xls' then Roo::Excel.new(file.path, file_warning: :ignore) when '.xlsx' then Roo::Excelx.new(file.path, file_warning: :ignore) else raise 'Unknown file' end end end
Trong method import ngoài việc duyệt từng dòng để lưu vào db còn xử lí thêm việc tìm xem code đã được sử dụng trong database chưa, nếu có rồi thì update các trường khác, chưa thì tạo mới.
II. Exporting Excel
- Trong file mime_type.rb
Mime::Type.register "application/xls", :xls
- Để export dữ liệu ra file xls phải thêm format: xls trong users_controller.rb
def index @users = User.all respond_to do |format| format.html format.xls { render text: @users.to_csv } end end
-Trong models/user.rb method to_csv được mô tả tương tự như đối với file csv:
class << self def to_csv CSV.generate do |csv| csv << column_names all.each do |user| csv << user.attributes.values_at(*column_names) end end end end
Đầu tiên là thêm các trường của User vào dòng đầu, mỗi trường tương ứng 1 cột trong file excel. Các dòng tiếp theo là giá trị các trường tương ứng với dòng đầu của mỗi user trong database.
- Trong view:
<%= link_to 'Export', users_path(format: 'xls') %>
- Kết quả xuất ra file excel: