如何在 Roo Rails 中使用 last_row 省略空行

How to omit empty rows using last_row in Roo Rails

我有一个 members 的电子表格,设计如下:

我的目标是上传一些列并排除其他列。在这种情况下,我希望只上传 nameageemail 并排除其他的。我已经能够使用 slice 方法实现此目的,如下所示:

def load_imported_members
    spreadsheet = open_spreadsheet
    spreadsheet.default_sheet = 'Worksheet'
    header = spreadsheet.row(1)
    (2..spreadsheet.last_row).map do |i|
      row = Hash[[header, spreadsheet.row(i)].transpose]
      member = Member.find_by_id(row["id"]) || Member.new
      member.attributes = row.to_hash.slice("id", "name", "age", "email")
      member
    end
  end

问题是 last_row 考虑了直到最后一行 (13) 的所有行,并且由于对表单进行了验证,因此由于空行 (不应该考虑)。有没有一种方法可以像我所做的那样只上传特定的列,但仅限于有数据的行?

感谢您提出这个问题。我从这个问题中学到了一些东西。

我已将您的答案列入候选名单[注意:使用'ROO' gem]

def load_imported_members(member)
  spreadsheet = open_spreadsheet(member)
  spreadsheet.each do |records|
  record = @spreadsheet ? Hash[[@header, @spreadsheet.row(records)].transpose] : Hash[records] # transpose for xlsx records and 
  attributes =  {id: record['id'], name: record['name'], email: record['email'], age: record['age']}
  member_object = Member.new(attributes)
  if member_object.valid?
    if Member.find(attributes[:id])
      Member.find(attributes[:id]).update(attributes)
    else
      member_object.save
    end
  end
 end
end

您可以使用 Roo gem 解析您上传的文件。

def self.open_spreadsheet(member)
case File.extname(member.file.original_filename)
when ".csv" then
  Roo::CSV.new(member.file.expiring_url, csv_options: {headers: true, skip_blanks: true, header_converters: ->(header) { header.strip }, converters: ->(data) { data ? data.strip : nil }})
when ".xlsx", ".xls" then
  @spreadsheet = Roo::Spreadsheet.open(member.file.expiring_url)
  @header = @spreadsheet.row(1)
  (2..@spreadsheet.last_row)
 end
end

这里我使用了 s3 上传 url 即 expiring_url。希望这会有所帮助。我没有测试过。抱歉,小错误。

如果您对姓名、电子邮件和年龄进行了验证。这一定会帮助你..

您可能想像这样链接 map 调用 reject 过滤器 example

您可能只需要将 map 行更改为此(假设缺少的行都与上面的行相同): (2..spreadsheet.last_row).reject{|i| spreadsheet.row(i)[0] }.map do |i|

这是假设空白行 return 为 nil,并且空白行将始终使所有四个所需字段为空白,如图所示。 reject 调用测试以查看 id 列 spreadsheet.row(i)[0] 是否为零,如果是,则该项目从提供给 map

的列表输出中被拒绝