Как мне заполнить таблицу из таблицы Excel в Rails? - PullRequest
3 голосов
/ 15 июня 2010

У меня есть простая таблица Excel с 4 столбцами, которая сопоставляет университеты с их идентификационными кодами для поиска.Файл довольно большой (300 КБ).

Мне нужно найти способ превратить эти данные в заполненную таблицу в моем приложении Rails.Суть в том, что это документ, который время от времени обновляется, поэтому он не может быть просто разовым решением.В идеале, это был бы какой-нибудь скрипт ruby, который автоматически считывал файл и создавал записи, поэтому, когда мы получим новую версию по электронной почте, мы можем просто обновить ее автоматически.Я на Heroku, если это вообще имеет значение.

Как мне добиться чего-то подобного?

Ответы [ 2 ]

2 голосов
/ 16 июня 2010

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

Так, например, вот как прочитать все строки из файлаиспользование старого, но все еще действующего FasterCSV gem

data = FasterCSV.read('lib/tasks/data.csv')
columns = data.remove(0)
unique_column_index = -1#The index of a column that's always unique per row in the spreadsheet
data.each do | row |
  r = Record.find_or_initialize_by_unique_column(row[unique_column_index])
  columns.each_with_index do | index, column_name |
    r[column_name] = row[index]
  end
  r.save! rescue => e Rails.logger.error("Failed to save #{r.inspect}")
end

Это действительно зависит от наличия уникального столбца в исходной электронной таблице.

Есливы помещаете это в задачу rake, затем можете подключить его к вашему сценарию развертывания Capistrano, так что он будет запускаться каждый раз при развертывании.find_or_initialize должен гарантировать, что вы не должны получать дубликаты записей.

1 голос
/ 16 июня 2010

С парсингом новых файлов Excel не так уж много проблем с использованием Hpricot Это даст вам двумерный массив:

require 'hpricot'

doc  = open("data.xlsx") { |f| Hpricot(f) }
rows = doc.search('row')
rows = rows[1..rows.length] # Skips the header row

rows = rows.map do |row|
    columns = []
    row.search('cell').each do |cell|
        # Excel stores cell indexes rather than blank cells
        next_index          = (cell.attributes['ss:Index']) ? (cell.attributes['ss:Index'].to_i - 1) : columns.length
        columns[next_index] = cell.search('data').inner_html
    end
    columns
end
...