diff options
| author | Randy Morgan <[email protected]> | 2012-03-28 00:52:30 +0900 |
|---|---|---|
| committer | Randy Morgan <[email protected]> | 2012-03-28 00:52:30 +0900 |
| commit | ec9d3b896a2b07cdcb8198c2227df8dac3b83cdb (patch) | |
| tree | bb0da233e87c50d6560fb236543e6fa2a12fe642 | |
| parent | be2d7bee9b9236fff4a378db8770c3ae793e8422 (diff) | |
| download | caxlsx-ec9d3b896a2b07cdcb8198c2227df8dac3b83cdb.tar.gz caxlsx-ec9d3b896a2b07cdcb8198c2227df8dac3b83cdb.zip | |
Still not fast enough?
```
user system total real
axlsx_noautowidth 0.760000 0.020000 0.780000 ( 0.885482)
axlsx 3.560000 0.130000 3.690000 ( 4.158594)
axlsx_shared 11.610000 0.180000 11.790000 ( 13.208945)
axlsx_stream 3.450000 0.120000 3.570000 ( 3.920745)
csv 0.240000 0.010000 0.250000 ( 0.269822)
| -rw-r--r-- | lib/axlsx.rb | 21 | ||||
| -rw-r--r-- | lib/axlsx/stylesheet/color.rb | 5 | ||||
| -rw-r--r-- | lib/axlsx/workbook/shared_strings_table.rb | 8 | ||||
| -rw-r--r-- | lib/axlsx/workbook/worksheet/cell.rb | 39 | ||||
| -rw-r--r-- | lib/axlsx/workbook/worksheet/row.rb | 10 | ||||
| -rw-r--r-- | lib/axlsx/workbook/worksheet/worksheet.rb | 4 | ||||
| -rw-r--r-- | test/workbook/worksheet/tc_cell.rb | 3 | ||||
| -rw-r--r-- | test/workbook/worksheet/tc_row.rb | 4 |
8 files changed, 56 insertions, 38 deletions
diff --git a/lib/axlsx.rb b/lib/axlsx.rb index cf3beb87..09f351fc 100644 --- a/lib/axlsx.rb +++ b/lib/axlsx.rb @@ -63,4 +63,25 @@ module Axlsx [v[:i]-1, ((name[/[1-9][0-9]*/]).to_i)-1] end + + # converts the column index into alphabetical values. + # @note This follows the standard spreadsheet convention of naming columns A to Z, followed by AA to AZ etc. + # @return [String] + def self.col_ref(index) + chars = [] + while index >= 26 do + chars << ((index % 26) + 65).chr + index /= 26 + end + chars << ((chars.empty? ? index : index-1) + 65).chr + chars.reverse.join + end + + # @return [String] The alpha(column)numeric(row) reference for this sell. + # @example Relative Cell Reference + # ws.rows.first.cells.first.r #=> "A1" + def self.cell_r(c_index, r_index) + Axlsx::col_ref(c_index).to_s << (r_index+1).to_s + end + end diff --git a/lib/axlsx/stylesheet/color.rb b/lib/axlsx/stylesheet/color.rb index 5d3e60ca..2a08fd3c 100644 --- a/lib/axlsx/stylesheet/color.rb +++ b/lib/axlsx/stylesheet/color.rb @@ -62,12 +62,11 @@ module Axlsx # def indexed=(v) Axlsx::validate_unsigned_integer v; @indexed = v end def to_xml_string - str = ["<color "] + str = "<color " self.instance_values.each do |key, value| - str << "%s='%s' " % [key, value] + str << key << '="' << value.to_s << '" ' end str << "/>" - str.join end # Serializes the color diff --git a/lib/axlsx/workbook/shared_strings_table.rb b/lib/axlsx/workbook/shared_strings_table.rb index 5ebfd87f..0bdd7936 100644 --- a/lib/axlsx/workbook/shared_strings_table.rb +++ b/lib/axlsx/workbook/shared_strings_table.rb @@ -32,11 +32,12 @@ module Axlsx cells = cells.flatten.reject { |c| c.type != :string || c.value.start_with?('=') } @count = cells.size @unique_cells = [] + @shared_xml_string = "" resolve(cells) end def to_xml_string - str = "<sst xmlns=\"%s\" count='%s' uniqueCount='%s'>%s</sst>" % [XML_NS, count, unique_count, @unique_cells.map {|cell| cell[:data]}.join] + '<sst xmlns="' << XML_NS << '" count="' << @count.to_s << '" uniqueCount="' << unique_count.to_s << '">' << @shared_xml_string << '</sst>' end # Generate the xml document for the Shared Strings Table @@ -64,11 +65,12 @@ module Axlsx cells.each do |cell| cell_hash = cell.shareable_hash index = @unique_cells.index do |item| - item[:hash] == cell_hash + item == cell_hash end if index == nil cell.send :ssti=, @unique_cells.size - @unique_cells << {:hash => cell_hash, :data => '<si>'<< cell.run_xml_string << '</si>'} + @shared_xml_string << '<si>' << cell.run_xml_string << '</si>' + @unique_cells << cell_hash else cell.send :ssti=, index end diff --git a/lib/axlsx/workbook/worksheet/cell.rb b/lib/axlsx/workbook/worksheet/cell.rb index a3ec046a..24b380cb 100644 --- a/lib/axlsx/workbook/worksheet/cell.rb +++ b/lib/axlsx/workbook/worksheet/cell.rb @@ -238,8 +238,9 @@ module Axlsx # @return [String] The alpha(column)numeric(row) reference for this sell. # @example Relative Cell Reference # ws.rows.first.cells.first.r #=> "A1" + # @note this will be discontinued in 1.1.0 - prefer Axlsx.cell_r def r - "#{col_ref}#{@row.index+1}" + "#{Axlsx::col_ref(index)}#{@row.index+1}" end # @return [String] The absolute alpha(column)numeric(row) reference for this sell. @@ -275,9 +276,9 @@ module Axlsx self.row.worksheet.merge_cells "#{self.r}:#{range_end}" unless range_end.nil? end - def run_xml_string - str = "" + def run_xml_string(str = '') if is_text_run? + puts 'text run' data = self.instance_values.reject{|key, value| value == nil } keys = data.keys & INLINE_STYLES keys.delete ['value', 'type'] @@ -333,30 +334,32 @@ module Axlsx # Serializes the cell # @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to. # @return [String] xml text for the cell - def to_xml_string + def to_xml_string(r_index, c_index, str = '') + str << '<c r="' << Axlsx::cell_r(c_index, r_index) << '" s="' << @style.to_s << '" ' case @type when :string #parse formula if @value.start_with?('=') - '<c r="' << r << '" t="str" s="' << @style.to_s << '"><f>' << value.to_s.gsub('=', '') << '</f></c>' + str << 't="str"><f>' << value.to_s.gsub('=', '') << '</f>' else #parse shared if @ssti - '<c r="' << r << '" t="s" s="' << @style.to_s << '"><v>' << ssti << '</v></c>' + str << 't="s"><v>' << ssti << '</v>' else - '<c r="' << r << '" t="inlineStr" s="' << @style.to_s << '"><is>' << run_xml_string << '</is></c>' + str << 't="inlineStr"><is>' << run_xml_string << '</is>' end end when :date # TODO: See if this is subject to the same restriction as Time below - '<c r="' << r << '" s="' << @style.to_s << '"><v>' << DateTimeConverter::date_to_serial(@value).to_s << '</v></c>' + str << '><v>' << DateTimeConverter::date_to_serial(@value).to_s << '</v>' when :time - '<c r="' << r << '" s="' << @style.to_s << '"><v>' << DateTimeConverter::time_to_serial(@value).to_s << '</v></c>' + str << '><v>' << DateTimeConverter::time_to_serial(@value).to_s << '</v>' when :boolean - '<c r="' << r << '" t="b" s="' << @style.to_s << '"><v>' << @value.to_s << '</v></c>' + str << 't="b"><v>' << @value.to_s << '</v>' else - '<c r="' << r << '" s="' << @style.to_s << '"><v>' << @value.to_s << '</v></c>' + str << '><v>' << @value.to_s << '</v>' end + str << '</c>' end def to_xml(xml) @@ -412,20 +415,6 @@ module Axlsx # assigns the owning row for this cell. def row=(v) DataTypeValidator.validate "Cell.row", Row, v; @row=v end - # converts the column index into alphabetical values. - # @note This follows the standard spreadsheet convention of naming columns A to Z, followed by AA to AZ etc. - # @return [String] - def col_ref - chars = [] - index = self.index - while index >= 26 do - chars << ((index % 26) + 65).chr - index /= 26 - end - chars << ((chars.empty? ? index : index-1) + 65).chr - chars.reverse.join - end - # Determines the cell type based on the cell value. # @note This is only used when a cell is created but no :type option is specified, the following rules apply: # 1. If the value is an instance of Date, the type is set to :date diff --git a/lib/axlsx/workbook/worksheet/row.rb b/lib/axlsx/workbook/worksheet/row.rb index 30101a28..ac251ed8 100644 --- a/lib/axlsx/workbook/worksheet/row.rb +++ b/lib/axlsx/workbook/worksheet/row.rb @@ -59,12 +59,16 @@ module Axlsx worksheet.rows.index(self) end - def to_xml_string + def to_xml_string(r_index, str = '') + str << '<row r="' << (r_index + 1 ).to_s << '" ' if custom_height? - '<row r="' << (index+1).to_s << '" customHeight="1" ht="' << height.to_s << '">' << @cells.map { |cell| cell.to_xml_string }.join << '</row>' + str << 'customHeight="1" ht="' << height.to_s << '">' else - '<row r="' << (index+1).to_s << '">' << (@cells.map { |cell| cell.to_xml_string }.join) << '</row>' + str << '>' end + @cells.each_with_index { |cell, c_index| cell.to_xml_string(r_index, c_index, str) } + str << '</row>' + str end # Serializes the row # @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to. diff --git a/lib/axlsx/workbook/worksheet/worksheet.rb b/lib/axlsx/workbook/worksheet/worksheet.rb index 6a029f19..20c13d8b 100644 --- a/lib/axlsx/workbook/worksheet/worksheet.rb +++ b/lib/axlsx/workbook/worksheet/worksheet.rb @@ -386,7 +386,9 @@ module Axlsx str.concat '</cols>' end - str.concat "<sheetData>%s</sheetData>" % @rows.map { |obj| obj.to_xml_string }.join + str.concat '<sheetData>' + @rows.each_with_index { |row, index| row.to_xml_string(index, str) } + str.concat '</sheetData>' str.concat page_margins.to_xml_string if @page_margins str.concat "<autoFilter ref='%s'></autoFilter>" % @auto_filter if @auto_filter str.concat "<mergeCells count='%s'>%s</mergeCells>" % [@merged_cells.size, @merged_cells.reduce('') { |memo, obj| "<mergeCell ref='%s'></mergeCell>" % obj } ] unless @merged_cells.empty? diff --git a/test/workbook/worksheet/tc_cell.rb b/test/workbook/worksheet/tc_cell.rb index 991181e7..499f9209 100644 --- a/test/workbook/worksheet/tc_cell.rb +++ b/test/workbook/worksheet/tc_cell.rb @@ -69,7 +69,8 @@ class TestCell < Test::Unit::TestCase end def test_col_ref - assert_equal(@c.send(:col_ref), "A") + #TODO move to axlsx spec + assert_equal(Axlsx.col_ref(0), "A") end def test_cell_type_from_value diff --git a/test/workbook/worksheet/tc_row.rb b/test/workbook/worksheet/tc_row.rb index b77715c5..47b0f054 100644 --- a/test/workbook/worksheet/tc_row.rb +++ b/test/workbook/worksheet/tc_row.rb @@ -61,14 +61,14 @@ class TestRow < Test::Unit::TestCase end def test_to_xml_string - r_s_xml = Nokogiri::XML(@row.to_xml_string) + r_s_xml = Nokogiri::XML(@row.to_xml_string(0, '')) assert_equal(r_s_xml.xpath(".//row[@r=1]").size, 1) end def test_to_xml_string_with_custom_height @row.add_cell 1 @row.height = 20 - r_s_xml = Nokogiri::XML(@row.to_xml_string) + r_s_xml = Nokogiri::XML(@row.to_xml_string(0, '')) assert_equal(r_s_xml.xpath(".//row[@r=1][@ht=20][@customHeight=1]").size, 1) end |
