Skip to content

Commit

Permalink
Merge 7275d1e into 4ec1104
Browse files Browse the repository at this point in the history
  • Loading branch information
ProGM committed Feb 14, 2019
2 parents 4ec1104 + 7275d1e commit bf22722
Show file tree
Hide file tree
Showing 10 changed files with 119 additions and 4 deletions.
11 changes: 10 additions & 1 deletion lib/roo/excelx.rb
Expand Up @@ -21,12 +21,13 @@ class Excelx < Roo::Base
require 'roo/excelx/sheet'
require 'roo/excelx/relationships'
require 'roo/excelx/comments'
require 'roo/excelx/drawings'
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, :image_rels, :image_files] => :@shared
delegate [:styles, :workbook, :shared_strings, :rels_files, :sheet_files, :comments_files, :image_rels, :image_files, :drawing_files] => :@shared
ExceedsMaxError = Class.new(StandardError)

# initialization and opening of a spreadsheet file
Expand Down Expand Up @@ -186,6 +187,11 @@ def font(row, col, sheet = nil)
styles.definitions[definition_index] if definition_index
end

def drawing(row, col, sheet = nil)
key = normalize(row, col)
sheet_for(sheet).drawings[key]
end

# returns the type of a cell:
# * :float
# * :string,
Expand Down Expand Up @@ -454,6 +460,9 @@ def process_zipfile_entries(entries)
# 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}"
when /vmldrawing([0-9+]).vml$/
nr = Regexp.last_match[1].to_i
drawing_files[nr - 1] = "#{@tmpdir}/vml_drawing#{nr}"
end

entry.extract(path) if path
Expand Down
16 changes: 16 additions & 0 deletions lib/roo/excelx/drawing/base.rb
@@ -0,0 +1,16 @@
module Roo
class Excelx
class Drawing
class Base
# extend Roo::Helpers::DefaultAttrReader
attr_reader :value, :coordinate

def initialize(type, value, coordinate)
@type = type
@value = value
@coordinate = coordinate
end
end
end
end
end
9 changes: 9 additions & 0 deletions lib/roo/excelx/drawing/checkbox.rb
@@ -0,0 +1,9 @@
module Roo
class Excelx
class Drawing
class Checkbox < Roo::Excelx::Drawing::Base

end
end
end
end
9 changes: 9 additions & 0 deletions lib/roo/excelx/drawing/unknown.rb
@@ -0,0 +1,9 @@
module Roo
class Excelx
class Drawing
class Unknown < Roo::Excelx::Drawing::Base
attr_reader :type
end
end
end
end
46 changes: 46 additions & 0 deletions lib/roo/excelx/drawings.rb
@@ -0,0 +1,46 @@
require 'roo/excelx/extractor'
require 'roo/excelx/drawing/base'
require 'roo/excelx/drawing/checkbox'
require 'roo/excelx/drawing/unknown'

module Roo
class Excelx
class Drawings < 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
@drawings ||= extract_drawings
end

private

def extract_drawings
return {} unless doc_exists?

doc.xpath('//shape').each_with_object({}) do |shape, hash|
client_data = shape.xpath('./ClientData').first
anchors = client_data.xpath('./Anchor').text
coords = Utils.anchor_to_coordinates(anchors)

hash[coords] = create_drawing(
client_data['ObjectType'],
client_data,
coords
)
end
end


def create_drawing(type, client_data, coords)
case type
when 'Checkbox'
Drawing::Checkbox.new(type, client_data.xpath('./Checked').any?, coords)
else
Drawing::Unknown.new(type, nil, coords)
end
end
end
end
end
3 changes: 2 additions & 1 deletion lib/roo/excelx/shared.rb
Expand Up @@ -4,7 +4,7 @@ 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, :image_rels, :image_files
attr_accessor :comments_files, :sheet_files, :rels_files, :image_rels, :image_files, :drawing_files
def initialize(dir, options = {})
@dir = dir
@comments_files = []
Expand All @@ -13,6 +13,7 @@ def initialize(dir, options = {})
@options = options
@image_rels = []
@image_files = []
@drawing_files = []
end

def styles
Expand Down
6 changes: 5 additions & 1 deletion lib/roo/excelx/sheet.rb
Expand Up @@ -4,7 +4,7 @@ class Excelx
class Sheet
extend Forwardable

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

attr_reader :images

Expand All @@ -22,6 +22,10 @@ def cells
@cells ||= @sheet.cells(@rels)
end

def drawings
@drawings ||= Drawings.new(drawing_files[@sheet_index]).list
end

def present_cells
@present_cells ||= begin
warn %{
Expand Down
6 changes: 6 additions & 0 deletions lib/roo/utils.rb
Expand Up @@ -94,6 +94,12 @@ def coordinates_in_range(str)
end
end

def anchor_to_coordinates(anchor)
col, _, row = *anchor.split(',').map(&:strip).map(&:to_i)

Excelx::Coordinate.new(row + 1, col + 1)
end

def load_xml(path)
::File.open(path, 'rb') do |file|
::Nokogiri::XML(file)
Expand Down
17 changes: 16 additions & 1 deletion spec/lib/roo/excelx_spec.rb
Expand Up @@ -584,6 +584,21 @@
end
end

describe 'drawings' do
let(:path) { 'test/files/checkbox.xlsx' }
it 'reads a drawing of type checkbox with value false' do
checkbox = subject.drawing(1, 'A')
expect(checkbox).to be_a(Roo::Excelx::Drawing::Checkbox)
expect(checkbox.value).to be(false)
end

it 'reads a drawing of type checkbox with value true' do
checkbox = subject.drawing(2, 'A')
expect(checkbox).to be_a(Roo::Excelx::Drawing::Checkbox)
expect(checkbox.value).to be(true)
end
end

describe 'opening a file with a chart sheet' do
let(:path) { 'test/files/chart_sheet.xlsx' }
it 'should not raise' do
Expand Down Expand Up @@ -653,4 +668,4 @@
end
end
end
end
end
Binary file added test/files/checkbox.xlsx
Binary file not shown.

0 comments on commit bf22722

Please sign in to comment.