From 51e0ce3a103410f1fb03f8305a323a537337ef33 Mon Sep 17 00:00:00 2001 From: Thomas <1258170+ThomasSevestre@users.noreply.github.com> Date: Wed, 10 May 2023 10:12:15 +0200 Subject: [PATCH] optimize rows_collection_parser (cf. Roo::Utils) --- lib/saxlsx/column_name_generator.rb | 18 -------------- lib/saxlsx/rows_collection_parser.rb | 37 ++++++++++++++++++++++------ spec/column_name_generator_spec.rb | 25 ------------------- 3 files changed, 30 insertions(+), 50 deletions(-) delete mode 100644 lib/saxlsx/column_name_generator.rb delete mode 100644 spec/column_name_generator_spec.rb diff --git a/lib/saxlsx/column_name_generator.rb b/lib/saxlsx/column_name_generator.rb deleted file mode 100644 index e1c9e6d..0000000 --- a/lib/saxlsx/column_name_generator.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true -module Saxlsx - class ColumnNameGenerator - FIRST = 'A' - LAST = 'Z' - - def self.next_to(previous) - char = previous ? previous[-1] : nil - if char.nil? - FIRST - elsif char < LAST - previous[0..-2] + char.next - else - next_to(previous[0..-2]) + FIRST - end - end - end -end diff --git a/lib/saxlsx/rows_collection_parser.rb b/lib/saxlsx/rows_collection_parser.rb index 07ef60b..cf3db4a 100644 --- a/lib/saxlsx/rows_collection_parser.rb +++ b/lib/saxlsx/rows_collection_parser.rb @@ -54,7 +54,6 @@ def start_element(name) case name when :row @current_row = [] - @next_column = 'A' when :c @current_type = nil @current_number_format = nil @@ -74,7 +73,11 @@ def attr(name, value) when :t @current_type = value when :r - @current_column = value.gsub(/\d/, '') + # fill missing columns with nil values + nb_columns = extract_current_column(value) - 1 + while @current_row.size != nb_columns + @current_row << nil + end when :s @current_number_format = detect_format_type(value.to_i) end @@ -83,12 +86,7 @@ def attr(name, value) def text(value) if @current_row && (@current_element == :v || @current_element == :t) - while @next_column != @current_column - @current_row << nil - @next_column = ColumnNameGenerator.next_to(@next_column) - end @current_row << value_of(value) - @next_column = ColumnNameGenerator.next_to(@next_column) end end @@ -155,5 +153,30 @@ def detect_custom_format_type(code) :unsupported end end + + def char_index(byte) + if byte >= 65 && byte <= 90 + byte - 64 + elsif byte >= 97 && byte <= 122 + byte - 96 + end + end + + def extract_current_column(value) + letter_num = 0 + + value.each_byte do |b| + if index = char_index(b) + letter_num *= 26 + letter_num += index + else + break + end + end + + raise ArgumentError if letter_num == 0 + + letter_num + end end end diff --git a/spec/column_name_generator_spec.rb b/spec/column_name_generator_spec.rb deleted file mode 100644 index 9bce426..0000000 --- a/spec/column_name_generator_spec.rb +++ /dev/null @@ -1,25 +0,0 @@ -# frozen_string_literal: true -require 'spec_helper' - -describe ColumnNameGenerator do - - it 'First char' do - ColumnNameGenerator::FIRST.should eq 'A' - end - - it 'Last char' do - ColumnNameGenerator::LAST.should eq 'Z' - end - - it 'Next value' do - ColumnNameGenerator.tap do |g| - g.next_to(nil).should eq 'A' - g.next_to('F').should eq 'G' - g.next_to('DM').should eq 'DN' - g.next_to('RZ').should eq 'SA' - g.next_to('ZZ').should eq 'AAA' - g.next_to('EDT').should eq 'EDU' - end - end - -end