diff options
| author | Paul Kmiec <[email protected]> | 2023-05-05 08:58:17 -0700 |
|---|---|---|
| committer | Paul Kmiec <[email protected]> | 2023-05-05 09:29:58 -0700 |
| commit | 67aefd7705df82e43a8670102400a5abab49f6e8 (patch) | |
| tree | 6872755fccedb331f4553c72b642c6c86a700bff /lib/axlsx/workbook/worksheet | |
| parent | 1c355c83a9603f835dfe59ef4473df2b8cc3534c (diff) | |
| download | caxlsx-67aefd7705df82e43a8670102400a5abab49f6e8.tar.gz caxlsx-67aefd7705df82e43a8670102400a5abab49f6e8.zip | |
Pipe output directly to str and avoid additional memory allocations
Currently, there are lots of examples of code like this,
```
str << ('<tag ' << foo << ' ' << bar << '/>')
```
which create the string for the tag in memory before piping to str.
We can avoid creating all of these intermediate strings by dropping
the paranthesis and piping directly to str.
This relies on the `str` passed around to handle lots of small
appends. This is a problem when using RubyZip, but that is solved
in the next commit.
Diffstat (limited to 'lib/axlsx/workbook/worksheet')
21 files changed, 69 insertions, 57 deletions
diff --git a/lib/axlsx/workbook/worksheet/auto_filter/filter_column.rb b/lib/axlsx/workbook/worksheet/auto_filter/filter_column.rb index f014eb18..16096a52 100644 --- a/lib/axlsx/workbook/worksheet/auto_filter/filter_column.rb +++ b/lib/axlsx/workbook/worksheet/auto_filter/filter_column.rb @@ -88,7 +88,9 @@ module Axlsx # Serialize the object to xml def to_xml_string(str = +'') - str << "<filterColumn #{serialized_attributes}>" + str << '<filterColumn ' + serialized_attributes(str) + str << '>' @filter.to_xml_string(str) str << "</filterColumn>" end diff --git a/lib/axlsx/workbook/worksheet/auto_filter/filters.rb b/lib/axlsx/workbook/worksheet/auto_filter/filters.rb index 0fc5c968..38bafe85 100644 --- a/lib/axlsx/workbook/worksheet/auto_filter/filters.rb +++ b/lib/axlsx/workbook/worksheet/auto_filter/filters.rb @@ -77,7 +77,9 @@ module Axlsx # Serialize the object to xml def to_xml_string(str = +'') - str << "<filters #{serialized_attributes}>" + str << '<filters ' + serialized_attributes(str) + str << '>' filter_items.each { |filter| filter.to_xml_string(str) } date_group_items.each { |date_group_item| date_group_item.to_xml_string(str) } str << '</filters>' diff --git a/lib/axlsx/workbook/worksheet/cell_serializer.rb b/lib/axlsx/workbook/worksheet/cell_serializer.rb index b4c16b57..e1bdf728 100644 --- a/lib/axlsx/workbook/worksheet/cell_serializer.rb +++ b/lib/axlsx/workbook/worksheet/cell_serializer.rb @@ -10,7 +10,7 @@ module Axlsx # @param [String] str The string to apend serialization to. # @return [String] def to_xml_string(row_index, column_index, cell, str = +'') - str << (+'<c r="' << Axlsx::cell_r(column_index, row_index) << '" s="' << cell.style.to_s << '" ') + str << '<c r="' << Axlsx::cell_r(column_index, row_index) << '" s="' << cell.style.to_s << '" ' return str << '/>' if cell.value.nil? method = cell.type @@ -30,7 +30,7 @@ module Axlsx elsif cell.contains_rich_text? cell.value.to_xml_string(str) else - str << (+'<t>' << cell.clean_value << '</t>') + str << '<t>' << cell.clean_value << '</t>' end str end @@ -88,8 +88,8 @@ module Axlsx # @param [String] str The string the serialized content will be appended to. # @return [String] def formula_serialization(cell, str = +'') - str << (+'t="str"><f>' << cell.clean_value.to_s.sub('=', '') << '</f>') - str << (+'<v>' << cell.formula_value.to_s << '</v>') unless cell.formula_value.nil? + str << 't="str"><f>' << cell.clean_value.to_s.sub('=', '') << '</f>' + str << '<v>' << cell.formula_value.to_s << '</v>' unless cell.formula_value.nil? end # Serializes cells that are type array formula @@ -97,8 +97,8 @@ module Axlsx # @param [String] str The string the serialized content will be appended to. # @return [String] def array_formula_serialization(cell, str = +'') - str << (+'t="str">' << '<f t="array" ref="' << cell.r << '">' << cell.clean_value.to_s.sub('{=', '').sub(/}$/, '') << '</f>') - str << (+'<v>' << cell.formula_value.to_s << '</v>') unless cell.formula_value.nil? + str << 't="str">' << '<f t="array" ref="' << cell.r << '">' << cell.clean_value.to_s.sub('{=', '').sub(/}$/, '') << '</f>' + str << '<v>' << cell.formula_value.to_s << '</v>' unless cell.formula_value.nil? end # Serializes cells that are type inline_string @@ -158,8 +158,8 @@ module Axlsx end def value_serialization(serialization_type, serialization_value, str = +'') - str << (+'t="' << serialization_type.to_s << '"') if serialization_type - str << (+'><v>' << serialization_value.to_s << '</v>') + str << 't="' << serialization_type.to_s << '"' if serialization_type + str << '><v>' << serialization_value.to_s << '</v>' end end end diff --git a/lib/axlsx/workbook/worksheet/col_breaks.rb b/lib/axlsx/workbook/worksheet/col_breaks.rb index 2e176f0d..58fe9e10 100644 --- a/lib/axlsx/workbook/worksheet/col_breaks.rb +++ b/lib/axlsx/workbook/worksheet/col_breaks.rb @@ -28,7 +28,7 @@ module Axlsx def to_xml_string(str = +'') return if empty? - str << (+'<colBreaks count="' << size.to_s << '" manualBreakCount="' << size.to_s << '">') + str << '<colBreaks count="' << size.to_s << '" manualBreakCount="' << size.to_s << '">' each { |brk| brk.to_xml_string(str) } str << '</colBreaks>' end diff --git a/lib/axlsx/workbook/worksheet/comment.rb b/lib/axlsx/workbook/worksheet/comment.rb index 1da779aa..ea8324d0 100644 --- a/lib/axlsx/workbook/worksheet/comment.rb +++ b/lib/axlsx/workbook/worksheet/comment.rb @@ -63,15 +63,15 @@ module Axlsx # @return [String] def to_xml_string(str = +'') author = @comments.authors[author_index] - str << (+'<comment ref="' << ref << '" authorId="' << author_index.to_s << '">') + str << '<comment ref="' << ref << '" authorId="' << author_index.to_s << '">' str << '<text>' unless author.to_s == "" str << '<r><rPr><b/><color indexed="81"/></rPr>' - str << (+"<t>" << ::CGI.escapeHTML(author.to_s) << ":\n</t></r>") + str << "<t>" << ::CGI.escapeHTML(author.to_s) << ":\n</t></r>" end str << '<r>' str << '<rPr><color indexed="81"/></rPr>' - str << (+'<t>' << ::CGI.escapeHTML(text) << '</t></r></text>') + str << '<t>' << ::CGI.escapeHTML(text) << '</t></r></text>' str << '</comment>' end diff --git a/lib/axlsx/workbook/worksheet/comments.rb b/lib/axlsx/workbook/worksheet/comments.rb index b121ccd7..cb8efdaa 100644 --- a/lib/axlsx/workbook/worksheet/comments.rb +++ b/lib/axlsx/workbook/worksheet/comments.rb @@ -66,9 +66,9 @@ module Axlsx # @return [String] def to_xml_string(str = +'') str << '<?xml version="1.0" encoding="UTF-8"?>' - str << (+'<comments xmlns="' << XML_NS << '"><authors>') + str << '<comments xmlns="' << XML_NS << '"><authors>' authors.each do |author| - str << (+'<author>' << author.to_s << '</author>') + str << '<author>' << author.to_s << '</author>' end str << '</authors><commentList>' each do |comment| diff --git a/lib/axlsx/workbook/worksheet/conditional_formatting.rb b/lib/axlsx/workbook/worksheet/conditional_formatting.rb index bd5f5bc6..7c05c77e 100644 --- a/lib/axlsx/workbook/worksheet/conditional_formatting.rb +++ b/lib/axlsx/workbook/worksheet/conditional_formatting.rb @@ -75,8 +75,8 @@ module Axlsx # @param [String] str # @return [String] def to_xml_string(str = +'') - str << (+'<conditionalFormatting sqref="' << sqref << '">') - str << rules.collect { |rule| rule.to_xml_string }.join(' ') + str << '<conditionalFormatting sqref="' << sqref << '">' + rules.each { |rule| rule.to_xml_string(str) } str << '</conditionalFormatting>' end end diff --git a/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb b/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb index 1845f327..5d626e46 100644 --- a/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb +++ b/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb @@ -208,7 +208,7 @@ module Axlsx str << '<cfRule ' serialized_attributes str str << '>' - str << (+'<formula>' << [*self.formula].join('</formula><formula>') << '</formula>') if @formula + str << '<formula>' << [*self.formula].join('</formula><formula>') << '</formula>' if @formula @color_scale.to_xml_string(str) if @color_scale && @type == :colorScale @data_bar.to_xml_string(str) if @data_bar && @type == :dataBar @icon_set.to_xml_string(str) if @icon_set && @type == :iconSet diff --git a/lib/axlsx/workbook/worksheet/data_validation.rb b/lib/axlsx/workbook/worksheet/data_validation.rb index 1b9cb46a..d5fa5908 100644 --- a/lib/axlsx/workbook/worksheet/data_validation.rb +++ b/lib/axlsx/workbook/worksheet/data_validation.rb @@ -237,12 +237,12 @@ module Axlsx valid_attributes = get_valid_attributes str << '<dataValidation ' - str << Axlsx.instance_values_for(self).map do |key, value| - +'' << key << '="' << Axlsx.booleanize(value).to_s << '"' if (valid_attributes.include?(key.to_sym) && !CHILD_ELEMENTS.include?(key.to_sym)) - end.join(' ') + Axlsx.instance_values_for(self).each do |key, value| + str << key << '="' << Axlsx.booleanize(value).to_s << '" ' if (valid_attributes.include?(key.to_sym) && !CHILD_ELEMENTS.include?(key.to_sym)) + end str << '>' - str << (+'<formula1>' << self.formula1 << '</formula1>') if @formula1 and valid_attributes.include?(:formula1) - str << (+'<formula2>' << self.formula2 << '</formula2>') if @formula2 and valid_attributes.include?(:formula2) + str << '<formula1>' << self.formula1 << '</formula1>' if @formula1 and valid_attributes.include?(:formula1) + str << '<formula2>' << self.formula2 << '</formula2>' if @formula2 and valid_attributes.include?(:formula2) str << '</dataValidation>' end diff --git a/lib/axlsx/workbook/worksheet/outline_pr.rb b/lib/axlsx/workbook/worksheet/outline_pr.rb index 4cfeea2d..1059ad18 100644 --- a/lib/axlsx/workbook/worksheet/outline_pr.rb +++ b/lib/axlsx/workbook/worksheet/outline_pr.rb @@ -28,7 +28,9 @@ module Axlsx # @param [String] str serialized output will be appended to this object if provided. # @return [String] def to_xml_string(str = +'') - str << "<outlinePr #{serialized_attributes} />" + str << '<outlinePr ' + serialized_attributes(str) + str << '/>' end end end diff --git a/lib/axlsx/workbook/worksheet/page_set_up_pr.rb b/lib/axlsx/workbook/worksheet/page_set_up_pr.rb index 9a2b778b..4291eb38 100644 --- a/lib/axlsx/workbook/worksheet/page_set_up_pr.rb +++ b/lib/axlsx/workbook/worksheet/page_set_up_pr.rb @@ -38,7 +38,9 @@ module Axlsx # serialize to xml def to_xml_string(str = +'') - str << (+'<pageSetUpPr ' << serialized_attributes << '/>') + str << '<pageSetUpPr ' + serialized_attributes(str) + str << '/>' end end end diff --git a/lib/axlsx/workbook/worksheet/pivot_table.rb b/lib/axlsx/workbook/worksheet/pivot_table.rb index e97b8119..27065e4b 100644 --- a/lib/axlsx/workbook/worksheet/pivot_table.rb +++ b/lib/axlsx/workbook/worksheet/pivot_table.rb @@ -189,10 +189,10 @@ module Axlsx def to_xml_string(str = +'') str << '<?xml version="1.0" encoding="UTF-8"?>' - str << (+'<pivotTableDefinition xmlns="' << XML_NS << '" name="' << name << '" cacheId="' << cache_definition.cache_id.to_s << '"' << (data.size <= 1 ? ' dataOnRows="1"' : '') << ' applyNumberFormats="0" applyBorderFormats="0" applyFontFormats="0" applyPatternFormats="0" applyAlignmentFormats="0" applyWidthHeightFormats="1" dataCaption="Data" showMultipleLabel="0" showMemberPropertyTips="0" useAutoFormatting="1" indent="0" compact="0" compactData="0" gridDropZones="1" multipleFieldFilters="0">') + str << '<pivotTableDefinition xmlns="' << XML_NS << '" name="' << name << '" cacheId="' << cache_definition.cache_id.to_s << '"' << (data.size <= 1 ? ' dataOnRows="1"' : '') << ' applyNumberFormats="0" applyBorderFormats="0" applyFontFormats="0" applyPatternFormats="0" applyAlignmentFormats="0" applyWidthHeightFormats="1" dataCaption="Data" showMultipleLabel="0" showMemberPropertyTips="0" useAutoFormatting="1" indent="0" compact="0" compactData="0" gridDropZones="1" multipleFieldFilters="0">' - str << (+'<location firstDataCol="1" firstDataRow="1" firstHeaderRow="1" ref="' << ref << '"/>') - str << (+'<pivotFields count="' << header_cells_count.to_s << '">') + str << '<location firstDataCol="1" firstDataRow="1" firstHeaderRow="1" ref="' << ref << '"/>' + str << '<pivotFields count="' << header_cells_count.to_s << '">' header_cell_values.each do |cell_value| subtotal = !no_subtotals_on_headers.include?(cell_value) @@ -205,12 +205,12 @@ module Axlsx str << '<rowFields count="1"><field x="-2"/></rowFields>' str << '<rowItems count="2"><i><x/></i> <i i="1"><x v="1"/></i></rowItems>' else - str << (+'<rowFields count="' << rows.size.to_s << '">') + str << '<rowFields count="' << rows.size.to_s << '">' rows.each do |row_value| - str << (+'<field x="' << header_index_of(row_value).to_s << '"/>') + str << '<field x="' << header_index_of(row_value).to_s << '"/>' end str << '</rowFields>' - str << (+'<rowItems count="' << rows.size.to_s << '">') + str << '<rowItems count="' << rows.size.to_s << '">' rows.size.times do |i| str << '<i/>' end @@ -229,16 +229,16 @@ module Axlsx str << '<colItems count="1"><i/></colItems>' end else - str << (+'<colFields count="' << columns.size.to_s << '">') + str << '<colFields count="' << columns.size.to_s << '">' columns.each do |column_value| - str << (+'<field x="' << header_index_of(column_value).to_s << '"/>') + str << '<field x="' << header_index_of(column_value).to_s << '"/>' end str << '</colFields>' end unless pages.empty? - str << (+'<pageFields count="' << pages.size.to_s << '">') + str << '<pageFields count="' << pages.size.to_s << '">' pages.each do |page_value| - str << (+'<pageField fld="' << header_index_of(page_value).to_s << '"/>') + str << '<pageField fld="' << header_index_of(page_value).to_s << '"/>' end str << '</pageFields>' end diff --git a/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb b/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb index d42c1fda..4928d5ac 100644 --- a/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb +++ b/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb @@ -47,13 +47,13 @@ module Axlsx # @return [String] def to_xml_string(str = +'') str << '<?xml version="1.0" encoding="UTF-8"?>' - str << (+'<pivotCacheDefinition xmlns="' << XML_NS << '" xmlns:r="' << XML_NS_R << '" invalid="1" refreshOnLoad="1" recordCount="0">') + str << '<pivotCacheDefinition xmlns="' << XML_NS << '" xmlns:r="' << XML_NS_R << '" invalid="1" refreshOnLoad="1" recordCount="0">' str << '<cacheSource type="worksheet">' - str << (+'<worksheetSource ref="' << pivot_table.range << '" sheet="' << pivot_table.data_sheet.name << '"/>') + str << '<worksheetSource ref="' << pivot_table.range << '" sheet="' << pivot_table.data_sheet.name << '"/>' str << '</cacheSource>' - str << (+'<cacheFields count="' << pivot_table.header_cells_count.to_s << '">') + str << '<cacheFields count="' << pivot_table.header_cells_count.to_s << '">' pivot_table.header_cells.each do |cell| - str << (+'<cacheField name="' << cell.clean_value << '" numFmtId="0">') + str << '<cacheField name="' << cell.clean_value << '" numFmtId="0">' str << '<sharedItems count="0">' str << '</sharedItems>' str << '</cacheField>' diff --git a/lib/axlsx/workbook/worksheet/rich_text_run.rb b/lib/axlsx/workbook/worksheet/rich_text_run.rb index ee988318..883d01d3 100644 --- a/lib/axlsx/workbook/worksheet/rich_text_run.rb +++ b/lib/axlsx/workbook/worksheet/rich_text_run.rb @@ -214,15 +214,15 @@ module Axlsx data.keys.each do |key| case key when :font_name - str << (+'<rFont val="' << font_name << '"/>') + str << '<rFont val="' << font_name << '"/>' when :color str << data[key].to_xml_string else - str << (+'<' << key.to_s << ' val="' << xml_value(data[key]) << '"/>') + str << '<' << key.to_s << ' val="' << xml_value(data[key]) << '"/>' end end clean_value = Axlsx::trust_input ? @value.to_s : ::CGI.escapeHTML(Axlsx::sanitize(@value.to_s)) - str << (+'</rPr><t>' << clean_value << '</t></r>') + str << '</rPr><t>' << clean_value << '</t></r>' end private diff --git a/lib/axlsx/workbook/worksheet/row.rb b/lib/axlsx/workbook/worksheet/row.rb index 0c139164..16116835 100644 --- a/lib/axlsx/workbook/worksheet/row.rb +++ b/lib/axlsx/workbook/worksheet/row.rb @@ -90,9 +90,7 @@ module Axlsx # @return [String] def to_xml_string(r_index, str = +'') serialized_tag('row', str, :r => r_index + 1) do - tmp = +'' # time / memory tradeoff, lots of calls to rubyzip costs more time.. - each_with_index { |cell, c_index| cell.to_xml_string(r_index, c_index, tmp) } - str << tmp + each_with_index { |cell, c_index| cell.to_xml_string(r_index, c_index, str) } end end diff --git a/lib/axlsx/workbook/worksheet/row_breaks.rb b/lib/axlsx/workbook/worksheet/row_breaks.rb index 3e945b78..56e8c4c6 100644 --- a/lib/axlsx/workbook/worksheet/row_breaks.rb +++ b/lib/axlsx/workbook/worksheet/row_breaks.rb @@ -26,7 +26,7 @@ module Axlsx def to_xml_string(str = +'') return if empty? - str << (+'<rowBreaks count="' << self.size.to_s << '" manualBreakCount="' << self.size.to_s << '">') + str << '<rowBreaks count="' << self.size.to_s << '" manualBreakCount="' << self.size.to_s << '">' each { |brk| brk.to_xml_string(str) } str << '</rowBreaks>' end diff --git a/lib/axlsx/workbook/worksheet/sheet_calc_pr.rb b/lib/axlsx/workbook/worksheet/sheet_calc_pr.rb index e85cbf2c..d43198cf 100644 --- a/lib/axlsx/workbook/worksheet/sheet_calc_pr.rb +++ b/lib/axlsx/workbook/worksheet/sheet_calc_pr.rb @@ -24,7 +24,9 @@ module Axlsx # content to. # @return [String] def to_xml_string(str = +'') - str << "<sheetCalcPr #{serialized_attributes}/>" + str << '<sheetCalcPr ' + serialized_attributes(str) + str << '/>' end end end diff --git a/lib/axlsx/workbook/worksheet/sheet_format_pr.rb b/lib/axlsx/workbook/worksheet/sheet_format_pr.rb index 227b9037..ecf8157f 100644 --- a/lib/axlsx/workbook/worksheet/sheet_format_pr.rb +++ b/lib/axlsx/workbook/worksheet/sheet_format_pr.rb @@ -49,7 +49,9 @@ module Axlsx # @param [String] str The string this objects serialization will be appended to # @return [String] def to_xml_string(str = +'') - str << "<sheetFormatPr #{serialized_attributes}/>" + str << '<sheetFormatPr ' + serialized_attributes(str) + str << '/>' end private diff --git a/lib/axlsx/workbook/worksheet/sheet_pr.rb b/lib/axlsx/workbook/worksheet/sheet_pr.rb index f90e7d6c..86826f77 100644 --- a/lib/axlsx/workbook/worksheet/sheet_pr.rb +++ b/lib/axlsx/workbook/worksheet/sheet_pr.rb @@ -52,7 +52,9 @@ module Axlsx # @return [String] def to_xml_string(str = +'') update_properties - str << "<sheetPr #{serialized_attributes}>" + str << '<sheetPr ' + serialized_attributes(str) + str << '>' tab_color.to_xml_string(str, 'tabColor') if tab_color outline_pr.to_xml_string(str) if @outline_pr page_setup_pr.to_xml_string(str) diff --git a/lib/axlsx/workbook/worksheet/table.rb b/lib/axlsx/workbook/worksheet/table.rb index 430ef489..210833e0 100644 --- a/lib/axlsx/workbook/worksheet/table.rb +++ b/lib/axlsx/workbook/worksheet/table.rb @@ -75,12 +75,12 @@ module Axlsx # @return [String] def to_xml_string(str = +'') str << '<?xml version="1.0" encoding="UTF-8"?>' - str << (+'<table xmlns="' << XML_NS << '" id="' << (index + 1).to_s << '" name="' << @name << '" displayName="' << @name.gsub(/\s/, '_') << '" ') - str << (+'ref="' << @ref << '" totalsRowShown="0">') - str << (+'<autoFilter ref="' << @ref << '"/>') - str << (+'<tableColumns count="' << header_cells.length.to_s << '">') + str << '<table xmlns="' << XML_NS << '" id="' << (index + 1).to_s << '" name="' << @name << '" displayName="' << @name.gsub(/\s/, '_') << '" ' + str << 'ref="' << @ref << '" totalsRowShown="0">' + str << '<autoFilter ref="' << @ref << '"/>' + str << '<tableColumns count="' << header_cells.length.to_s << '">' header_cells.each_with_index do |cell, index| - str << (+'<tableColumn id ="' << (index + 1).to_s << '" name="' << cell.clean_value << '"/>') + str << '<tableColumn id ="' << (index + 1).to_s << '" name="' << cell.clean_value << '"/>' end str << '</tableColumns>' table_style_info.to_xml_string(str) diff --git a/lib/axlsx/workbook/worksheet/worksheet.rb b/lib/axlsx/workbook/worksheet/worksheet.rb index 0a44027f..8c3514cc 100644 --- a/lib/axlsx/workbook/worksheet/worksheet.rb +++ b/lib/axlsx/workbook/worksheet/worksheet.rb @@ -632,8 +632,8 @@ module Axlsx add_autofilter_defined_name_to_workbook str << '<sheet ' serialized_attributes str - str << (+'name="' << name << '" ') - str << (+'r:id="' << rId << '"></sheet>') + str << 'name="' << name << '" ' + str << 'r:id="' << rId << '"></sheet>' end # Serializes the worksheet object to an xml string |
