axlsx 1.3.6 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts_guide +19 -0
  3. data/CHANGELOG.md +8 -0
  4. data/README.md +52 -79
  5. data/Rakefile +0 -5
  6. data/examples/2010_comments.rb +17 -0
  7. data/examples/anchor_swapping.rb +28 -0
  8. data/examples/example.rb +16 -1
  9. data/examples/pivot_table.rb +2 -0
  10. data/examples/underline.rb +13 -0
  11. data/lib/axlsx.rb +8 -0
  12. data/lib/axlsx/doc_props/core.rb +6 -1
  13. data/lib/axlsx/drawing/axes.rb +7 -3
  14. data/lib/axlsx/drawing/bar_3D_chart.rb +2 -2
  15. data/lib/axlsx/drawing/chart.rb +20 -4
  16. data/lib/axlsx/drawing/drawing.rb +2 -17
  17. data/lib/axlsx/drawing/graphic_frame.rb +3 -8
  18. data/lib/axlsx/drawing/hyperlink.rb +5 -12
  19. data/lib/axlsx/drawing/marker.rb +25 -5
  20. data/lib/axlsx/drawing/one_cell_anchor.rb +9 -0
  21. data/lib/axlsx/drawing/pic.rb +17 -23
  22. data/lib/axlsx/drawing/two_cell_anchor.rb +7 -27
  23. data/lib/axlsx/package.rb +31 -11
  24. data/lib/axlsx/rels/relationship.rb +73 -8
  25. data/lib/axlsx/rels/relationships.rb +8 -1
  26. data/lib/axlsx/stylesheet/color.rb +1 -1
  27. data/lib/axlsx/stylesheet/num_fmt.rb +2 -2
  28. data/lib/axlsx/stylesheet/styles.rb +5 -3
  29. data/lib/axlsx/util/serialized_attributes.rb +11 -8
  30. data/lib/axlsx/util/simple_typed_list.rb +34 -13
  31. data/lib/axlsx/util/validators.rb +7 -0
  32. data/lib/axlsx/version.rb +1 -1
  33. data/lib/axlsx/workbook/defined_name.rb +1 -1
  34. data/lib/axlsx/workbook/shared_strings_table.rb +12 -3
  35. data/lib/axlsx/workbook/workbook.rb +31 -8
  36. data/lib/axlsx/workbook/worksheet/break.rb +37 -0
  37. data/lib/axlsx/workbook/worksheet/cell.rb +5 -5
  38. data/lib/axlsx/workbook/worksheet/cell_serializer.rb +1 -1
  39. data/lib/axlsx/workbook/worksheet/col_breaks.rb +35 -0
  40. data/lib/axlsx/workbook/worksheet/comment.rb +6 -5
  41. data/lib/axlsx/workbook/worksheet/comments.rb +3 -3
  42. data/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb +1 -1
  43. data/lib/axlsx/workbook/worksheet/date_time_converter.rb +6 -5
  44. data/lib/axlsx/workbook/worksheet/pivot_table.rb +32 -18
  45. data/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb +4 -3
  46. data/lib/axlsx/workbook/worksheet/pivot_tables.rb +1 -1
  47. data/lib/axlsx/workbook/worksheet/row.rb +1 -1
  48. data/lib/axlsx/workbook/worksheet/row_breaks.rb +33 -0
  49. data/lib/axlsx/workbook/worksheet/table.rb +3 -2
  50. data/lib/axlsx/workbook/worksheet/tables.rb +1 -1
  51. data/lib/axlsx/workbook/worksheet/worksheet.rb +61 -26
  52. data/lib/axlsx/workbook/worksheet/worksheet_comments.rb +6 -5
  53. data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +3 -9
  54. data/lib/axlsx/workbook/worksheet/worksheet_hyperlink.rb +5 -10
  55. data/lib/schema/sml.xsd +4 -0
  56. data/test/axlsx.qcachegrind +2226 -0
  57. data/test/doc_props/tc_core.rb +7 -0
  58. data/test/drawing/tc_axes.rb +8 -0
  59. data/test/drawing/tc_bar_3D_chart.rb +6 -0
  60. data/test/drawing/tc_chart.rb +13 -0
  61. data/test/drawing/tc_drawing.rb +0 -5
  62. data/test/drawing/tc_graphic_frame.rb +4 -7
  63. data/test/drawing/tc_hyperlink.rb +0 -4
  64. data/test/drawing/tc_pic.rb +14 -3
  65. data/test/drawing/tc_two_cell_anchor.rb +3 -3
  66. data/test/profile.rb +7 -3
  67. data/test/rels/tc_relationship.rb +29 -11
  68. data/test/rels/tc_relationships.rb +12 -1
  69. data/test/stylesheet/tc_color.rb +6 -0
  70. data/test/stylesheet/tc_styles.rb +2 -2
  71. data/test/tc_helper.rb +1 -0
  72. data/test/tc_package.rb +30 -0
  73. data/test/util/tc_serialized_attributes.rb +19 -0
  74. data/test/workbook/tc_shared_strings_table.rb +6 -0
  75. data/test/workbook/tc_workbook.rb +23 -1
  76. data/test/workbook/worksheet/tc_break.rb +49 -0
  77. data/test/workbook/worksheet/tc_comment.rb +17 -6
  78. data/test/workbook/worksheet/tc_conditional_formatting.rb +2 -2
  79. data/test/workbook/worksheet/tc_date_time_converter.rb +3 -11
  80. data/test/workbook/worksheet/tc_pivot_table.rb +40 -22
  81. data/test/workbook/worksheet/tc_pivot_table_cache_definition.rb +9 -1
  82. data/test/workbook/worksheet/tc_sheet_view.rb +39 -39
  83. data/test/workbook/worksheet/tc_table.rb +2 -2
  84. data/test/workbook/worksheet/tc_worksheet.rb +39 -7
  85. data/test/workbook/worksheet/tc_worksheet_hyperlink.rb +2 -11
  86. metadata +37 -10
  87. data/test/example.xlsx +0 -0
@@ -3,7 +3,43 @@ module Axlsx
3
3
  # A relationship defines a reference between package parts.
4
4
  # @note Packages automatically manage relationships.
5
5
  class Relationship
6
+
7
+ class << self
8
+ # Keeps track of all instances of this class.
9
+ # @return [Array]
10
+ def instances
11
+ @instances ||= []
12
+ end
13
+
14
+ # Clear cached instances.
15
+ #
16
+ # This should be called before serializing a package (see {Package#serialize} and
17
+ # {Package#to_stream}) to make sure that serialization is idempotent (i.e.
18
+ # Relationship instances are generated with the same IDs everytime the package
19
+ # is serialized).
20
+ #
21
+ # Also, calling this avoids memory leaks (cached instances lingering around
22
+ # forever).
23
+ def clear_cached_instances
24
+ @instances = []
25
+ end
26
+
27
+ # Generate and return a unique id (eg. `rId123`) Used for setting {#Id}.
28
+ #
29
+ # The generated id depends on the number of cached instances, so using
30
+ # {clear_cached_instances} will automatically reset the generated ids, too.
31
+ # @return [String]
32
+ def next_free_id
33
+ "rId#{@instances.size + 1}"
34
+ end
35
+ end
6
36
 
37
+ # The id of the relationship (eg. "rId123"). Most instances get their own unique id.
38
+ # However, some instances need to share the same id – see {#should_use_same_id_as?}
39
+ # for details.
40
+ # @return [String]
41
+ attr_reader :Id
42
+
7
43
  # The location of the relationship target
8
44
  # @return [String]
9
45
  attr_reader :Target
@@ -30,14 +66,26 @@ module Axlsx
30
66
  # Target mode must be :external for now.
31
67
  attr_reader :TargetMode
32
68
 
33
- # creates a new relationship
69
+ # The source object the relations belongs to (e.g. a hyperlink, drawing, ...). Needed when
70
+ # looking up the relationship for a specific object (see {Relationships#for}).
71
+ attr_reader :source_obj
72
+
73
+ # Initializes a new relationship.
74
+ # @param [Object] source_obj see {#source_obj}
34
75
  # @param [String] type The type of the relationship
35
76
  # @param [String] target The target for the relationship
36
77
  # @option [Symbol] :target_mode only accepts :external.
37
- def initialize(type, target, options={})
78
+ def initialize(source_obj, type, target, options={})
79
+ @source_obj = source_obj
38
80
  self.Target=target
39
81
  self.Type=type
40
- self.TargetMode = options.delete(:target_mode) if options[:target_mode]
82
+ self.TargetMode = options[:target_mode] if options[:target_mode]
83
+ @Id = if (existing = self.class.instances.find{ |i| should_use_same_id_as?(i) })
84
+ existing.Id
85
+ else
86
+ self.class.next_free_id
87
+ end
88
+ self.class.instances << self
41
89
  end
42
90
 
43
91
  # @see Target
@@ -50,15 +98,32 @@ module Axlsx
50
98
 
51
99
  # serialize relationship
52
100
  # @param [String] str
53
- # @param [Integer] rId the id for this relationship
54
101
  # @return [String]
55
- def to_xml_string(rId, str = '')
56
- h = self.instance_values
57
- h[:Id] = 'rId' << rId.to_s
102
+ def to_xml_string(str = '')
103
+ h = self.instance_values.reject{|k, _| k == "source_obj"}
58
104
  str << '<Relationship '
59
105
  str << h.map { |key, value| '' << key.to_s << '="' << Axlsx::coder.encode(value.to_s) << '"'}.join(' ')
60
106
  str << '/>'
61
107
  end
62
-
108
+
109
+ # Whether this relationship should use the same id as `other`.
110
+ #
111
+ # Instances designating the same relationship need to use the same id. We can not simply
112
+ # compare the {#Target} attribute, though: `foo/bar.xml`, `../foo/bar.xml`,
113
+ # `../../foo/bar.xml` etc. are all different but probably mean the same file (this
114
+ # is especially an issue for relationships in the context of pivot tables). So lets
115
+ # just ignore this attribute for now (except when {#TargetMode} is set to `:External` –
116
+ # then {#Target} will be an absolute URL and thus can safely be compared).
117
+ #
118
+ # @todo Implement comparison of {#Target} based on normalized path names.
119
+ # @param other [Relationship]
120
+ def should_use_same_id_as?(other)
121
+ result = self.source_obj == other.source_obj && self.Type == other.Type && self.TargetMode == other.TargetMode
122
+ if self.TargetMode == :External
123
+ result &&= self.Target == other.Target
124
+ end
125
+ result
126
+ end
127
+
63
128
  end
64
129
  end
@@ -11,10 +11,17 @@ require 'axlsx/rels/relationship.rb'
11
11
  super Relationship
12
12
  end
13
13
 
14
+ # The relationship instance for the given source object, or nil if none exists.
15
+ # @see Relationship#source_obj
16
+ # @return [Relationship]
17
+ def for(source_obj)
18
+ @list.find{ |rel| rel.source_obj == source_obj }
19
+ end
20
+
14
21
  def to_xml_string(str = '')
15
22
  str << '<?xml version="1.0" encoding="UTF-8"?>'
16
23
  str << '<Relationships xmlns="' << RELS_R << '">'
17
- each_with_index { |rel, index| rel.to_xml_string(index+1, str) }
24
+ each{ |rel| rel.to_xml_string(str) }
18
25
  str << '</Relationships>'
19
26
  end
20
27
 
@@ -51,7 +51,7 @@ module Axlsx
51
51
  # @see color
52
52
  def rgb=(v)
53
53
  Axlsx::validate_string(v)
54
- v.upcase!
54
+ v = v.upcase
55
55
  v = v * 3 if v.size == 2
56
56
  v = v.rjust(8, 'FF')
57
57
  raise ArgumentError, "Invalid color rgb value: #{v}." unless v.match(/[0-9A-F]{8}/)
@@ -10,7 +10,7 @@ module Axlsx
10
10
  # Creates a new NumFmt object
11
11
  # @param [Hash] options Options for the number format object
12
12
  # @option [Integer] numFmtId The predefined format id or new format id for this format
13
- # @option [String] fomratCode The format code for this number format
13
+ # @option [String] formatCode The format code for this number format
14
14
  def initialize(options={})
15
15
  @numFmtId = 0
16
16
  @formatCode = ""
@@ -23,7 +23,7 @@ module Axlsx
23
23
  # @see http://support.microsoft.com/kb/264372
24
24
  attr_reader :formatCode
25
25
 
26
- # @return [Integer] An unsinged integer referencing a standard or custom number format.
26
+ # @return [Integer] An unsigned integer referencing a standard or custom number format.
27
27
  # @note
28
28
  # These are the known formats I can dig up. The constant NUM_FMT_PERCENT is 9, and uses the default % formatting. Axlsx also defines a few formats for date and time that are commonly used in asia as NUM_FMT_YYYYMMDD and NUM_FRM_YYYYMMDDHHMMSS.
29
29
  # 1 0
@@ -183,7 +183,7 @@ module Axlsx
183
183
  # :border=>Axlsx::STYLE_THIN_BORDER)
184
184
  #
185
185
  # # build your rows
186
- # ws.add_row ["Genreated At:", Time.now], :styles=>[nil, date_time]
186
+ # ws.add_row ["Generated At:", Time.now], :styles=>[nil, date_time]
187
187
  # ws.add_row ["Previous Year Quarterly Profits (JPY)"], :style=>title
188
188
  # ws.add_row ["Quarter", "Profit", "% of Total"], :style=>title
189
189
  # ws.add_row ["Q1", 4000, 40], :style=>[title, currency, percent]
@@ -296,9 +296,11 @@ module Axlsx
296
296
  def parse_fill_options(options={})
297
297
  return unless options[:bg_color]
298
298
  color = Color.new(:rgb=>options[:bg_color])
299
- pattern = PatternFill.new(:patternType =>:solid, :fgColor=>color)
299
+ dxf = options[:type] == :dxf
300
+ color_key = dxf ? :bgColor : :fgColor
301
+ pattern = PatternFill.new(:patternType =>:solid, color_key=>color)
300
302
  fill = Fill.new(pattern)
301
- options[:type] == :dxf ? fill : fills << fill
303
+ dxf ? fill : fills << fill
302
304
  end
303
305
 
304
306
  # parses Style#add_style options for borders.
@@ -40,18 +40,21 @@ module Axlsx
40
40
  # @param [Hash] additional_attributes An option key value hash for
41
41
  # defining values that are not serializable attributes list.
42
42
  def serialized_attributes(str = '', additional_attributes = {})
43
- key_value_pairs = instance_values
44
- key_value_pairs.each do |key, value|
45
- key_value_pairs.delete(key) if value == nil
46
- key_value_pairs.delete(key) unless self.class.xml_attributes.include?(key.to_sym)
47
- end
48
- key_value_pairs.merge! additional_attributes
49
- key_value_pairs.each do |key, value|
50
- str << "#{Axlsx.camel(key, false)}=\"#{value}\" "
43
+ attributes = declared_attributes.merge! additional_attributes
44
+ attributes.each do |key, value|
45
+ str << "#{Axlsx.camel(key, false)}=\"#{Axlsx.camel(value, false)}\" "
51
46
  end
52
47
  str
53
48
  end
54
49
 
50
+ # A hash of instance variables that have been declared with
51
+ # seraialized_attributes and are not nil.
52
+ # This requires ruby 1.9.3 or higher
53
+ def declared_attributes
54
+ instance_values.select do |key, value|
55
+ value != nil && self.class.xml_attributes.include?(key.to_sym)
56
+ end
57
+ end
55
58
 
56
59
  # serialized instance values at text nodes on a camelized element of the
57
60
  # attribute name. You may pass in a block for evaluation against non nil
@@ -1,21 +1,9 @@
1
1
  # encoding: UTF-8
2
2
  module Axlsx
3
+
3
4
  # A SimpleTypedList is a type restrictive collection that allows some of the methods from Array and supports basic xml serialization.
4
5
  # @private
5
6
  class SimpleTypedList
6
- # The class constants of allowed types
7
- # @return [Array]
8
- attr_reader :allowed_types
9
-
10
- # The index below which items cannot be removed
11
- # @return [Integer]
12
- attr_reader :locked_at
13
-
14
- # The tag name to use when serializing this object
15
- # by default the parent node for all items in the list is the classname of the first allowed type with the first letter in lowercase.
16
- # @return [String]
17
- attr_reader :serialize_as
18
-
19
7
  # Creats a new typed list
20
8
  # @param [Array, Class] type An array of Class objects or a single Class object
21
9
  # @param [String] serialize_as The tag name to use in serialization
@@ -33,6 +21,39 @@ module Axlsx
33
21
  @serialize_as = serialize_as
34
22
  end
35
23
 
24
+ # The class constants of allowed types
25
+ # @return [Array]
26
+ attr_reader :allowed_types
27
+
28
+ # The index below which items cannot be removed
29
+ # @return [Integer]
30
+ attr_reader :locked_at
31
+
32
+ # The tag name to use when serializing this object
33
+ # by default the parent node for all items in the list is the classname of the first allowed type with the first letter in lowercase.
34
+ # @return [String]
35
+ attr_reader :serialize_as
36
+
37
+ # Transposes the list (without blowing up like ruby does)
38
+ # any non populated cell in the matrix will be a nil value
39
+ def transpose
40
+ return @list.clone if @list.size == 0
41
+ row_count = @list.size
42
+ max_column_count = @list.map{|row| row.cells.size}.max
43
+ result = Array.new(max_column_count) { Array.new(row_count) }
44
+ # yes, I know it is silly, but that warning is really annoying
45
+ row_count.times do |row_index|
46
+ max_column_count.times do |column_index|
47
+ datum = if @list[row_index].cells.size >= max_column_count
48
+ @list[row_index].cells[column_index]
49
+ elsif block_given?
50
+ yield(column_index, row_index)
51
+ end
52
+ result[column_index][row_index] = datum
53
+ end
54
+ end
55
+ result
56
+ end
36
57
  # Lock this list at the current size
37
58
  # @return [self]
38
59
  def lock
@@ -290,4 +290,11 @@ module Axlsx
290
290
  def self.validate_split_state_type(v)
291
291
  RestrictionValidator.validate :split_state_type, [:frozen, :frozen_split, :split], v
292
292
  end
293
+
294
+ # Requires that the value is a valid "display blanks as" type.
295
+ # valid types must be one of gap, span, zero
296
+ # @param [Any] v The value validated
297
+ def self.validate_display_blanks_as(v)
298
+ RestrictionValidator.validate :display_blanks_as, [:gap, :span, :zero], v
299
+ end
293
300
  end
@@ -1,5 +1,5 @@
1
1
  module Axlsx
2
2
 
3
3
  # The current version
4
- VERSION = "1.3.6"
4
+ VERSION = "2.0.0"
5
5
  end
@@ -105,7 +105,7 @@ module Axlsx
105
105
  attr_reader :local_sheet_id
106
106
 
107
107
  # The local sheet index (0-based)
108
- # @param [Integer] value the unsinged integer index of the sheet this defined_name applies to.
108
+ # @param [Integer] value the unsigned integer index of the sheet this defined_name applies to.
109
109
  def local_sheet_id=(value)
110
110
  Axlsx::validate_unsigned_int(value)
111
111
  @local_sheet_id = value
@@ -26,10 +26,16 @@ module Axlsx
26
26
  # @see Cell#sharable
27
27
  attr_reader :unique_cells
28
28
 
29
+ # The xml:space attribute
30
+ # @see Workbook#xml_space
31
+ attr_reader :xml_space
32
+
29
33
  # Creates a new Shared Strings Table agains an array of cells
30
34
  # @param [Array] cells This is an array of all of the cells in the workbook
31
- def initialize(cells)
35
+ # @param [Symbol] xml_space The xml:space behavior for the shared string table.
36
+ def initialize(cells, xml_space=:preserve)
32
37
  @index = 0
38
+ @xml_space = xml_space
33
39
  @unique_cells = {}
34
40
  @shared_xml_string = ""
35
41
  shareable_cells = cells.flatten.select{ |cell| cell.plain_string? }
@@ -40,8 +46,11 @@ module Axlsx
40
46
  # Serializes the object
41
47
  # @param [String] str
42
48
  # @return [String]
43
- def to_xml_string
44
- '<?xml version="1.0" encoding="UTF-8"?><sst xmlns="' << XML_NS << '" count="' << @count.to_s << '" uniqueCount="' << unique_count.to_s << '">' << @shared_xml_string << '</sst>'
49
+ def to_xml_string(str='')
50
+ str << '<?xml version="1.0" encoding="UTF-8"?><sst xmlns="' << XML_NS << '"'
51
+ str << ' count="' << @count.to_s << '" uniqueCount="' << unique_count.to_s << '"'
52
+ str << ' xml:space="' << xml_space.to_s << '">' << @shared_xml_string << '</sst>'
53
+ str = Axlsx::sanitize(str)
45
54
  end
46
55
 
47
56
  private
@@ -34,6 +34,12 @@ require 'axlsx/workbook/worksheet/worksheet_drawing.rb'
34
34
  require 'axlsx/workbook/worksheet/worksheet_comments.rb'
35
35
  require 'axlsx/workbook/worksheet/worksheet_hyperlink'
36
36
  require 'axlsx/workbook/worksheet/worksheet_hyperlinks'
37
+ require 'axlsx/workbook/worksheet/break'
38
+ require 'axlsx/workbook/worksheet/row_breaks'
39
+ require 'axlsx/workbook/worksheet/col_breaks'
40
+
41
+
42
+
37
43
  require 'axlsx/workbook/worksheet/worksheet.rb'
38
44
  require 'axlsx/workbook/shared_strings_table.rb'
39
45
  require 'axlsx/workbook/defined_name.rb'
@@ -270,14 +276,14 @@ require 'axlsx/workbook/worksheet/selection.rb'
270
276
  def relationships
271
277
  r = Relationships.new
272
278
  @worksheets.each do |sheet|
273
- r << Relationship.new(WORKSHEET_R, WORKSHEET_PN % (r.size+1))
279
+ r << Relationship.new(sheet, WORKSHEET_R, WORKSHEET_PN % (r.size+1))
274
280
  end
275
281
  pivot_tables.each_with_index do |pivot_table, index|
276
- r << Relationship.new(PIVOT_TABLE_CACHE_DEFINITION_R, PIVOT_TABLE_CACHE_DEFINITION_PN % (index+1))
282
+ r << Relationship.new(pivot_table.cache_definition, PIVOT_TABLE_CACHE_DEFINITION_R, PIVOT_TABLE_CACHE_DEFINITION_PN % (index+1))
277
283
  end
278
- r << Relationship.new(STYLES_R, STYLES_PN)
284
+ r << Relationship.new(self, STYLES_R, STYLES_PN)
279
285
  if use_shared_strings
280
- r << Relationship.new(SHARED_STRINGS_R, SHARED_STRINGS_PN)
286
+ r << Relationship.new(self, SHARED_STRINGS_R, SHARED_STRINGS_PN)
281
287
  end
282
288
  r
283
289
  end
@@ -285,7 +291,25 @@ require 'axlsx/workbook/worksheet/selection.rb'
285
291
  # generates a shared string object against all cells in all worksheets.
286
292
  # @return [SharedStringTable]
287
293
  def shared_strings
288
- SharedStringsTable.new(worksheets.collect { |ws| ws.cells })
294
+ SharedStringsTable.new(worksheets.collect { |ws| ws.cells }, xml_space)
295
+ end
296
+
297
+ # The xml:space attribute for the worksheet.
298
+ # This determines how whitespace is handled withing the document.
299
+ # The most relevant part being whitespace in the cell text.
300
+ # allowed values are :preserve and :default. Axlsx uses :preserve unless
301
+ # you explicily set this to :default.
302
+ # @return Symbol
303
+ def xml_space
304
+ @xml_space ||= :preserve
305
+ end
306
+
307
+ # Sets the xml:space attribute for the worksheet
308
+ # @see Worksheet#xml_space
309
+ # @param [Symbol] space must be one of :preserve or :default
310
+ def xml_space=(space)
311
+ Axlsx::RestrictionValidator.validate(:xml_space, [:preserve, :default], space)
312
+ @xml_space = space;
289
313
  end
290
314
 
291
315
  # returns a range of cells in a worksheet
@@ -318,9 +342,8 @@ require 'axlsx/workbook/worksheet/selection.rb'
318
342
  defined_names.to_xml_string(str)
319
343
  unless pivot_tables.empty?
320
344
  str << '<pivotCaches>'
321
- pivot_tables.each_with_index do |pivot_table, index|
322
- rId = "rId#{@worksheets.size + index + 1 }"
323
- str << '<pivotCache cacheId="' << pivot_table.cache_definition.cache_id.to_s << '" r:id="' << rId << '"/>'
345
+ pivot_tables.each do |pivot_table|
346
+ str << '<pivotCache cacheId="' << pivot_table.cache_definition.cache_id.to_s << '" r:id="' << pivot_table.cache_definition.rId << '"/>'
324
347
  end
325
348
  str << '</pivotCaches>'
326
349
  end
@@ -0,0 +1,37 @@
1
+ module Axlsx
2
+
3
+ # The Break class stores the details for row and column page breaks.
4
+ # @see RowBreaks, ColBreaks
5
+ class Break
6
+
7
+ include Axlsx::OptionsParser
8
+ include Axlsx::Accessors
9
+ include Axlsx::SerializedAttributes
10
+
11
+ # Creates a new Break object
12
+ # @param options A hash of attribute options for this break.
13
+ # @option options [Integer] id Zero-based row or column Id of the page break. Breaks occur above the specified row and left of the specified column.
14
+ # @option options [Integer] min Zero-based index of start row or column of the break. For row breaks, specifies column index; for column breaks, specifies row index.
15
+ # @option options [Integer] max Zero-based index of end row or column of the break. For row breaks, specifies column index; for column breaks, specifies row index.
16
+ # @option options [Boolean] man Manual Break flag. 1 means the break is a manually inserted break.
17
+ # @option option [Boolean] pt Flag indicating that a PivotTable created this break.
18
+ def initialize(options={})
19
+ parse_options options
20
+ yield self if block_given?
21
+ end
22
+
23
+ unsigned_int_attr_accessor :id, :min, :max
24
+
25
+ boolean_attr_accessor :man, :pt
26
+
27
+ serializable_attributes :id, :min, :max, :man, :pt
28
+
29
+ # serializes the break to xml
30
+ def to_xml_string(str='')
31
+ str << '<brk '
32
+ serialized_attributes str
33
+ str << '></brk>'
34
+ end
35
+ end
36
+ end
37
+
@@ -302,7 +302,7 @@ module Axlsx
302
302
  def to_xml_string(r_index, c_index, str = '')
303
303
  CellSerializer.to_xml_string r_index, c_index, self, str
304
304
  end
305
-
305
+
306
306
  def is_formula?
307
307
  @type == :string && @value.to_s.start_with?('=')
308
308
  end
@@ -318,9 +318,9 @@ module Axlsx
318
318
  end
319
319
 
320
320
  # returns the absolute or relative string style reference for
321
- # this cell.
321
+ # this cell.
322
322
  # @param [Boolean] absolute -when false a relative reference will be
323
- # returned.
323
+ # returned.
324
324
  # @return [String]
325
325
  def reference(absolute=true)
326
326
  absolute ? r_abs : r
@@ -353,7 +353,7 @@ module Axlsx
353
353
 
354
354
  # assigns the owning row for this cell.
355
355
  def row=(v) @row=v end
356
-
356
+
357
357
  # Determines the cell type based on the cell value.
358
358
  # @note This is only used when a cell is created but no :type option is specified, the following rules apply:
359
359
  # 1. If the value is an instance of Date, the type is set to :date
@@ -375,7 +375,7 @@ module Axlsx
375
375
  :float
376
376
  # \A(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[0-1]|0[1-9]|[1-2][0-9])
377
377
  # T(2[0-3]|[0-1][0-9]):([0-5][0-9]):([0-5][0-9])(\.[0-9]+)?
378
- # (Z|[+-](?:2[0-3]|[0-1][0-9]):[0-5][0-9])?\Z
378
+ # (Z|[+-](?:2[0-3]|[0-1][0-9]):[0-5][0-9])?\Z
379
379
  elsif v.to_s =~/\A(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[0-1]|0[1-9]|[1-2][0-9])T(2[0-3]|[0-1][0-9]):([0-5][0-9]):([0-5][0-9])(\.[0-9]+)?(Z|[+-](?:2[0-3]|[0-1][0-9]):[0-5][0-9])?\Z/
380
380
  :iso_8601
381
381
  else