Skip to content
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
58 changes: 56 additions & 2 deletions lib/creek/sheet.rb
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ def rows_generator(include_meta_data = false, use_simple_rows_format = false)
cell = nil
cell_type = nil
cell_style_idx = nil
last_cell_ref = nil
current_col_index = nil
increment_on_close = false
@book.files.file.open(path) do |xml|
prefix = ''
name_row = 'row'
Expand All @@ -123,9 +126,11 @@ def rows_generator(include_meta_data = false, use_simple_rows_format = false)
row = node.attributes
row['cells'] = {}
cells = {}
last_cell_ref = nil
current_col_index = 0
y << (include_meta_data ? row : cells) if node.self_closing?
elsif node.name == name_row && node.node_type == closer
processed_cells = fill_in_empty_cells(cells, row['r'], cell, use_simple_rows_format)
processed_cells = fill_in_empty_cells(cells, row['r'], last_cell_ref, use_simple_rows_format)
@headers = processed_cells if with_headers && row['r'] == HEADERS_ROW_NUMBER

if @images_present
Expand All @@ -142,6 +147,33 @@ def rows_generator(include_meta_data = false, use_simple_rows_format = false)
cell_type = node.attributes['t']
cell_style_idx = node.attributes['s']
cell = node.attributes['r']
if cell.nil? || cell.empty?
row_number = row && row['r']
if row_number && !current_col_index.nil?
cell = "#{column_index_to_letters(current_col_index)}#{row_number}"
end
else
col_letters = column_from_cell_ref(cell)
current_col_index = column_letters_to_index(col_letters) unless col_letters.nil?
end
last_cell_ref = cell unless cell.nil?
if node.self_closing?
current_col_index += 1 if !current_col_index.nil?
increment_on_close = false
cell = nil
cell_type = nil
cell_style_idx = nil
else
increment_on_close = true
end
elsif node.name == name_c && node.node_type == closer
if increment_on_close && !current_col_index.nil?
current_col_index += 1
end
increment_on_close = false
cell = nil
cell_type = nil
cell_style_idx = nil
elsif (node.name == name_v || node.name == name_t) && node.node_type == opener
unless cell.nil?
node.read
Expand Down Expand Up @@ -170,7 +202,7 @@ def converter_options
# Empty cells are being padded in using this function
def fill_in_empty_cells(cells, row_number, last_col, use_simple_rows_format)
new_cells = {}
return new_cells if cells.empty?
return new_cells if cells.empty? || row_number.nil? || last_col.nil?

last_col = last_col.gsub(row_number, '')
('A'..last_col).to_a.each do |column|
Expand Down Expand Up @@ -203,5 +235,27 @@ def cell_id(column, use_simple_rows_format, row_number)

(with_headers && headers) ? headers[column] : column
end

def column_from_cell_ref(cell_ref)
cell_ref.to_s.upcase[/[A-Z]+/]
end

def column_letters_to_index(column_letters)
return nil if column_letters.nil? || column_letters.empty?

column_letters.chars.reduce(0) { |sum, char| (sum * 26) + (char.ord - 64) } - 1
end

def column_index_to_letters(column_index)
return nil if column_index.nil? || column_index.negative?

result = +''
index = column_index
while index >= 0
result.prepend((index % 26 + 65).chr)
index = (index / 26) - 1
end
result
end
end
end
Binary file added spec/fixtures/sample-missing-cell-ref.xlsx
Binary file not shown.
16 changes: 16 additions & 0 deletions spec/sheet_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,22 @@ def load_cell(rows, cell_name)
expect(load_cell(rows, 'A10')).to eq(0.15)
end
end

context 'when cell references are missing' do
let(:book_missing_refs) { Creek::Book.new('spec/fixtures/sample-missing-cell-ref.xlsx') }
let(:missing_refs_sheet) { book_missing_refs.sheets[0] }

after { book_missing_refs.close }

it 'infers cell references from column order' do
rows = missing_refs_sheet.rows.to_a

expect(rows[0]['A1']).to eq('Content 1')
expect(rows[0]['C1']).to eq('Content 2')
expect(rows[5]['B6']).to eq('2')
expect(rows[5]['C6']).to eq('3')
end
end
end

describe '#images_at' do
Expand Down