diff --git a/lib/roo/excelx.rb b/lib/roo/excelx.rb index 91ebc1e0..a4004683 100755 --- a/lib/roo/excelx.rb +++ b/lib/roo/excelx.rb @@ -41,6 +41,7 @@ def initialize(filename_or_stream, 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) + sheet_options[:support_excel_sheet_hyperlinks] = (options[:support_excel_sheet_hyperlinks] || false) shared_options = {} shared_options[:disable_html_wrapper] = (options[:disable_html_wrapper] || false) diff --git a/lib/roo/excelx/sheet.rb b/lib/roo/excelx/sheet.rb index 840a0533..61baee43 100644 --- a/lib/roo/excelx/sheet.rb +++ b/lib/roo/excelx/sheet.rb @@ -19,7 +19,7 @@ def initialize(name, shared, sheet_index, options = {}) end def cells - @cells ||= @sheet.cells(@rels) + @cells ||= @sheet.cells end def present_cells @@ -85,7 +85,7 @@ def excelx_format(key) end def hyperlinks - @hyperlinks ||= @sheet.hyperlinks(@rels) + @hyperlinks ||= @sheet.hyperlinks end def comments diff --git a/lib/roo/excelx/sheet_doc.rb b/lib/roo/excelx/sheet_doc.rb index 7a09725a..65a54af5 100755 --- a/lib/roo/excelx/sheet_doc.rb +++ b/lib/roo/excelx/sheet_doc.rb @@ -16,16 +16,16 @@ def initialize(path, relationships, shared, options = {}) @relationships = relationships end - def cells(relationships) - @cells ||= extract_cells(relationships) + def cells + @cells ||= extract_cells end - def hyperlinks(relationships) + def hyperlinks # If you're sure you're not going to need this hyperlinks you can discard it - @hyperlinks ||= if @options[:no_hyperlinks] || !relationships.include_type?("hyperlink") + @hyperlinks ||= if @options[:no_hyperlinks] || (!@relationships.include_type?("hyperlink") && !@options[:support_excel_sheet_hyperlinks]) {} else - extract_hyperlinks(relationships) + extract_hyperlinks end end @@ -47,9 +47,9 @@ def each_cell(row_xml) return [] unless row_xml row_xml.children.each do |cell_element| coordinate = ::Roo::Utils.extract_coordinate(cell_element["r"]) - hyperlinks = hyperlinks(@relationships)[coordinate] + row_hyperlink = hyperlinks[coordinate] - yield cell_from_xml(cell_element, hyperlinks, coordinate) + yield cell_from_xml(cell_element, row_hyperlink, coordinate) end end @@ -173,17 +173,20 @@ def create_cell_from_value(value_type, cell, formula, format, style, hyperlink, end end - def extract_hyperlinks(relationships) + def extract_hyperlinks return {} unless (hyperlinks = doc.xpath('/worksheet/hyperlinks/hyperlink')) hyperlinks.each_with_object({}) do |hyperlink, hash| - if relationship = relationships[hyperlink['id']] - target_link = relationship['Target'] - target_link += "##{hyperlink['location']}" if hyperlink['location'] + relationship = @relationships[hyperlink['id']] + # If the relationship is not found, we can still use the location for the excel sheet link + target_link = relationship['Target'] if relationship + target_link += "##{hyperlink['location']}" if hyperlink['location'] && (!@options[:support_excel_sheet_hyperlinks] || relationship) + target_link = "##{hyperlink['location']}" if @options[:support_excel_sheet_hyperlinks] && hyperlink['location'] && !relationship - Roo::Utils.coordinates_in_range(hyperlink["ref"].to_s) do |coord| - hash[coord] = target_link - end + next unless target_link + + Roo::Utils.coordinates_in_range(hyperlink["ref"].to_s) do |coord| + hash[coord] = target_link end end end @@ -207,7 +210,7 @@ def expand_merged_ranges(cells) end end - def extract_cells(relationships) + def extract_cells extracted_cells = {} empty_cell = @options[:empty_cell] @@ -221,7 +224,7 @@ def extract_cells(relationships) ::Roo::Utils.extract_coordinate(r) end - cell = cell_from_xml(cell_xml, hyperlinks(relationships)[coordinate], coordinate, empty_cell) + cell = cell_from_xml(cell_xml, hyperlinks[coordinate], coordinate, empty_cell) extracted_cells[coordinate] = cell if cell end end diff --git a/spec/lib/roo/excelx_spec.rb b/spec/lib/roo/excelx_spec.rb index 10b0caf5..0b78c066 100755 --- a/spec/lib/roo/excelx_spec.rb +++ b/spec/lib/roo/excelx_spec.rb @@ -410,6 +410,7 @@ it 'returns the expected result' do expect(subject.hyperlink?(1, 1)).to eq true expect(subject.hyperlink?(1, 2)).to eq false + expect(subject.hyperlink?(3, 1)).to eq false end context 'defined on cell range' do @@ -660,13 +661,14 @@ describe 'Roo::Excelx with options set' do subject(:xlsx) do - Roo::Excelx.new(path, disable_html_wrapper: true) + Roo::Excelx.new(path, options) end describe '#html_strings' do - describe "HTML Parsing Disabled" do - let(:path) { 'test/files/html_strings_formatting.xlsx' } + let(:path) { 'test/files/html_strings_formatting.xlsx' } + let(:options) { {disable_html_wrapper: true} } + describe "HTML Parsing Disabled" do it 'returns the expected result' do expect(subject.excelx_value(1, 1, "Sheet1")).to eq("This has no formatting.") expect(subject.excelx_value(2, 1, "Sheet1")).to eq("This has bold formatting.") @@ -696,4 +698,14 @@ end end end + + describe '#match_relationships_with_hyperlinks' do + let(:path) { 'test/files/sheet_link.xlsx' } + let(:options) { { support_excel_sheet_hyperlinks: true } } + + it 'should display excel links' do + expect(subject.hyperlink(1, 1)).to eq "http://www.google.com/" + expect(subject.hyperlink(1, 2)).to eq "#Sheet2!A1" + end + end end diff --git a/test/files/sheet_link.xlsx b/test/files/sheet_link.xlsx new file mode 100644 index 00000000..afe54b5c Binary files /dev/null and b/test/files/sheet_link.xlsx differ