12/08/2018, 13:09

Export and Import excel file in Ruby on Rails framework - Phần 1

Theo sự phát triền của công nghệ thông tin việc 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. Nó không chỉ tiện cho qúa trình trao đổi thông tin của người dùng mà còn được lập trình viên sử ...

Theo sự phát triền của công nghệ thông tin việc 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. Nó không chỉ tiện cho qúa trình trao đổi thông tin của người dùng mà còn được lập trình viên sử dụng để thao tác với dữ liệu nhanh chóng.

Vậy làm sao để xây dựng được chức năng này hoàn hảo? Có những cách nào phù hợp với yêu cầu chức năng mà tiện nhất cho lập trình viên?

Bài viết xin được chia làm 2 phần giới thiệu một số phương pháp export, import dữ liệu ra file với định dạng xls cùng đó sẽ đưa ra đánh gía khách quan để người dùng lựa chọn.

Export excel file bằng thiết kế XML

1. Thêm thư viện "csv" sẵn có của framework trong file config/application.rb

require "csv"

2. Thiết kế giao diện cho button download tại controller home_controller.rb action index

<div class="row">
  <div class="container">
    <table class="table">
      <tr>
        <td>ID</td>
        <td>Student Name</td>
        <td>Student Age</td>
      </tr>
      <% @students.each do |student| %>
        <tr>
          <td><%= student.id %></td>
          <td><%= student.name %></td>
          <td><%= student.age %></td>
        </tr>
      <% end %>
    </table>
  </div>
  <div class="container">
    <p>
      Download:
      <%= link_to "Excel_By_Xml", xml_index_path(format: "xls") %>
    </p>
  </div>
</div>

Trong đó:

  • xml_index_path: Là đường dẫn tới controller xử lý export, thường sẽ là action index.
  • format: "xls": Định dạng file sau khi được tải về(bắt buộc).

3. Xây dựng controller controller/xml_controller.rb

class XmlController < ApplicationController
  def index
  	@students = Student.order(:name)
	  respond_to do |format|
	    format.html
	    format.xls { send_data @students.to_xls(col_sep: "	") }
	  end
  end
end

4. to_xls là method của class Student dùng để convert data được khai báo trong model/student.rb:

class Student < ActiveRecord::Base
  def self.to_xls(options = {})
    CSV.generate(options) do |csv|
      csv << column_names
      all.each do |student|
        csv << student.attributes.values_at(*column_names)
      end
    end
  end
end

5. Kết qủa:

Screenshot from 2016-01-24 14:49:57.png

Giao diện của file xml.xls

Screenshot from 2016-01-24 14:53:04.png

6. Nhận xét:

Phương pháp này sử dụng thư viện có sẵn csv của framework nên rất dễ ràng sử dụng, tốc độ xử lý nhanh. Thiết kế giao diện dễ ràng với định dạng xml. Tuy vậy, chú ý cần tìm được format chuẩn của định dạng xls.

<?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">

Do vậy, cách này thường được sử dụng khi xuất data ra file xls để đọc và không import ngược lại hệ thống vì có thể không tương thích định dạng với phương pháp import data.

Export excel file bằng gem "to_xls-Rails"

Để khắc phục điểm bất lợi của phương pháp trên xin được giới thiệu gem "to_xls-rails".

Đối với chức năng export xls không yêu cầu nhiều xử lý khó với file xuất ra, định dạng chuẩn xlsx cho cả hai chiều import, export cộng với một số setting đơn giản thì nên lựa chọn phương pháp này.

1. Thêm gem "to_xls-rails" trong Gemfile:

gem 'to_xls-rails'

2. Run bundle install trên terminal rồi khời động lại server rails s

bundle install
rails s

3. Thêm button download file với đường url tới controller to_xls_path xử lý export và format: xls tương tự như phương pháp trên trong file view/home/index.html.erb.

  <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") %>
    </p>
  </div>

4. Xây dựng controller controller/to_xls_controller.rb

class ToXlsController < ApplicationController
  def index
    @students = Student.all
    respond_to do |format|
      format.html
      format.xls {
        filename = "Student-#{Time.now.strftime("%Y%m%d%H%M%S")}.xls"
        send_data(@students.to_xls,
          type: "text/xls; charset=utf-8; header=present",
          filename: filename)
      }
    end
  end
end

5. Kết Qủa:

Screenshot from 2016-01-24 15:50:28.png

Kết qủa trong file export

Screenshot from 2016-01-24 15:51:25.png

6. Giới thiệu một số setting mà gem cung cấp.

  • object.to_xls(:only => [:title, :body]): Chỉ export ra hai trường title và body của object.

  • object.to_xls(:except => [:id]): Bỏ qua trường id của object khi export.

  • [ { key1: 'value1', key2: 'value2' }, { key3: 'value3', key4: 'value4' } ].to_xls: Có thể export data ở dạng Hash

  • prepend: Thêm dữ liệu vào file export dưới dạng mảng

    VD: [["Col 0, Row 0", "Col 1, Row 0"], ["Col 0, Row 1"]]

7. Kết luận Về cơ bản gem "to_xls" đã khắc phục được những vấn đề mà phương pháp sử dụng xml gặp phải đồng thời đáp ừng được nhu cầu người dùng chức năng này một cách đơn giản. Tuy nhiên để xử lý được những yêu cầu khó hơn khi export file cùng với setting phức tạp thì gem 'xls' còn rất nhiều hạn chế.

Trong phần này mới chỉ đề cấp tới 2 phương pháp đơn giản để xây dựng chức năng export file xls trong phần 2 xin tiếp tục đưa ra phương pháp đầy đủ, hoàn thiện và nâng cao hơn để xây dựng chức năng này.

  • Export excel file bằng gem "randym/axlsx"
  • Import excel file bằng gem "roo"

Rất mong nhận được ủng hộ và đóng góp về bài viết.

Thank you for reading !!!

0