+9

Export Csv Trong Rails

Bài viết này sẽ giới thiệu một chức năng mà mọi người thường thấy trong các ứng dụng Web đó là Export Csv(Excel).

Mình sẽ demo một ví dụ đơn giản là export dữ liệu người dùng bao gồm các thông tin: tên, số điện thoại, địa chỉ.

Tạo mới project và model User

Tạo 1 project mới

rails new export_csv

Tạo model User

rails g model user name:string address:text phone:string

Migrate

rails db:migrate

Tạo controller, view và thêm route

Tạo home controller

class HomeController < ApplicationController
  def index
  end
end

Tạo mới export users controller

# app/controller/export_users_controller.rb
class ExportUsersController < ApplicationController
  def index
  end
end

Thêm route, ở đây chúng ta chỉ sử dụng method index.

# config/routes.rb
Rails.application.routes.draw do
  root "home#index"
  resources :export_users, only: :index
end

View

# app/views/home/index.html.erb
<h1>Export csv</h1>

Tạo service generate CSV

Chúng ta sẽ sử dụng gem CSV có sẵn của Ruby nên cần require vào trong service

Service sẽ có 2 tham số truyền vào:

  • objects: data lấy ra từ database
  • attributes: các field cần export
# app/services/export_csv_service.rb
require "csv"

class ExportCsvService
  def initialize objects, attributes
    @attributes = attributes
    @objects = objects
  end

  def perform
  end

  private
  attr_reader :attributes, :objects
end

Tạo header cho file csv, sử dụng I18n nhé

# app/services/export_csv_service.rb
require "csv"

class ExportCsvService
  def initialize objects, attributes
    @attributes = attributes
    @objects = objects
    @header = attributes.map { |attr| I18n.t("header_csv.#{attr}") }
  end

  def perform
  end

  private
  attr_reader :attributes, :objects, :header
end

Tạo file csv trong hàm perform chúng ta sẽ được 1 service hoàn chỉnh

# app/services/export_csv_service.rb
require "csv"

class ExportCsvService
  def initialize objects, attributes
    @attributes = attributes
    @objects = objects
    @header = attributes.map { |attr| I18n.t("header_csv.#{attr}") }
  end

  def perform
    CSV.generate do |csv|
      csv << header
      objects.each do |object|
        csv << attributes.map{ |attr| object.public_send(attr) }
      end
    end
  end

  private
  attr_reader :attributes, :objects, :header
end

Khai báo các field export trong model

# app/models/user.rb
class User < ApplicationRecord
  CSV_ATTRIBUTES = %w(name address phone).freeze
end

Gọi service export csv trong controller

Ở đây mình sẽ lấy hết User, các bạn có thể query theo ý thích

# app/controllers/export_users_controller.rb
class ExportUsersController < ApplicationController
  def index
    csv = ExportCsvService.new User.all, User::CSV_ATTRIBUTES
    respond_to do |format|
      format.csv { send_data csv.perform,
        filename: "users.csv" }
    end
  end
end

Thêm nút export và I18n cho header

# app/views/home/index.html.erb

<h1><%= t ".title" %></h1>
<%= link_to t(".link_export"), export_users_path(format: :csv) %>
# config/locales/en.yml
en:
  home:
    index:
      link_export: Export Users
      title: Export CSV
  header_csv:
    name: Full Name
    address: Address
    phone: Phone Number

Ok vậy là demo của mình đã hoàn thành đây là file csv sau khi export

source: https://github.com/cuongtobi/export_csv

library: https://github.com/ruby/csv

Thank for reading!!!!!!


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí