summaryrefslogtreecommitdiffstats
path: root/lib/roo/excelx.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/roo/excelx.rb')
-rwxr-xr-x[-rw-r--r--]lib/roo/excelx.rb58
1 files changed, 42 insertions, 16 deletions
diff --git a/lib/roo/excelx.rb b/lib/roo/excelx.rb
index 82c1431..f9f0ee2 100644..100755
--- a/lib/roo/excelx.rb
+++ b/lib/roo/excelx.rb
@@ -24,8 +24,9 @@ module Roo
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
@@ -39,7 +40,10 @@ module Roo
sheet_options = {}
sheet_options[:expand_merged_ranges] = (options[:expand_merged_ranges] || false)
sheet_options[:no_hyperlinks] = (options[:no_hyperlinks] || false)
+ sheet_options[:empty_cell] = (options[:empty_cell] || false)
+ shared_options = {}
+ shared_options[:disable_html_wrapper] = (options[:disable_html_wrapper] || false)
unless is_stream?(filename_or_stream)
file_type_check(filename_or_stream, %w[.xlsx .xlsm], 'an Excel 2007', file_warning, packed)
basename = find_basename(filename_or_stream)
@@ -52,7 +56,7 @@ module Roo
@tmpdir = self.class.make_tempdir(self, basename, options[:tmpdir_root])
ObjectSpace.define_finalizer(self, self.class.finalize(object_id))
- @shared = Shared.new(@tmpdir)
+ @shared = Shared.new(@tmpdir, shared_options)
@filename = local_filename(filename_or_stream, @tmpdir, packed)
process_zipfile(@filename || filename_or_stream)
@@ -62,10 +66,10 @@ module Roo
end
end.compact
@sheets = []
- @sheets_by_name = Hash[@sheet_names.map.with_index do |sheet_name, n|
- @sheets[n] = Sheet.new(sheet_name, @shared, n, sheet_options)
- [sheet_name, @sheets[n]]
- end]
+ @sheets_by_name = {}
+ @sheet_names.each_with_index do |sheet_name, n|
+ @sheets_by_name[sheet_name] = @sheets[n] = Sheet.new(sheet_name, @shared, n, sheet_options)
+ end
if cell_max
cell_count = ::Roo::Utils.num_cells_in_range(sheet_for(options.delete(:sheet)).dimensions)
@@ -94,7 +98,12 @@ module Roo
def sheet_for(sheet)
sheet ||= default_sheet
validate_sheet!(sheet)
- @sheets_by_name[sheet]
+ @sheets_by_name[sheet] || @sheets[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.
@@ -325,7 +334,7 @@ module Roo
wb.extract(path)
workbook_doc = Roo::Utils.load_xml(path).remove_namespaces!
- workbook_doc.xpath('//sheet').map { |s| s.attributes['id'].value }
+ workbook_doc.xpath('//sheet').map { |s| s['id'] }
end
# Internal
@@ -349,17 +358,13 @@ module Roo
wb_rels.extract(path)
rels_doc = Roo::Utils.load_xml(path).remove_namespaces!
- worksheet_type = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet'
relationships = rels_doc.xpath('//Relationship').select do |relationship|
- relationship.attributes['Type'].value == worksheet_type
+ worksheet_types.include? relationship['Type']
end
- relationships.inject({}) do |hash, relationship|
- attributes = relationship.attributes
- id = attributes['Id']
- hash[id.value] = attributes['Target'].value
- hash
+ relationships.each_with_object({}) do |relationship, hash|
+ hash[relationship['Id']] = relationship['Target']
end
end
@@ -376,6 +381,15 @@ module Roo
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 = []
@@ -409,6 +423,7 @@ module Roo
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 =
@@ -435,6 +450,10 @@ module Roo
# 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
@@ -442,7 +461,14 @@ module Roo
end
def safe_send(object, method, *args)
- object.send(method, *args) if object && object.respond_to?(method)
+ object.send(method, *args) if object&.respond_to?(method)
+ end
+
+ def worksheet_types
+ [
+ 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet', # OOXML Transitional
+ 'http://purl.oclc.org/ooxml/officeDocument/relationships/worksheet' # OOXML Strict
+ ]
end
end
end