diff options
Diffstat (limited to 'lib/axlsx/workbook')
| -rw-r--r-- | lib/axlsx/workbook/workbook.rb | 17 | ||||
| -rw-r--r-- | lib/axlsx/workbook/worksheet/auto_filter.rb | 23 | ||||
| -rw-r--r-- | lib/axlsx/workbook/worksheet/cols.rb | 20 | ||||
| -rw-r--r-- | lib/axlsx/workbook/worksheet/comments.rb | 8 | ||||
| -rw-r--r-- | lib/axlsx/workbook/worksheet/conditional_formattings.rb | 25 | ||||
| -rw-r--r-- | lib/axlsx/workbook/worksheet/data_validations.rb | 28 | ||||
| -rw-r--r-- | lib/axlsx/workbook/worksheet/dimension.rb | 49 | ||||
| -rw-r--r-- | lib/axlsx/workbook/worksheet/merged_cells.rb | 25 | ||||
| -rw-r--r-- | lib/axlsx/workbook/worksheet/protected_ranges.rb | 32 | ||||
| -rw-r--r-- | lib/axlsx/workbook/worksheet/sheet_data.rb | 20 | ||||
| -rw-r--r-- | lib/axlsx/workbook/worksheet/sheet_pr.rb | 16 | ||||
| -rw-r--r-- | lib/axlsx/workbook/worksheet/tables.rb | 31 | ||||
| -rw-r--r-- | lib/axlsx/workbook/worksheet/worksheet.rb | 251 | ||||
| -rw-r--r-- | lib/axlsx/workbook/worksheet/worksheet_comments.rb | 38 | ||||
| -rw-r--r-- | lib/axlsx/workbook/worksheet/worksheet_drawing.rb | 48 |
15 files changed, 464 insertions, 167 deletions
diff --git a/lib/axlsx/workbook/workbook.rb b/lib/axlsx/workbook/workbook.rb index b9a46c06..c169d630 100644 --- a/lib/axlsx/workbook/workbook.rb +++ b/lib/axlsx/workbook/workbook.rb @@ -1,8 +1,9 @@ # -*- coding: utf-8 -*- module Axlsx - +require 'axlsx/workbook/worksheet/auto_filter.rb' require 'axlsx/workbook/worksheet/date_time_converter.rb' require 'axlsx/workbook/worksheet/protected_range.rb' +require 'axlsx/workbook/worksheet/protected_ranges.rb' require 'axlsx/workbook/worksheet/cell.rb' require 'axlsx/workbook/worksheet/page_margins.rb' require 'axlsx/workbook/worksheet/page_setup.rb' @@ -13,15 +14,25 @@ require 'axlsx/workbook/worksheet/data_bar.rb' require 'axlsx/workbook/worksheet/icon_set.rb' require 'axlsx/workbook/worksheet/conditional_formatting.rb' require 'axlsx/workbook/worksheet/conditional_formatting_rule.rb' +require 'axlsx/workbook/worksheet/conditional_formattings.rb' require 'axlsx/workbook/worksheet/row.rb' require 'axlsx/workbook/worksheet/col.rb' +require 'axlsx/workbook/worksheet/cols.rb' require 'axlsx/workbook/worksheet/comments.rb' require 'axlsx/workbook/worksheet/comment.rb' +require 'axlsx/workbook/worksheet/merged_cells.rb' require 'axlsx/workbook/worksheet/sheet_protection.rb' +require 'axlsx/workbook/worksheet/sheet_pr.rb' +require 'axlsx/workbook/worksheet/dimension.rb' +require 'axlsx/workbook/worksheet/sheet_data.rb' +require 'axlsx/workbook/worksheet/worksheet_drawing.rb' +require 'axlsx/workbook/worksheet/worksheet_comments.rb' require 'axlsx/workbook/worksheet/worksheet.rb' require 'axlsx/workbook/shared_strings_table.rb' require 'axlsx/workbook/worksheet/table.rb' +require 'axlsx/workbook/worksheet/tables.rb' require 'axlsx/workbook/worksheet/data_validation.rb' +require 'axlsx/workbook/worksheet/data_validations.rb' require 'axlsx/workbook/worksheet/sheet_view.rb' require 'axlsx/workbook/worksheet/pane.rb' require 'axlsx/workbook/worksheet/selection.rb' @@ -236,9 +247,9 @@ require 'axlsx/workbook/worksheet/selection.rb' str << '</sheets>' str << '<definedNames>' @worksheets.each_with_index do |sheet, index| - if sheet.auto_filter + if sheet.auto_filter.defined_name str << '<definedName name="_xlnm._FilterDatabase" localSheetId="' << index.to_s << '" hidden="1">' - str << sheet.abs_auto_filter << '</definedName>' + str << sheet.auto_filter.defined_name << '</definedName>' end end str << '</definedNames>' diff --git a/lib/axlsx/workbook/worksheet/auto_filter.rb b/lib/axlsx/workbook/worksheet/auto_filter.rb new file mode 100644 index 00000000..ff0c93d1 --- /dev/null +++ b/lib/axlsx/workbook/worksheet/auto_filter.rb @@ -0,0 +1,23 @@ +module Axlsx + + #This class represents an auto filter range in a worksheet + class AutoFilter + def initialize(worksheet) + raise ArgumentError, 'you must provide a worksheet' unless worksheet.is_a?(Worksheet) + @worksheet = worksheet + end + + attr_reader :worksheet + attr_accessor :range + + def defined_name + return unless range + Axlsx.cell_range(range.split(':').collect { |name| worksheet.name_to_cell(name)}) + end + + def to_xml_string(str='') + str << "<autoFilter ref='#{range}'></autoFilter>" + end + + end +end diff --git a/lib/axlsx/workbook/worksheet/cols.rb b/lib/axlsx/workbook/worksheet/cols.rb new file mode 100644 index 00000000..d4595f29 --- /dev/null +++ b/lib/axlsx/workbook/worksheet/cols.rb @@ -0,0 +1,20 @@ +module Axlsx + + # The cols class manages the col object used to manage column widths. + # This is where the magic happens with autowidth + class Cols < SimpleTypedList + + def initialize(worksheet) + raise ArgumentError, "you must provide a worksheet" unless worksheet.is_a?(Worksheet) + super Col + @worksheet = worksheet + end + + def to_xml_string(str = '') + return if empty? + str << '<cols>' + each { |item| item.to_xml_string(str) } + str << '</cols>' + end + end +end diff --git a/lib/axlsx/workbook/worksheet/comments.rb b/lib/axlsx/workbook/worksheet/comments.rb index 0bf703f5..25da9de2 100644 --- a/lib/axlsx/workbook/worksheet/comments.rb +++ b/lib/axlsx/workbook/worksheet/comments.rb @@ -53,6 +53,14 @@ module Axlsx @list.map { |comment| comment.author.to_s }.uniq.sort end + # The relationships required by this object + # @return [Array] + def relationships + [Relationship.new(VML_DRAWING_R, "../#{vml_drawing.pn}"), + Relationship.new(COMMENT_R, "../#{pn}"), + Relationship.new(COMMENT_R_NULL, "NULL")] + end + # serialize the object # @param [String] str # @return [String] diff --git a/lib/axlsx/workbook/worksheet/conditional_formattings.rb b/lib/axlsx/workbook/worksheet/conditional_formattings.rb new file mode 100644 index 00000000..2fe9f2e8 --- /dev/null +++ b/lib/axlsx/workbook/worksheet/conditional_formattings.rb @@ -0,0 +1,25 @@ +module Axlsx + + # A simple, self serializing class for storing conditional formattings + class ConditionalFormattings < SimpleTypedList + + # creates a new Tables object + def initialize(worksheet) + raise ArgumentError, "you must provide a worksheet" unless worksheet.is_a?(Worksheet) + super ConditionalFormatting + @worksheet = worksheet + end + + # The worksheet that owns this collection of tables + # @return [Worksheet] + attr_reader :worksheet + + # serialize the conditional formattings + def to_xml_string(str = "") + return if empty? + each { |item| item.to_xml_string(str) } + end + end + +end + diff --git a/lib/axlsx/workbook/worksheet/data_validations.rb b/lib/axlsx/workbook/worksheet/data_validations.rb new file mode 100644 index 00000000..cdfcf375 --- /dev/null +++ b/lib/axlsx/workbook/worksheet/data_validations.rb @@ -0,0 +1,28 @@ +module Axlsx + + # A simple, self serializing class for storing conditional formattings + class DataValidations < SimpleTypedList + + # creates a new Tables object + def initialize(worksheet) + raise ArgumentError, "you must provide a worksheet" unless worksheet.is_a?(Worksheet) + super DataValidation + @worksheet = worksheet + end + + # The worksheet that owns this collection of tables + # @return [Worksheet] + attr_reader :worksheet + + # serialize the conditional formattings + def to_xml_string(str = "") + return if empty? + str << "<dataValidations count='#{size}'>" + each { |item| item.to_xml_string(str) } + str << '</dataValidations>' + end + end + +end + + diff --git a/lib/axlsx/workbook/worksheet/dimension.rb b/lib/axlsx/workbook/worksheet/dimension.rb new file mode 100644 index 00000000..838b4ffa --- /dev/null +++ b/lib/axlsx/workbook/worksheet/dimension.rb @@ -0,0 +1,49 @@ +module Axlsx + + # This class manages the dimensions for a worksheet. + # While this node is optional in the specification some readers like + # LibraOffice require this node to render the sheet + class Dimension + + + def self.default_first + @@default_first ||= 'A1' + end + + def self.default_last + @@default_last ||= 'AA200' + end + + + def initialize(worksheet) + raise ArgumentError, "you must provide a worksheet" unless worksheet.is_a?(Worksheet) + @worksheet = worksheet + end + + attr_reader :worksheet + + def sqref + "#{first_cell_reference}:#{last_cell_reference}" + end + + def to_xml_string(str = '') + return if worksheet.rows.empty? + str << "<dimension ref=\"%s\"></dimension>" % sqref + end + + def first_cell_reference + dimension_reference(worksheet.rows.first.cells.first, Dimension.default_first) + end + + def last_cell_reference + dimension_reference(worksheet.rows.last.cells.last, Dimension.default_last) + end + + private + + def dimension_reference(cell, default) + return default unless cell.respond_to?(:r) + cell.r + end + end +end diff --git a/lib/axlsx/workbook/worksheet/merged_cells.rb b/lib/axlsx/workbook/worksheet/merged_cells.rb new file mode 100644 index 00000000..943cab04 --- /dev/null +++ b/lib/axlsx/workbook/worksheet/merged_cells.rb @@ -0,0 +1,25 @@ +module Axlsx + + class MergedCells < SimpleTypedList + + def initialize(worksheet) + raise ArgumentError, 'you must provide a worksheet' unless worksheet.is_a?(Worksheet) + super String + end + + def add(cells) + @list << if cells.is_a?(String) + cells + elsif cells.is_a?(Array) + Axlsx::cell_range(cells, false) + end + end + + def to_xml_string(str = '') + return if @list.empty? + str << "<mergeCells count='#{size}'>" + each { |merged_cell| str << "<mergeCell ref='#{merged_cell}'></mergeCell>" } + str << '</mergeCells>' + end + end +end diff --git a/lib/axlsx/workbook/worksheet/protected_ranges.rb b/lib/axlsx/workbook/worksheet/protected_ranges.rb new file mode 100644 index 00000000..e55d35fa --- /dev/null +++ b/lib/axlsx/workbook/worksheet/protected_ranges.rb @@ -0,0 +1,32 @@ +module Axlsx + + # A self serializing collection of ranges that should be protected in + # the worksheet + class ProtectedRanges < SimpleTypedList + + attr_reader :worksheet + + def initialize(worksheet) + raise ArgumentError, 'You must provide a worksheet' unless worksheet.is_a?(Worksheet) + super ProtectedRange + @worksheet = worksheet + end + + def add_range(cells) + sqref = if cells.is_a?(String) + cells + elsif cells.is_a?(SimpleTypedList) || cells.is_a?(Array) + Axlsx::cell_range(cells, false) + end + @list << ProtectedRange.new(:sqref => sqref, :name => "Range#{size}") + last + end + + def to_xml_string(str = '') + return if empty? + str << '<protectedRanges>' + each { |range| range.to_xml_string(str) } + str << '</protectedRanges>' + end + end +end diff --git a/lib/axlsx/workbook/worksheet/sheet_data.rb b/lib/axlsx/workbook/worksheet/sheet_data.rb new file mode 100644 index 00000000..98354b29 --- /dev/null +++ b/lib/axlsx/workbook/worksheet/sheet_data.rb @@ -0,0 +1,20 @@ +module Axlsx + + # This class manages the serialization of rows for worksheets + class SheetData + + def initialize(worksheet) + raise ArgumentError, "you must provide a worksheet" unless worksheet.is_a?(Worksheet) + @worksheet = worksheet + end + + attr_reader :worksheet + + def to_xml_string(str = '') + str << '<sheetData>' + worksheet.rows.each_with_index{ |row, index| row.to_xml_string(index, str) } + str << '</sheetData>' + end + + end +end diff --git a/lib/axlsx/workbook/worksheet/sheet_pr.rb b/lib/axlsx/workbook/worksheet/sheet_pr.rb new file mode 100644 index 00000000..a7f54f28 --- /dev/null +++ b/lib/axlsx/workbook/worksheet/sheet_pr.rb @@ -0,0 +1,16 @@ +module Axlsx + class SheetPr + + def initialize(worksheet) + raise ArgumentError, "you must provide a worksheet" unless worksheet.is_a?(Worksheet) + @worksheet = worksheet + end + + attr_reader :worksheet + + def to_xml_string(str = '') + return unless worksheet.fit_to_page? + str << "<sheetPr><pageSetUpPr fitToPage=\"%s\"></pageSetUpPr></sheetPr>" % worksheet.fit_to_page? + end + end +end diff --git a/lib/axlsx/workbook/worksheet/tables.rb b/lib/axlsx/workbook/worksheet/tables.rb new file mode 100644 index 00000000..2d9a1f3c --- /dev/null +++ b/lib/axlsx/workbook/worksheet/tables.rb @@ -0,0 +1,31 @@ +module Axlsx + + # A simple, self serializing class for storing tables + class Tables < SimpleTypedList + + # creates a new Tables object + def initialize(worksheet) + raise ArgumentError, "you must provide a worksheet" unless worksheet.is_a?(Worksheet) + super Table + @worksheet = worksheet + end + + # The worksheet that owns this collection of tables + # @return [Worksheet] + attr_reader :worksheet + + # returns the relationships required by this collection + def relationships + return [] if empty? + map{ |table| Relationship.new(TABLE_R, "../#{table.pn}") } + end + + def to_xml_string(str = "") + return if empty? + str << "<tableParts count='#{size}'>" + @list.each { |table| str << "<tablePart r:id='#{table.rId}'/>" } + str << '</tableParts>' + end + end + +end diff --git a/lib/axlsx/workbook/worksheet/worksheet.rb b/lib/axlsx/workbook/worksheet/worksheet.rb index bf48bf67..fd135726 100644 --- a/lib/axlsx/workbook/worksheet/worksheet.rb +++ b/lib/axlsx/workbook/worksheet/worksheet.rb @@ -21,24 +21,20 @@ module Axlsx def initialize(wb, options={}) self.workbook = wb @workbook.worksheets << self - initialize_optional_instance_variables + @sheet_protection = nil initialize_page_options(options) options.each do |o| self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}=" end end - - def initialize_optional_instance_variables - @page_setup = @drawing = @sheet_protection = @auto_filter = nil - end - + def initialize_page_options(options) @page_margins = PageMargins.new options[:page_margins] if options[:page_margins] @page_setup = PageSetup.new options[:page_setup] if options[:page_setup] @print_options = PrintOptions.new options[:print_options] if options[:print_options] end - # The name of the worksheet + # The name of the worksheet # @return [String] def name @name ||= "Sheet" + (index+1).to_s @@ -52,7 +48,6 @@ module Axlsx @sheet_protection end - # The sheet view object for this worksheet # @return [SheetView] # @see [SheetView] @@ -69,14 +64,19 @@ module Axlsx # The tables in this worksheet # @return [Array] of Table def tables - @tables ||= SimpleTypedList.new Table + @tables ||= Tables.new self end # The comments associated with this worksheet # @return [SimpleTypedList] + def worksheet_comments + @worksheet_comments ||= WorksheetComments.new self + end + def comments - @comments ||= Comments.new(self) + worksheet_comments.comments if worksheet_comments.has_comments? end + # The rows in this worksheet # @note The recommended way to manage rows is Worksheet#add_row # @return [SimpleTypedList] @@ -85,11 +85,13 @@ module Axlsx @rows ||= SimpleTypedList.new Row end - # An range that excel will apply an autfilter to "A1:B3" + # An range that excel will apply an autfilter to "A1:B3" # This will turn filtering on for the cells in the range. # The first row is considered the header, while subsequent rows are considerd to be data. # @return String - attr_reader :auto_filter + def auto_filter + @auto_filter ||= AutoFilter.new self + end # Indicates if the worksheet should show gridlines or not # @return Boolean @@ -115,7 +117,7 @@ module Axlsx # @return Boolean # @see #page_setup def fit_to_page? - return false unless @page_setup + return false unless self.instance_values.keys.include?('page_setup') page_setup.fit_to_page? end @@ -123,7 +125,7 @@ module Axlsx # Column info for the sheet # @return [SimpleTypedList] def column_info - @column_info ||= SimpleTypedList.new Col + @column_info ||= Cols.new self end # Page margins for printing the worksheet. @@ -213,6 +215,7 @@ module Axlsx cf = ConditionalFormatting.new( :sqref => cells ) cf.add_rules rules conditional_formattings << cf + conditional_formattings end # Add data validation to this worksheet. @@ -236,34 +239,30 @@ module Axlsx # worksheet["C1"].merge worksheet["E1"] # @param [Array, string] cells def merge_cells(cells) - merged_cells << if cells.is_a?(String) - cells - elsif cells.is_a?(Array) - Axlsx::cell_range(cells, false) - end + merged_cells.add cells end # Adds a new protected cell range to the worksheet. Note that protected ranges are only in effect when sheet protection is enabled. # @param [String|Array] cells The string reference for the cells to protect or an array of cells. # @return [ProtectedRange] # @note When using an array of cells, a contiguous range is created from the minimum top left to the maximum top bottom of the cells provided. def protect_range(cells) - sqref = if cells.is_a?(String) - cells - elsif cells.is_a?(SimpleTypedList) - Axlsx::cell_range(cells, false) - end - protected_ranges << ProtectedRange.new(:sqref => sqref, :name => "Range#{protected_ranges.size}") - protected_ranges.last + protected_ranges.add_range(cells) end - # The demensions of a worksheet. This is not actually a required element by the spec, + # The dimensions of a worksheet. This is not actually a required element by the spec, # but at least a few other document readers expect this for conversion - # @return [String] the A1:B2 style reference for the first and last row column intersection in the workbook + # @return [Dimension] def dimension - "#{dimension_reference(rows.first.cells.first, 'A1')}:#{dimension_reference(rows.last.cells.last, 'AA200')}" + @dimension ||= Dimension.new self + end + + # The sheet properties for this workbook. + # Currently only pageSetUpPr -> fitToPage is implemented + # @return [SheetPr] + def sheet_pr + @sheet_pr ||= SheetPr.new self end - # # Indicates if gridlines should be shown in the sheet. # This is true by default. # @return [Boolean] @@ -314,18 +313,12 @@ module Axlsx @name=v end - # The absolute auto filter range - # @see auto_filter - def abs_auto_filter - Axlsx.cell_range(@auto_filter.split(':').collect { |name| name_to_cell(name)}) if @auto_filter - end - # The auto filter range for the worksheet # @param [String] v # @see auto_filter def auto_filter=(v) DataTypeValidator.validate "Worksheet.auto_filter", String, v - @auto_filter = v + auto_filter.range = v end # The part name of this worksheet @@ -357,7 +350,7 @@ module Axlsx # @return [Drawing] # @see Worksheet#add_chart def drawing - @drawing ||= Axlsx::Drawing.new(self) + worksheet_drawing.drawing end # Adds a row to the worksheet and updates auto fit data. @@ -483,29 +476,28 @@ module Axlsx # @see Line3DChart # @see README for examples def add_chart(chart_type, options={}) - chart = drawing.add_chart(chart_type, options) + chart = worksheet_drawing.add_chart(chart_type, options) yield chart if block_given? chart end # needs documentation def add_table(ref, options={}) - table = Table.new(ref, self, options) - tables << table - yield table if block_given? - table + tables << Table.new(ref, self, options) + yield tables.last if block_given? + tables.last end - # Shortcut to comments#add_comment + # Shortcut to worsksheet_comments#add_comment def add_comment(options={}) - comments.add_comment(options) + worksheet_comments.add_comment(options) end # Adds a media item to the worksheets drawing # @option [Hash] options options passed to drawing.add_image def add_image(options={}) - image = drawing.add_image(options) + image = worksheet_drawing.add_image(options) yield image if block_given? image end @@ -516,58 +508,34 @@ module Axlsx def to_xml_string str = '<?xml version="1.0" encoding="UTF-8"?>' str << worksheet_node - str << sheet_pr_node - str << dimension_node - self_serializing_node(sheet_view, str) - collection_node('cols', column_info, str) - collection_node('sheetData', rows, str, :with_index => true, :required => true) - str << auto_filter_node - self_serializing_node(@sheet_protection, str) - collection_node('protectedRanges', protected_ranges, str) - str << merged_cells_node - self_serializing_node(print_options, str) - self_serializing_node(page_margins, str) - self_serializing_node(page_setup, str) - str << drawing_nodes - str << table_parts_node - str << conditional_formattings_node - collection_node('dataValidations', data_validations, str, :count => true) + [sheet_pr, dimension, + sheet_view, column_info, + sheet_data, + @sheet_protection, + protected_ranges, + auto_filter, + merged_cells, + print_options, + page_margins, + page_setup, + worksheet_drawing, + worksheet_comments, + tables, + conditional_formattings, + data_validations].each do |item| + item.to_xml_string(str) if item + end str << '</worksheet>' str.gsub(/[[:cntrl:]]/,'') end - def self_serializing_node(item, str) - item.to_xml_string(str) if item - end - - def collection_node(node_name, collection, str="", options={}) - return '' if collection && collection.empty? && !options[:required] - str << "<#{node_name}" - str << " count='#{collection.size}'" if options[:count] - str << '>' - if options[:with_index] - collection.each_with_index { |item, index| item.to_xml_string(index, str) } - else - collection.each { |item| item.to_xml_string(str) } - end - str << "</#{node_name}>" - end - # The worksheet relationships. This is managed automatically by the worksheet # @return [Relationships] def relationships r = Relationships.new - tables.each do |table| - r << Relationship.new(TABLE_R, "../#{table.pn}") - end - - if comments.size > 0 - r << Relationship.new(VML_DRAWING_R, "../#{comments.vml_drawing.pn}") - r << Relationship.new(COMMENT_R, "../#{comments.pn}") - r << Relationship.new(COMMENT_R_NULL, "NULL") - end - - r << Relationship.new(DRAWING_R, "../#{@drawing.pn}") if @drawing + r + [tables.relationships, + worksheet_comments.relationships, + worksheet_drawing.relationship].flatten.compact r end @@ -587,82 +555,61 @@ module Axlsx private def range(*cell_def) - first, last = cell_def - cells = [] - 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 - + first, last = cell_def + cells = [] + 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 + # A collection of protected ranges in the worksheet # @note The recommended way to manage protected ranges is with Worksheet#protect_range # @see Worksheet#protect_range # @return [SimpleTypedList] The protected ranges for this worksheet def protected_ranges - @protected_ranges ||= SimpleTypedList.new ProtectedRange + @protected_ranges ||= ProtectedRanges.new self + # SimpleTypedList.new ProtectedRange end + # conditional formattings + # @return [Array] def conditional_formattings - @conditional_formattings ||= [] + @conditional_formattings ||= ConditionalFormattings.new self end - + + # data validations array + # @return [Array] def data_validations - @data_validations ||= [] + @data_validations ||= DataValidations.new self end - # An array of merged cell ranges e.d "A1:B3" - # Content and formatting is read from the first cell. - # @return Array + # merged cells array + # @return [Array] def merged_cells - @merged_cells ||= [] + @merged_cells ||= MergedCells.new self end - + # Helper method for parsingout the root node for worksheet # @return [String] def worksheet_node "<worksheet xmlns=\"%s\" xmlns:r=\"%s\">" % [XML_NS, XML_NS_R] end - # Helper method fo parsing out the sheetPr node - # @return [String] - def sheet_pr_node - return '' unless fit_to_page? - "<sheetPr><pageSetUpPr fitToPage=\"%s\"></pageSetUpPr></sheetPr>" % fit_to_page? - end - - # Helper method for parsing out the demension node - # @return [String] - def dimension_node - return '' if rows.size == 0 - "<dimension ref=\"%s\"></dimension>" % dimension - end - - # Helper method for parsing out the autoFilter node - # @return [String] - def auto_filter_node - return '' unless @auto_filter - "<autoFilter ref='%s'></autoFilter>" % @auto_filter + def sheet_data + @sheet_data ||= SheetData.new self end - # Helper method for parsing out the mergedCells node - # @return [String] - def merged_cells_node - return '' if merged_cells.empty? - str = "<mergeCells count='#{merged_cells.size}'>" - merged_cells.each { |merged_cell| str << "<mergeCell ref='#{merged_cell}'></mergeCell>" } - str << '</mergeCells>' + def worksheet_drawing + @worksheet_drawing ||= WorksheetDrawing.new self end def drawing_nodes str = "" - if @drawing - str << relation_node('drawing', DRAWING_R) - end - unless comments.empty? + if @comments str << relation_node('legacyDrawing', VML_DRAWING_R) end str @@ -672,24 +619,6 @@ module Axlsx "<#{node_name} r:id='rId" << (relationships.index{ |r| r.Type == relation_type } + 1).to_s << "'/>" end - # Helper method for parsing out the tableParts node - # @return [String] - def table_parts_node - return '' if tables.empty? - str = "<tableParts count='#{tables.size}'>" - tables.each { |table| str << "<tablePart r:id='#{table.rId}'/>" } - str << '</tableParts>' - end - - # Helper method for parsing out the conditional formattings - # @return [String] - def conditional_formattings_node - return '' if conditional_formattings.size == 0 - str = '' - conditional_formattings.each { |conditional_formatting| str << conditional_formatting.to_xml_string } - str - end - # Helper method for parsing out the dataValidations node # @return [String] def data_validations_node @@ -715,14 +644,8 @@ module Axlsx end def find_or_create_column_info(index, fixed_width=nil) - col = column_info[index] || Col.new(index + 1, index + 1) - column_info[index] = col if index == column_info.size - col + column_info[index] ||= Col.new(index + 1, index + 1) end - def dimension_reference(cell, default) - return default unless cell.respond_to?(:r) - cell.r - end end end diff --git a/lib/axlsx/workbook/worksheet/worksheet_comments.rb b/lib/axlsx/workbook/worksheet/worksheet_comments.rb new file mode 100644 index 00000000..25ddb024 --- /dev/null +++ b/lib/axlsx/workbook/worksheet/worksheet_comments.rb @@ -0,0 +1,38 @@ +module Axlsx + + #A wraper class for comments that defines its on worksheet + #serailization + class WorksheetComments + + def initialize(worksheet) + raise ArugumentError, 'You must provide a worksheet' unless worksheet.is_a?(Worksheet) + @worksheet = worksheet + end + attr_reader :worksheet + + def comments + @comments ||= Comments.new(worksheet) + end + + def add_comment(options={}) + comments.add_comment(options) + end + + def relationships + return [] unless has_comments? + comments.relationships + end + + def has_comments? + !comments.empty? + end + + def index + worksheet.relationships.index { |r| r.Type == VML_DRAWING_R } + 1 + end + def to_xml_string(str = '') + return unless has_comments? + str << "<legacyDrawing r:id='rId#{index}' />" + end + end +end diff --git a/lib/axlsx/workbook/worksheet/worksheet_drawing.rb b/lib/axlsx/workbook/worksheet/worksheet_drawing.rb new file mode 100644 index 00000000..56131540 --- /dev/null +++ b/lib/axlsx/workbook/worksheet/worksheet_drawing.rb @@ -0,0 +1,48 @@ +module Axlsx + + # This is a utility class for serialing the drawing node in a + # worksheet. Drawing objects have their own serialization that exports + # a drawing document. This is only for the single node in the + # worksheet + class WorksheetDrawing + + def initialize(worksheet) + raise ArgumentError, 'you must provide a worksheet' unless worksheet.is_a?(Worksheet) + @worksheet = worksheet + @drawing = nil + end + + attr_reader :worksheet + attr_reader :drawing + + def add_chart(chart_type, options) + @drawing ||= Drawing.new worksheet + drawing.add_chart(chart_type, options) + end + + def add_image(options) + @drawing ||= Drawing.new worksheet + drawing.add_image(options) + end + + def has_drawing? + @drawing.is_a? Drawing + end + + # The relationship required by this object + # @return [Relationship] + def relationship + return unless has_drawing? + Relationship.new(DRAWING_R, "../#{drawing.pn}") + end + + def index + worksheet.relationships.index{ |r| r.Type == DRAWING_R } +1 + end + + def to_xml_string(str = '') + return unless has_drawing? + str << "<drawing r:id='rId#{index}'/>" + end + end +end |
