Как я могу загрузить и проанализировать файл Excel в Rails?

Я хочу загрузить файл Excel, содержащий контактную информацию. Затем я решил обработать его и создать записи для моей модели контактов.

Мое приложение - это приложение Rails.

Я использую paperclip gem на heroku, мне удалось разобрать карты vim в модели Contact, и я ищу что-то подобное, но будет проходить через все строки файла Excel.

Полезны драгоценные камни, упрощающие задачу и образец кода для разбора.

Ответы

Ответ 1

Электронная таблица - лучший синтаксический анализатор Excel, который я нашел до сих пор. Он предлагает довольно много функциональности.

Вы говорите, что вы используете Paperclip для вложений, что хорошо. Однако, если вы храните вложения в S3 (который я предполагаю с тех пор, как вы используете Heroku), синтаксис для передачи файла в электронную таблицу немного отличается, но не сложно.

Вот пример чистого синтаксиса, который можно использовать и не помещать в какие-либо классы или модули, поскольку я не знаю, как вы собираетесь начинать разбор контактов.

# load the gem
require 'spreadsheet'

# In this example the model MyFile has_attached_file :attachment
@workbook = Spreadsheet.open(MyFile.first.attachment.to_file)

# Get the first worksheet in the Excel file
@worksheet = @workbook.worksheet(0)

# It can be a little tricky looping through the rows since the variable
# @worksheet.rows often seem to be empty, but this will work:
0.upto @worksheet.last_row_index do |index|
  # .row(index) will return the row which is a subclass of Array
  row = @worksheet.row(index)

  @contact = Contact.new
  #row[0] is the first cell in the current row, row[1] is the second cell, etc...
  @contact.first_name = row[0]
  @contact.last_name = row[1]

  @contact.save
end

Ответ 2

У меня было аналогичное требование в одном из моих приложений Rails 2.1.0. Я решил это следующим образом:

В папке "lib" я написал такой модуль:

require 'spreadsheet'

module DataReader
  def read_bata(path_to_file)
    begin
      sheet = book.worksheet 0
      sheet.each 2 do |row|
        unless row[0].blank?
          # Create model and save it to DB
          ...
        end
      end
    rescue Exception => e
      puts e
    end
  end
end

Если бы модель загружалась:

class Upload < AR::Base
  has_attached_file :doc, 
    :url => "datafiles/:id",
    :path => ":rails_root/uploads/:id/:style/:basename.:extension"

  # validations, if any
end

Сгенерирован UploadsController, который будет обрабатывать загрузку файла и сохранять его в соответствующем месте. Я использовал Paperclip для загрузки файлов.

class UploadsController < AC
  include DataReader

  def new 
    @upload = Upload.new
  end

  def create
    @upload = Upload.new(params[:upload])

    @upload.save
    file_path = "uploads/#{@upload.id}/original/#{@upload.doc_file_name}"
    @upload.read = DataReader.read_data(file_path)

    # respond_to block
  end
end

Прочитайте об этой библиотеке здесь и здесь. Вы можете сделать соответствующие улучшения и сделать технику работы в Rails 3. Надеюсь, это поможет.