diff options
| author | Randy Morgan <[email protected]> | 2012-03-26 18:29:35 +0900 |
|---|---|---|
| committer | Randy Morgan <[email protected]> | 2012-03-26 18:29:35 +0900 |
| commit | 42f45f4138a1f71b19411fd8600f2a2bce67a46b (patch) | |
| tree | bcef93a7c400d806f1f8aa7a4ebc08d359540d67 /lib | |
| parent | d7ccb09a0aaac4564fe01a56305e68d41ee37f57 (diff) | |
| download | caxlsx-42f45f4138a1f71b19411fd8600f2a2bce67a46b.tar.gz caxlsx-42f45f4138a1f71b19411fd8600f2a2bce67a46b.zip | |
Quick and Dirty run on trying interpolated strings instead of nokogiri for sheet generation.
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/axlsx.rb | 3 | ||||
| -rw-r--r-- | lib/axlsx/package.rb | 4 | ||||
| -rw-r--r-- | lib/axlsx/workbook/worksheet/cell.rb | 42 | ||||
| -rw-r--r-- | lib/axlsx/workbook/worksheet/page_margins.rb | 23 | ||||
| -rw-r--r-- | lib/axlsx/workbook/worksheet/row.rb | 7 | ||||
| -rw-r--r-- | lib/axlsx/workbook/worksheet/worksheet.rb | 74 |
6 files changed, 117 insertions, 36 deletions
diff --git a/lib/axlsx.rb b/lib/axlsx.rb index eb5068b5..cf3beb87 100644 --- a/lib/axlsx.rb +++ b/lib/axlsx.rb @@ -5,6 +5,9 @@ require 'axlsx/util/simple_typed_list.rb' require 'axlsx/util/constants.rb' require 'axlsx/util/validators.rb' require 'axlsx/util/storage.rb' + +#not even close to being ready but it does not break anything so it stays for now. +# needs a full re-write to use agile-encryption properly require 'axlsx/util/cbf.rb' require 'axlsx/util/ms_off_crypto.rb' diff --git a/lib/axlsx/package.rb b/lib/axlsx/package.rb index 73e72493..505f8cc9 100644 --- a/lib/axlsx/package.rb +++ b/lib/axlsx/package.rb @@ -184,7 +184,7 @@ module Axlsx end workbook.tables.each do |table| - @parts << {:entry => "xl/#{table.pn}", :doc => table.to_xml, :schema => SML_XSD} + @parts << {:entry => "xl/#{table.pn}", :doc => table.to_xml, :schema => SML_XSD} end workbook.charts.each do |chart| @@ -201,7 +201,7 @@ module Axlsx workbook.worksheets.each do |sheet| @parts << {:entry => "xl/#{sheet.rels_pn}", :doc => sheet.relationships.to_xml, :schema => RELS_XSD} - @parts << {:entry => "xl/#{sheet.pn}", :doc => sheet.to_xml, :schema => SML_XSD} + @parts << {:entry => "xl/#{sheet.pn}", :doc => sheet.to_xml_string, :schema => SML_XSD} end @parts end diff --git a/lib/axlsx/workbook/worksheet/cell.rb b/lib/axlsx/workbook/worksheet/cell.rb index ff759cdf..5e59aa40 100644 --- a/lib/axlsx/workbook/worksheet/cell.rb +++ b/lib/axlsx/workbook/worksheet/cell.rb @@ -259,6 +259,15 @@ module Axlsx self.row.worksheet.merge_cells "#{self.r}:#{range_end}" unless range_end.nil? end + + def run_xml_string + #if (self.instance_values.keys & INLINE_STYLES).size > 0 + # str = "<r><rPr></rPr><r>" + #else + # "<t>%s</t>" % value.to_s + #end + "<t>%s</t>" % value.to_s + end # builds an xml text run based on this cells attributes. This is extracted from to_xml so that shared strings can use it. # @param [Nokogiri::XML::Builder] xml The document builder instance this output will be added to. # @return [String] the xml for this cell's text run @@ -294,11 +303,42 @@ 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 + + FORMULA = "<c r=\"%s\" t=\"str\" s=\"%i\"><f>%s</f></c>" + SHARED_STRING = "<c r=\"%s\" t=\"s\" s=\"%i\"><v>%i</v></c>" + INLINE_STRING = "<c r=\"%s\" t=\"inlineStr\" s=\"%i\"><is>%s</is></c>" + OTHER = "<c r=\"%s\" s=\"%i\"><v>%s</v></c>" + BOOLEAN = "<c r=\"%s\" t=\"b\" s=\"%i\"><v>%s</v></c>" + def to_xml_string + if @type == :string + #parse formula + if @value.start_with?('=') + FORMULA % [r, style, value.to_s.gsub('=', '')] + else + #parse shared + if @ssti + SHARED_STRING % [r, style, ssti] + else + INLINE_STRING % [r, style, run_xml_string] + end + end + elsif @type == :date + # TODO: See if this is subject to the same restriction as Time below + OTHER % [r, style, DateTimeConverter::date_to_serial(@value)] + elsif @type == :time + OTHER % [r, style, DateTimeConverter::time_to_serial(@value)] + elsif @type == :boolean + BOOLEAN % [r, style, value] + else + OTHER % [r, style, value] + end + end + def to_xml(xml) if @type == :string #parse formula if @value.start_with?('=') - xml.c(:r => r, :t=>:str, :s=>style) { + xml.c(:r => r, :s=>style, :t=>:str) { xml.f @value.to_s.gsub('=', '') } else diff --git a/lib/axlsx/workbook/worksheet/page_margins.rb b/lib/axlsx/workbook/worksheet/page_margins.rb index f41e3426..1c456f2a 100644 --- a/lib/axlsx/workbook/worksheet/page_margins.rb +++ b/lib/axlsx/workbook/worksheet/page_margins.rb @@ -12,13 +12,13 @@ module Axlsx # Default left and right margin (in inches) DEFAULT_LEFT_RIGHT = 0.75 - + # Default top and bottom margins (in inches) DEFAULT_TOP_BOTTOM = 1.00 - + # Default header and footer margins (in inches) DEFAULT_HEADER_FOOTER = 0.50 - + # Left margin (in inches) # @return [Float] attr_reader :left @@ -26,23 +26,23 @@ module Axlsx # Right margin (in inches) # @return [Float] attr_reader :right - + # Top margin (in inches) # @return [Float] attr_reader :top - + # Bottom margin (in inches) # @return [Float] attr_reader :bottom - + # Header margin (in inches) # @return [Float] attr_reader :header - + # Footer margin (in inches) # @return [Float] attr_reader :footer - + # Creates a new PageMargins object # @option options [Numeric] left The left margin in inches # @option options [Numeric] right The right margin in inches @@ -60,7 +60,7 @@ module Axlsx self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}=" end end - + # Set some or all margins at once. # @param [Hash] margins the margins to set (possible keys are :left, :right, :top, :bottom, :header and :footer). def set(margins) @@ -69,7 +69,7 @@ module Axlsx send("#{k}=", v) end end - + # @see left def left=(v); Axlsx::validate_unsigned_numeric(v); @left = v end # @see right @@ -83,6 +83,9 @@ module Axlsx # @see footer def footer=(v); Axlsx::validate_unsigned_numeric(v); @footer = v end + def to_xml_string + "<pageMargins left='%s' right='%s' top='%s' bottom='%s' header='%s' footer='%s'/>" % [left, right, top, bottom, header, footer] + end # Serializes the page margins element # @note For compatibility, this is a noop unless custom margins have been specified. # @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to. diff --git a/lib/axlsx/workbook/worksheet/row.rb b/lib/axlsx/workbook/worksheet/row.rb index bb6a92a8..db7a56e5 100644 --- a/lib/axlsx/workbook/worksheet/row.rb +++ b/lib/axlsx/workbook/worksheet/row.rb @@ -59,6 +59,13 @@ module Axlsx worksheet.rows.index(self) end + def to_xml_string + if custom_height? + "<row r=\"%s\" customHeight=\"1\" ht=\"%s\">%s</row>" % [index+1, height, @cells.inject("") { |memo, obj| obj.to_xml_string }] + else + "<row r=\"%s\">%s</row>" % [index+1, @cells.inject("") { |memo, obj| memo.concat obj.to_xml_string }] + end + end # Serializes the row # @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to. # @return [String] diff --git a/lib/axlsx/workbook/worksheet/worksheet.rb b/lib/axlsx/workbook/worksheet/worksheet.rb index 5325294f..1d128235 100644 --- a/lib/axlsx/workbook/worksheet/worksheet.rb +++ b/lib/axlsx/workbook/worksheet/worksheet.rb @@ -168,27 +168,6 @@ module Axlsx @fit_to_page = v end - # Returns the cell or cells defined using excel style A1:B3 references. - # @param [String|Integer] cell_def the string defining the cell or range of cells, or the rownumber - # @return [Cell, Array] - def [](cell_def) - return rows[cell_def - 1] if cell_def.is_a? Integer - parts = cell_def.split(':') - first = name_to_cell parts[0] - - if parts.size == 1 - first - else - cells = [] - last = name_to_cell(parts[1]) - rows[(first.row.index..last.row.index)].each do |r| - r.cells[(first.index..last.index)].each do |c| - cells << c - end - end - cells - end - end # returns the column and row index for a named based cell # @param [String] name The cell or cell range to return. "A1" will return the first cell of the first row. @@ -375,6 +354,7 @@ module Axlsx chart end + # needs documentation def add_table(ref, options={}) table = Table.new(ref, self, options) @tables << table @@ -391,14 +371,40 @@ module Axlsx image end + def to_xml_string + str = "<worksheet xmlns=\"%s\" xmlns:r=\"%s\">" % [XML_NS, XML_NS_R] + str.concat "<sheetPr><pageSetUpPr fitToPage=\"%s\"></pageSetUpPr></sheetPr>" % fit_to_page if fit_to_page + str.concat "<dimension ref=\"%s\"></dimension>" % dimension unless rows.size == 0 + str.concat "<sheetViews><sheetView tabSelected='%s' workbookViewId='0' showGridLines='%s'><selection activeCell=\"A1\" sqref=\"A1\"/></sheetView></sheetViews>" % [@selected, show_gridlines] + + if @auto_fit_data.size > 0 + str.concat "<cols>" + @auto_fit_data.each_with_index do |col, index| + min_max = index+1 + str.concat "<col min='%s' max='%s' width='%s' customWidth='1'></col>" % [min_max, min_max, auto_width(col)] + end + str.concat '</cols>' + end + + str.concat "<sheetData>%s</sheetData>" % [@rows.reduce('') { |memo, obj| memo += obj.to_xml_string }] + 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? + str.concat "<drawing r:id='rId1'></drawing>" if @drawing + unless @tables.empty? + str.concat "<tableParts count='%s'>%s</tableParts>" % [@tables.size, @tables.reduce('') { |memo, obj| memo += "<tablePart r:id='%s'/>" % obj.rId }] + end + str + end + # Serializes the worksheet document # @return [String] def to_xml builder = Nokogiri::XML::Builder.new(:encoding => ENCODING) do |xml| xml.worksheet(:xmlns => XML_NS, :'xmlns:r' => XML_NS_R) { - xml.sheetPr { - xml.pageSetUpPr :fitToPage => fit_to_page if fit_to_page + xml.sheetPr { + xml.pageSetUpPr :fitToPage => fit_to_page if fit_to_page } # another patch for the folks at rubyXL as thier parser depends on this optional element. xml.dimension :ref=>dimension unless rows.size == 0 @@ -450,6 +456,28 @@ module Axlsx r end + # Returns the cell or cells defined using excel style A1:B3 references. + # @param [String|Integer] cell_def the string defining the cell or range of cells, or the rownumber + # @return [Cell, Array] + def [](cell_def) + return rows[cell_def - 1] if cell_def.is_a?(Integer) + parts = cell_def.split(':') + first = name_to_cell parts[0] + + if parts.size == 1 + first + else + cells = [] + last = name_to_cell(parts[1]) + rows[(first.row.index..last.row.index)].each do |r| + r.cells[(first.index..last.index)].each do |c| + cells << c + end + end + cells + end + end + private # assigns the owner workbook for this worksheet |
