解析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 等