Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Streaming rows with implied coordinates #599

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions lib/roo/excelx/sheet.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def each_row(options = {}, &block)
@sheet.each_row_streaming do |row|
break if options[:max_rows] && row_count == options[:max_rows] + options[:offset] + 1
if block_given? && !(options[:offset] && row_count < options[:offset])
block.call(cells_for_row_element(row, options))
block.call(cells_for_row_element(row, row_count + 1, options))
end
row_count += 1
end
Expand Down Expand Up @@ -101,11 +101,11 @@ def dimensions
# Take an xml row and return an array of Excelx::Cell objects
# optionally pad array to header width(assumed 1st row).
# takes option pad_cells (boolean) defaults false
def cells_for_row_element(row_element, options = {})
def cells_for_row_element(row_element, row_index, options = {})
return [] unless row_element
cell_col = 0
cells = []
@sheet.each_cell(row_element) do |cell|
@sheet.each_cell(row_element, row_index) do |cell|
cells.concat(pad_cells(cell, cell_col)) if options[:pad_cells]
cells << cell
cell_col = cell.coordinate.column
Expand Down
20 changes: 10 additions & 10 deletions lib/roo/excelx/sheet_doc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ def each_row_streaming(&block)

# Yield each cell as Excelx::Cell to caller for given
# row xml
def each_cell(row_xml)
def each_cell(row_xml, row_index = nil)
return [] unless row_xml
row_xml.children.each do |cell_element|
coordinate = ::Roo::Utils.extract_coordinate(cell_element["r"])
row_xml.children.each.with_index(1) do |cell_element, col_index|
coordinate = cell_coordinate(cell_element["r"], row_index, col_index)
hyperlinks = hyperlinks(@relationships)[coordinate]

yield cell_from_xml(cell_element, hyperlinks, coordinate)
Expand Down Expand Up @@ -213,13 +213,7 @@ def extract_cells(relationships)

doc.xpath('/worksheet/sheetData/row').each.with_index(1) do |row_xml, ycoord|
row_xml.xpath('c').each.with_index(1) do |cell_xml, xcoord|
r = cell_xml['r']
coordinate =
if r.nil?
::Roo::Excelx::Coordinate.new(ycoord, xcoord)
else
::Roo::Utils.extract_coordinate(r)
end
coordinate = cell_coordinate(cell_xml['r'], ycoord, xcoord)

cell = cell_from_xml(cell_xml, hyperlinks(relationships)[coordinate], coordinate, empty_cell)
extracted_cells[coordinate] = cell if cell
Expand Down Expand Up @@ -252,6 +246,12 @@ def base_timestamp
def shared_strings
@shared.shared_strings
end

def cell_coordinate(r, row_index, col_index)
return ::Roo::Excelx::Coordinate.new(row_index, col_index) if r.nil?

::Roo::Utils.extract_coordinate(r)
end
end
end
end
15 changes: 15 additions & 0 deletions test/roo/test_excelx.rb
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,21 @@ def test_implicit_coordinates
assert_equal 'C2', xlsx.cell('c', 2)
end

def test_implicit_coordinates_with_streaming_rows
xlsx = roo_class.new(File.join(TESTDIR, 'implicit_coordinates.xlsx'))

expected_rows = [
['Test'],
['A2', 'B2', 'C2']
]

index = 0
xlsx.each_row_streaming do |row|
assert_equal expected_rows[index], row.map(&:value)
index += 1
end
end

def roo_class
Roo::Excelx
end
Expand Down