diff --git a/lib/roo/excelx.rb b/lib/roo/excelx.rb index 91ebc1e0..9280c0ac 100755 --- a/lib/roo/excelx.rb +++ b/lib/roo/excelx.rb @@ -395,16 +395,28 @@ def extract_images(entries, tmpdir) def process_zipfile(zipfilename_or_stream) @sheet_files = [] - unless is_stream?(zipfilename_or_stream) - zip_file = Zip::File.open(zipfilename_or_stream) + entries = if is_stream?(zipfilename_or_stream) + begin + zip_stream = Zip::InputStream.new(zipfilename_or_stream) + entries = [] + while (entry = zip_stream.get_next_entry) + entries << entry + end + + entries + rescue Zip::GPFBit3Error + zip_file = Zip::File.open_buffer(zipfilename_or_stream) + zip_file.to_a + end else - zip_file = Zip::CentralDirectory.new - zip_file.read_from_stream zipfilename_or_stream + zip_file = Zip::File.open(zipfilename_or_stream) + zip_file.to_a end - process_zipfile_entries zip_file.to_a.sort_by(&:name) + process_zipfile_entries entries.sort_by(&:name) end + def process_zipfile_entries(entries) # NOTE: When Google or Numbers 3.1 exports to xlsx, the worksheet filenames # are not in order. With Numbers 3.1, the first sheet is always diff --git a/spec/lib/roo/excelx_spec.rb b/spec/lib/roo/excelx_spec.rb index 7cc9b13e..a69266e5 100755 --- a/spec/lib/roo/excelx_spec.rb +++ b/spec/lib/roo/excelx_spec.rb @@ -56,6 +56,14 @@ expect(subject).to be_a(Roo::Excelx) end end + + context 'given a stream input' do + let(:path) { StringIO.new(File.read('test/files/simple_spreadsheet.xlsx')) } + + it 'creates an instance' do + expect(subject).to be_a(Roo::Excelx) + end + end end describe '#cell' do