Как читать данные файла .xlsx с активным хранилищем

У меня есть этот класс, и я использую активное хранилище

class DataSheet < ApplicationRecord
  belongs_to :admin

  has_one_attached :excel_file
  after_save :create_user
end

Я знаю, что есть много драгоценных камней creek, write_xlsx_rails, roo для чтения или записи файла .xlsx, но все они требуют физического расположения файла. ранее я использовал creek gem для чтения файла .xlsx, но мне нужно сохранить этот файл локально, например.

class LocalFileUploader


attr_reader :file

    def initialize(file = nil)
        @file = file
    end

    def save
        file_path = Rails.root.join('storage', file.original_filename)
        IO.copy_stream(file.path, file_path)
      return file_path.to_s
    end

end

Теперь я использую активное хранилище, в котором файл .xlsx хранится как двоичный. Я не смог найти способ прочитать этот файл как файл xlsx. Хотя активное хранилище предоставляет метод download для получения двоичных данных файла.

pry(#<DataSheet>)> self.excel_file
=> #<ActiveStorage::Attached::One:0x007f9db0607750
 @dependent=:purge_later,
 @name="excel_file",
 @record=#<DataSheet:0x007f9db811ba40 id: 3, admin_id: 1, created_at: Mon, 28 May 2018 01:33:06 UTC +00:00, updated_at: Mon, 28 May 2018 01:33:06 UTC +00:00>>

[3] pry(#<DataSheet>)> self.excel_file.blob
=> #<ActiveStorage::Blob:0x007f9db81125f8
 id: 6,
 key: "TBitz1dEzma2R2uTgtEoJ7X1",
 filename: "faizabad 1424.xlsx",
 content_type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
 metadata: {"identified"=>true},
 byte_size: 374211,
 checksum: "/shAXf0kEnYV4DGl0z3fng==",
 created_at: Mon, 28 May 2018 01:33:06 UTC +00:00>

[4] pry(#<DataSheet>)> SimpleXlsxReader.open self.excel_file.blob
TypeError: no implicit conversion of ActiveStorage::Blob into String
from /home/rotlu_crush/.rvm/gems/ruby-2.4.1/gems/rubyzip-1.2.1/lib/zip/file.rb:73:in `size?'
[5] pry(#<DataSheet>)> SimpleXlsxReader.open self.excel_file.blob.download
  Disk Storage (0.6ms) Downloaded file from key: TBitz1dEzma2R2uTgtEoJ7X1
ArgumentError: string contains null byte
from /home/rotlu_crush/.rvm/gems/ruby-2.4.1/gems/rubyzip-1.2.1/lib/zip/file.rb:73:in `size?'

Я где-то читал пример чтение данных файла csv с активным хранилищем путем разбора этих двоичных данных в формате csv.

CSV.parse(materials_upload.csv_file.download, headers: true) do |row|
  # ...
end

Есть ли способ прочитать файл excel с активным хранилищем?


person TheVinspro    schedule 28.05.2018    source источник


Ответы (2)


Rails 6 добавит ActiveStorage::Blob#open, который загружает большой двоичный объект. во временный файл:

data_sheet.excel_file.open do |file|
  # Operate on the file
end

Вы можете собрать Rails из GitHub, чтобы использовать эту функцию уже сегодня:

gem "rails", github: "rails/rails"
person George Claghorn    schedule 28.05.2018
comment
Хорошо, но как это сделать в rails 5? - person A. Askarov; 14.04.2020

Вы можете использовать gem xsv, а затем просто позвонить

x = Xsv::Workbook.open(blob.download)

sheet = x.sheets[0]

# Iterate over rows
sheet.each_row do |row|
  row # => ["header1", "header2"], etc.
end
person TomiD    schedule 21.05.2020