使用 Ruby 解析CSV文件&YAML文件
haml (students.csv文件位置在在public/csv_demo/students.csv)
[html]
.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
[ruby]
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
[ruby]
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
[ruby]
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
[ruby]
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中引入
[ruby]
require 'csv'
require File.join(Rails.root, 'lib/mindpin_global_methods.rb')
同理解析YAML
modles
[ruby]
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
补充:综合编程 , 其他综合 ,