Skip to content

Commit

Permalink
Rebase of esergion-images #397
Browse files Browse the repository at this point in the history
Rebase of #397

Merge branch 'images' of https://github.com/esergion/roo into esergion-images
  • Loading branch information
stevendaniels committed Feb 14, 2018
2 parents 62b033c + ce8d1b2 commit fc0f4eb
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 3 deletions.
22 changes: 21 additions & 1 deletion lib/roo/excelx.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ class Excelx < Roo::Base
require 'roo/excelx/sheet_doc'
require 'roo/excelx/coordinate'
require 'roo/excelx/format'
require 'roo/excelx/images'

delegate [:styles, :workbook, :shared_strings, :rels_files, :sheet_files, :comments_files] => :@shared
delegate [:styles, :workbook, :shared_strings, :rels_files, :sheet_files, :comments_files, :image_rels, :image_files] => :@shared
ExceedsMaxError = Class.new(StandardError)

# initialization and opening of a spreadsheet file
Expand Down Expand Up @@ -99,6 +100,11 @@ def sheet_for(sheet)
@sheets_by_name[sheet]
end

def images(sheet = nil)
images_names = sheet_for(sheet).images.map(&:last)
images_names.map { |iname| image_files.find { |ifile| ifile[iname] } }
end

# Returns the content of a spreadsheet-cell.
# (1,1) is the upper left corner.
# (1,1), (1,'A'), ('A',1), ('a',1) all refers to the
Expand Down Expand Up @@ -378,6 +384,15 @@ def extract_sheets_in_order(entries, sheet_ids, sheets, tmpdir)
end
end

def extract_images(entries, tmpdir)
img_entries = entries.select { |e| e.name[/media\/image([0-9]+)/] }
img_entries.each do |entry|
path = "#{@tmpdir}/roo#{entry.name.gsub(/xl\/|\//, "_")}"
image_files << path
entry.extract(path)
end
end

# Extracts all needed files from the zip file
def process_zipfile(zipfilename_or_stream)
@sheet_files = []
Expand Down Expand Up @@ -411,6 +426,7 @@ def process_zipfile_entries(entries)
sheet_ids = extract_worksheet_ids(entries, "#{@tmpdir}/roo_workbook.xml")
sheets = extract_worksheet_rels(entries, "#{@tmpdir}/roo_workbook.xml.rels")
extract_sheets_in_order(entries, sheet_ids, sheets, @tmpdir)
extract_images(entries, @tmpdir)

entries.each do |entry|
path =
Expand All @@ -437,6 +453,10 @@ def process_zipfile_entries(entries)
# drawings, etc.
nr = Regexp.last_match[1].to_i
rels_files[nr - 1] = "#{@tmpdir}/roo_rels#{nr}"
when /drawing([0-9]+).xml.rels$/
# Extracting drawing relationships to make images lists for each sheet
nr = Regexp.last_match[1].to_i
image_rels[nr -1] = "#{@tmpdir}/roo_image_rels#{nr}"
end

entry.extract(path) if path
Expand Down
26 changes: 26 additions & 0 deletions lib/roo/excelx/images.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
require 'roo/excelx/extractor'

module Roo
class Excelx
class Images < Excelx::Extractor

# Returns: Hash { id1: extracted_file_name1 },
# Example: { "rId1"=>"roo_media_image1.png",
# "rId2"=>"roo_media_image2.png",
# "rId3"=>"roo_media_image3.png" }
def list
@images ||= extract_images_names
end

private

def extract_images_names
return {} unless doc_exists?

Hash[doc.xpath('/Relationships/Relationship').map do |rel|
[rel['Id'], "roo" + rel['Target'].gsub(/\.\.\/|\//, '_')]
end]
end
end
end
end
4 changes: 3 additions & 1 deletion lib/roo/excelx/shared.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ class Excelx
# reduce memory usage and reduce the number of objects being passed
# to various inititializers.
class Shared
attr_accessor :comments_files, :sheet_files, :rels_files
attr_accessor :comments_files, :sheet_files, :rels_files, :image_rels, :image_files
def initialize(dir, options = {})
@dir = dir
@comments_files = []
@sheet_files = []
@rels_files = []
@options = options
@image_rels = []
@image_files = []
end

def styles
Expand Down
6 changes: 5 additions & 1 deletion lib/roo/excelx/sheet.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@ class Excelx
class Sheet
extend Forwardable

delegate [:styles, :workbook, :shared_strings, :rels_files, :sheet_files, :comments_files] => :@shared
delegate [:styles, :workbook, :shared_strings, :rels_files, :sheet_files, :comments_files, :image_rels] => :@shared

attr_reader :images

def initialize(name, shared, sheet_index, options = {})
@name = name
@shared = shared
@sheet_index = sheet_index
@images = Images.new(image_rels[sheet_index]).list
@rels = Relationships.new(rels_files[sheet_index])
@comments = Comments.new(comments_files[sheet_index])
@sheet = SheetDoc.new(sheet_files[sheet_index], @rels, shared, options)
Expand Down
13 changes: 13 additions & 0 deletions spec/lib/roo/excelx_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,19 @@
expect(subject.sheet(0).excelx_format(2,1)).to eq 'm/d/yyyy" "h:mm:ss" "AM/PM'
end
end

describe 'images' do
let(:path) { 'test/files/images.xlsx' }

it 'returns array of images from default sheet' do
expect(subject.images).to be_kind_of(Array)
expect(subject.images.size).to eql(19)
end

it 'returns empty array if there is no images on the sheet' do
expect(subject.images("Sheet2")).to eql([])
end
end
end

describe 'Roo::Excelx with options set' do
Expand Down
Binary file added test/files/images.xlsx
Binary file not shown.

0 comments on commit fc0f4eb

Please sign in to comment.