scinote-web/app/services/spreadsheet_parser.rb

69 lines
1.8 KiB
Ruby
Raw Normal View History

2019-09-05 14:35:11 +08:00
# frozen_string_literal: true
class SpreadsheetParser
# Based on file's extension opens file (used for importing)
def self.open_spreadsheet(file)
2019-09-23 19:33:02 +08:00
if file.class == ActionDispatch::Http::UploadedFile
filename = file.original_filename
file_path = file.path
else
filename = file.filename.to_s
file_path = file.service_url
end
case File.extname(filename)
when '.csv'
Roo::CSV.new(file_path, extension: :csv)
when '.tsv'
Roo::CSV.new(file_path, csv_options: { col_sep: "\t" })
when '.txt'
# This assumption is based purely on biologist's habits
Roo::CSV.new(file_path, csv_options: { col_sep: "\t" })
when '.xlsx'
# Roo Excel parcel was replaced with Creek, but it can be enabled back,
# just swap lines below. But only one can be enabled at the same time.
Roo::Excelx.new(file_path)
# Creek::Book.new(file_path).sheets[0]
else
raise TypeError
end
end
def self.spreadsheet_enumerator(sheet)
if sheet.is_a?(Roo::CSV)
sheet
elsif sheet.is_a?(Roo::Excelx)
sheet.each_row_streaming
else
sheet.rows
end
end
def self.first_two_rows(sheet)
rows = spreadsheet_enumerator(sheet)
header = []
columns = []
i = 1
rows.each do |row_values|
# Creek XLSX parser returns Hash of the row, Roo - Array
row = parse_row(row_values, sheet)
header = row if i == 1 && row
columns = row if i == 2 && row
i += 1
break if i > 2
end
return header, columns
end
def self.parse_row(row, sheet)
# Creek XLSX parser returns Hash of the row, Roo - Array
if row.is_a?(Hash)
row.values.map(&:to_s)
elsif sheet.is_a?(Roo::Excelx)
row.map { |cell| cell.value.to_s }
else
row.map(&:to_s)
end
end
end