CSV 导入导出详解编程语言

 

 def export 
   csv_string = FasterCSV.generate do |csv| 
     csv << ["name","detail","price","num","category_id"] 
     Product.find(:all).each do |p| 
       csv << [p.name, p.detail, p.price, p.num, p.category_id] 
     end 
   end 
   csv_string = NKF.nkf("-s",csv_string) 
   send_data csv_string,   
   :type=>'text/csv;',:disposition => "attachment; filename=product.csv"  
 end 
 
def self.import_db(file, model_str) 
    field_names = eval(model_str).column_names 
    field_names.delete("id") 
    field_names.delete("deleted_at") 
    params_value = {} 
    file_path = "#{RAILS_ROOT}/tmp/csv/" 
    Dir.mkdir(file_path,0777) unless File.exist?(file_path) 
    file_name = "temp.csv" 
    data_utf = file.read 
    File.open(file_path + file_name , 'wb+') do |f| 
      f.write(data_utf) 
    end 
    key_id = Time.now.strftime('%Y%m%d%H%M%S')  
    system(" nkf -w #{file_path + file_name} > #{file_path + key_id + file_name}") 
    messages = [] 
    f_path = file_path + key_id + file_name 
    index = -1   
    eval(model_str).transaction do 
      FasterCSV.foreach(f_path) do |row| 
        index += 1 
        next if index == 0 
        #开始垃圾处理,对象垃圾回收站,GC.start 
        GC.start if index % 50 == 0 
        row.each do |r| 
          r = r.to_s.toutf8 unless r.blank? 
      end 
        field_names.each_with_index { |name, name_index| params_value["#{name}"] = row[name_index]} 
        model = eval(model_str).new(params_value) 
        if model.valid? 
          model.save! 
        else 
          messages << "第#{index}行#{model.errors.full_messages}"            
        end 
      end 
    end 
    FileUtils.rm_rf(file_path) if File.exists?(file_path) 
    return messages 
  end 

 

def export     
    send_data Export.export_csv("Product"), :type=>'text/csv',  
                                            :disposition => "attachment", 
                                            :filename => "product_#{Time.now.strftime('%Y%m%d%H%M%S')}.csv"  
  end 
 
def self.export_csv(model) 
    #动态取得model 
    field_names = eval(model).column_names 
    field_names.delete("id") 
    field_names.delete("deleted_at") 
    csv_string = FasterCSV.generate do |csv| 
      #得到所有的modle字段 
      csv << field_names 
      eval(model).find(:all).each do |m| 
        csv << field_names.collect {|name| m.send(name)} 
      end 
    end 
    csv_string = NKF.nkf("-w", csv_string) 
  end

 

 

使用<%= file_field_tag ‘file’ %>,在form表单中加入action指向csv_import,记得加上:enctype => “multipart/form-data”哦,不然不能上传文件。

<% form_for :attachment, :url => { :controller => "attachment", :action => "import_to_db" },  
                                             :html => { :multipart => true } do |f| %> 
    csv导入:<%= f.file_field :csv %> 
    <br /> 
    <%= submit_tag "导入csv" %> 
<% end %>

 

def self.import_to_db(file) 
    file_path = "#{RAILS_ROOT}/tmp/csv/"  #创建文件夹  
    FileUtils.mkdir(file_path) if !File.exist?(file_path) 
    #临时文件命名,不能有非法字符,比如"()"因为在linux下文件名不支持"()"等特殊符号    
    file_name = "temp.csv" 
    begin 
      data_utf = file.read#Iconv.conv("UTF-8//IGNORE","shift_jis//IGNORE",params[:csv_file].read) 
      File.open(file_path + file_name , 'wb') do |f| 
        f.write(data_utf) 
        f.close 
      end 
    ensure   
      file.close 
    end 
    key_id = UUID.random_create().to_s  
    system("nkf -Lu -S -w80 #{file_path + file_name} > #{file_path + key_id + file_name}") 
    messages = [] 
    f_path = file_path + key_id + file_name 
    index = -1   
    Attachment.transaction do 
      FasterCSV.foreach(f_path) do |row| 
        flag = true 
        index += 1 
        next if index == 0 
        GC.start if index % 50 == 0 
        row.each do |r| 
          r = r.to_s.toutf8 unless r.blank? 
        end 
        attachment = Attachment.new 
        attachment.id = row[0] 
        attachment.type = row[1] 
        attachment.owner_id = row[2] 
        attachment.url = row[3] 
        attachment.name = row[4] 
        attachment.created_at = row[5] 
        attachment.updated_at = row[6] 
        attachment.deleted_at = row[7] 
        if attachment.save 
          messages << "第#{index}行#{attachment.errors.full_messages}" 
        end 
      end 
    end 
    FileUtils.rm_rf(file_path) if File.exists?(file_path) 
    return messages 
  end

 

 

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/13410.html

(0)
上一篇 2021年7月19日
下一篇 2021年7月19日

相关推荐

发表回复

登录后才能评论