如何在 Roo Rails 中使用 last_row 省略空行
How to omit empty rows using last_row in Roo Rails
我有一个 members
的电子表格,设计如下:
我的目标是上传一些列并排除其他列。在这种情况下,我希望只上传 name
、age
和 email
并排除其他的。我已经能够使用 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
的列表输出中被拒绝
我有一个 members
的电子表格,设计如下:
我的目标是上传一些列并排除其他列。在这种情况下,我希望只上传 name
、age
和 email
并排除其他的。我已经能够使用 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