Как я могу загрузить и проанализировать файл 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. Надеюсь, это поможет.