现在的位置: 首页 > 综合 > 正文

使用 Ruby 解析CSV文件&YAML文件

2018年09月09日 ⁄ 综合 ⁄ 共 1980字 ⁄ 字号 评论关闭

解析CSV

haml  (students.csv文件位置在在public/csv_demo/students.csv)

.page-model-form
  .page-admin-form-info
    .desc 请先下载 CSV 示例文件,按照给定格式填充数据,然后上传导入
    %a.download{:href=>'/csv_demo/students.csv'} 下载示例文件

  = flash_info
  = form_tag "/admin/students/import_from_csv",:method=>:post,:multipart => true do
    .field
      %label 选择 CSV 文件
      = file_field_tag :csv_file
    .field
      =submit_tag '确定导入'

controller

def import_from_csv
    Student.import_from_csv(params[:csv_file])
    redirect_to "/admin/students"
  rescue Exception=>ex
    flash[:error] = ex.message
    redirect_to "/admin/students/import_from_csv_page"
  end

helpers

module MindpinFormHelper
  def flash_info
    re = ''

    [:success, :error, :notice].each do |kind|
      info = flash[kind]
      if !info.blank?
        re += content_tag(:div, info, :class=>'page-flash-info')
      end
    end

    return re.html_safe
  end
end

models

def self.import_from_csv(file)
    ActiveRecord::Base.transaction do
      parse_csv_file(file) do |row,index|
        student = Student.new(
          :real_name => row[0], :sid => row[1],
          :user_attributes => {
            :name => row[2],
            :email => row[3],
            :password => row[4],
            :password_confirmation => row[4]
          })
        if !student.save
          message = student.errors.first[1]
          raise "第 #{index+1} 行解析出错,可能的错误原因 #{message} ,请修改后重新导入"
        end
      end
    end
  end

lib 

def parse_csv_file(file)
  raise '请先选择 一个 CSV 文件' if file.blank?
  if File.extname(file.original_filename) != '.csv'
    raise '你导入的不是一个 CSV 文件'
  end
  rows = CSV::parse(file.read)
  is_utf8 = rows[0].join(",").utf8?
  rows.each_with_index do |row,index|
    next if index == 0
    row = row.map{|v|(v || "").gb2312_to_utf8} if !is_utf8
    yield row,index
  end
end

lib我们在config/application.rb中引入 

require 'csv'
    

同理解析YAML

modles

def self.import_from_yaml(file)
    text = file.read
    text = text.gb2312_to_utf8 if !text.utf8?
    hash = YAML.load(text)
    ActiveRecord::Base.transaction do
      categories = _import_from_yaml_by_hash(hash)
      categories.each{|c|c.move_to_root}
    end
  end

  def self._import_from_yaml_by_hash(child_hash)
    return [] if child_hash.blank?

    child_hash.map do |parent_name,child_name_hash|
      categories = self._import_from_yaml_by_hash(child_name_hash)
      parent_category = Category.create(:name=>parent_name)
      categories.each{|c|c.move_to_child_of(parent_category)}
      parent_category
    end
  end

解析Excel还有其他许多方法 roo,axlsx 等

抱歉!评论已关闭.