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

来源:互联网 发布:js 点击复制当前内容 编辑:程序博客网 时间:2024/04/30 04:25


解析CSV





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

[html] view plaincopy在CODE上查看代码片派生到我的代码片
  1. .page-model-form  
  2.   .page-admin-form-info  
  3.     .desc 请先下载 CSV 示例文件,按照给定格式填充数据,然后上传导入  
  4.     %a.download{:href=>'/csv_demo/students.csv'} 下载示例文件  
  5.   
  6.   = flash_info  
  7.   = form_tag "/admin/students/import_from_csv",:method=>:post,:multipart => true do  
  8.     .field  
  9.       %label 选择 CSV 文件  
  10.       = file_field_tag :csv_file  
  11.     .field  
  12.       =submit_tag '确定导入'  

controller

[ruby] view plaincopy在CODE上查看代码片派生到我的代码片
  1. def import_from_csv  
  2.     Student.import_from_csv(params[:csv_file])  
  3.     redirect_to "/admin/students"  
  4.   rescue Exception=>ex  
  5.     flash[:error] = ex.message  
  6.     redirect_to "/admin/students/import_from_csv_page"  
  7.   end  


helpers

[ruby] view plaincopy在CODE上查看代码片派生到我的代码片
  1. module MindpinFormHelper  
  2.   def flash_info  
  3.     re = ''  
  4.   
  5.     [:success:error:notice].each do |kind|  
  6.       info = flash[kind]  
  7.       if !info.blank?  
  8.         re += content_tag(:div, info, :class=>'page-flash-info')  
  9.       end  
  10.     end  
  11.   
  12.     return re.html_safe  
  13.   end  
  14. end  

models

[ruby] view plaincopy在CODE上查看代码片派生到我的代码片
  1. def self.import_from_csv(file)  
  2.     ActiveRecord::Base.transaction do  
  3.       parse_csv_file(file) do |row,index|  
  4.         student = Student.new(  
  5.           :real_name => row[0], :sid => row[1],  
  6.           :user_attributes => {  
  7.             :name => row[2],  
  8.             :email => row[3],  
  9.             :password => row[4],  
  10.             :password_confirmation => row[4]  
  11.           })  
  12.         if !student.save  
  13.           message = student.errors.first[1]  
  14.           raise "第 #{index+1} 行解析出错,可能的错误原因 #{message} ,请修改后重新导入"  
  15.         end  
  16.       end  
  17.     end  
  18.   end  

lib 

[ruby] view plaincopy在CODE上查看代码片派生到我的代码片
  1. def parse_csv_file(file)  
  2.   raise '请先选择 一个 CSV 文件' if file.blank?  
  3.   if File.extname(file.original_filename) != '.csv'  
  4.     raise '你导入的不是一个 CSV 文件'  
  5.   end  
  6.   rows = CSV::parse(file.read)  
  7.   is_utf8 = rows[0].join(",").utf8?  
  8.   rows.each_with_index do |row,index|  
  9.     next if index == 0  
  10.     row = row.map{|v|(v || "").gb2312_to_utf8} if !is_utf8  
  11.     yield row,index  
  12.   end  
  13. end  


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

[ruby] view plaincopy在CODE上查看代码片派生到我的代码片
  1. require 'csv'  
  2.       




同理解析YAML



modles

[ruby] view plaincopy在CODE上查看代码片派生到我的代码片
  1. def self.import_from_yaml(file)  
  2.     text = file.read  
  3.     text = text.gb2312_to_utf8 if !text.utf8?  
  4.     hash = YAML.load(text)  
  5.     ActiveRecord::Base.transaction do  
  6.       categories = _import_from_yaml_by_hash(hash)  
  7.       categories.each{|c|c.move_to_root}  
  8.     end  
  9.   end  
  10.   
  11.   def self._import_from_yaml_by_hash(child_hash)  
  12.     return [] if child_hash.blank?  
  13.   
  14.     child_hash.map do |parent_name,child_name_hash|  
  15.       categories = self._import_from_yaml_by_hash(child_name_hash)  
  16.       parent_category = Category.create(:name=>parent_name)  
  17.       categories.each{|c|c.move_to_child_of(parent_category)}  
  18.       parent_category  
  19.     end  
  20.   end 
0 0