Исключить заголовки при импорте содержимого google spreadsheet с roo

Я создал задачу с граблями для импорта пользователей из Google Sheet. Поэтому я использую драгоценный камень Ру. Пока все работает, но я не могу заставить его работать без импорта первой строки (заголовков).

Это мой код:

require 'roo'

namespace :import do
  desc "Import users from Google Sheet"
  task users: :environment do

    @counter = 0
    url = 'https://docs.google.com/spreadsheets/d/{mycode}/export?format=xlsx'
    xlsx = Roo::Spreadsheet.open(url, extension: :xlsx, headers: true)
    xlsx.each do |row|
        n = User.where(name:row[0]).first
        user = User.find_or_create_by(id: n)
        user.update(
                     name:row[0],
                     country_id:row[6]
                   )
        user.save!
        puts user.name
        @counter += 1
      end
     puts "Imported #{@counter} lines."
    end
end
1
0
475
2

Ответы 2

Когда вы открываете лист, ваш код говорит headers: true. Вы пытались превратить его в ложь? Или вы говорите, что это не работает, если установлено значение false?

Кроме того, вы используете .each несколько иначе, чем пример в документации. В документе показан хеш с ключами, полученными из заголовков. Вы используете нотацию массива [n]. Это работает?

Обновлено:

Попробуйте использовать .each способом, более похожим на то, что написано в документации:

xlsx.each(name: 'Name', country_id: 'Country ID') do |row|
  n = User.where(name: row[:name]).first
  ...
end

Строки «Имя» и «Идентификатор страны» являются лишь примерами; они должны быть текстом любого заголовка столбца, имеющего информацию name и country_id.

Я пробовал true, false, first_row, но пока ничего не работает.

dasbabs 13.09.2018 20:00

Отредактировал свой ответ другим предложением. Неудивительно, что headers: false не работает; он указан в документации как опция для .parse, но вы пытаетесь использовать его в .open.

John Skiles Skinner 13.09.2018 20:12

Спасибо! Я повторно использовал .each из старого проекта, в который я импортировал из CSV вместо электронной таблицы. Я переписал его, но, к сожалению, заголовки все еще импортированы.

dasbabs 13.09.2018 21:04

Хорошо, ты мог бы просто пропустить первую строку, не так ли? xlsx[1..-1].each

John Skiles Skinner 13.09.2018 21:08

Я был так сосредоточен на заголовках, что даже не думал о том, чтобы полностью пропустить первую строку. К сожалению, ваше предложение приводит к следующей ошибке NoMethodError: undefined method [] for #<Roo::Excelx:0x00007f9c2858bd50>

dasbabs 13.09.2018 21:31

Есть способ пропустить заголовки, он использует метод: each_row_streaming(offset: 1).

Он вернет массив со строками, пропуская заголовок, поэтому вам нужно получить значение с помощью метода .value. В документации укажите его для объектов Excelx::Cell, но он работает и для объектов Roo::Spreadsheet. Пример документация:

xlsx.each_row_streaming(offset: 1) do |row| # Will exclude first (inevitably header) row
  puts row.inspect # Array of Excelx::Cell objects
end

Другие вопросы по теме