axlsx 2.0.1 → 3.0.0.pre

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 (180) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/README.md +23 -23
  4. data/Rakefile +9 -11
  5. data/examples/auto_filter.rb +10 -1
  6. data/examples/conditional_formatting/example_conditional_formatting.rb +18 -3
  7. data/examples/example.rb +102 -4
  8. data/examples/merge_cells.rb +17 -0
  9. data/examples/no_grid_with_borders.rb +18 -0
  10. data/examples/pivot_test.rb +63 -0
  11. data/examples/split.rb +16 -0
  12. data/lib/axlsx/content_type/abstract_content_type.rb +1 -1
  13. data/lib/axlsx/content_type/content_type.rb +1 -1
  14. data/lib/axlsx/doc_props/app.rb +1 -1
  15. data/lib/axlsx/doc_props/core.rb +5 -5
  16. data/lib/axlsx/drawing/area_chart.rb +99 -0
  17. data/lib/axlsx/drawing/area_series.rb +110 -0
  18. data/lib/axlsx/drawing/axes.rb +1 -1
  19. data/lib/axlsx/drawing/axis.rb +12 -9
  20. data/lib/axlsx/drawing/bar_3D_chart.rb +13 -13
  21. data/lib/axlsx/drawing/bar_chart.rb +143 -0
  22. data/lib/axlsx/drawing/bar_series.rb +9 -9
  23. data/lib/axlsx/drawing/bubble_chart.rb +59 -0
  24. data/lib/axlsx/drawing/bubble_series.rb +63 -0
  25. data/lib/axlsx/drawing/cat_axis.rb +5 -5
  26. data/lib/axlsx/drawing/chart.rb +52 -8
  27. data/lib/axlsx/drawing/d_lbls.rb +3 -3
  28. data/lib/axlsx/drawing/drawing.rb +6 -1
  29. data/lib/axlsx/drawing/graphic_frame.rb +3 -3
  30. data/lib/axlsx/drawing/hyperlink.rb +1 -3
  31. data/lib/axlsx/drawing/line_3D_chart.rb +2 -2
  32. data/lib/axlsx/drawing/line_chart.rb +10 -10
  33. data/lib/axlsx/drawing/line_series.rb +32 -3
  34. data/lib/axlsx/drawing/marker.rb +1 -1
  35. data/lib/axlsx/drawing/num_data.rb +4 -4
  36. data/lib/axlsx/drawing/num_data_source.rb +6 -6
  37. data/lib/axlsx/drawing/num_val.rb +3 -1
  38. data/lib/axlsx/drawing/one_cell_anchor.rb +3 -2
  39. data/lib/axlsx/drawing/pic.rb +25 -19
  40. data/lib/axlsx/drawing/picture_locking.rb +1 -3
  41. data/lib/axlsx/drawing/pie_3D_chart.rb +5 -6
  42. data/lib/axlsx/drawing/pie_series.rb +6 -6
  43. data/lib/axlsx/drawing/scaling.rb +6 -6
  44. data/lib/axlsx/drawing/scatter_chart.rb +10 -10
  45. data/lib/axlsx/drawing/scatter_series.rb +40 -7
  46. data/lib/axlsx/drawing/ser_axis.rb +2 -2
  47. data/lib/axlsx/drawing/series.rb +3 -3
  48. data/lib/axlsx/drawing/series_title.rb +2 -2
  49. data/lib/axlsx/drawing/str_data.rb +3 -3
  50. data/lib/axlsx/drawing/str_val.rb +3 -1
  51. data/lib/axlsx/drawing/title.rb +22 -4
  52. data/lib/axlsx/drawing/two_cell_anchor.rb +6 -1
  53. data/lib/axlsx/drawing/val_axis.rb +1 -1
  54. data/lib/axlsx/drawing/view_3D.rb +2 -2
  55. data/lib/axlsx/drawing/vml_drawing.rb +1 -1
  56. data/lib/axlsx/package.rb +34 -32
  57. data/lib/axlsx/rels/relationship.rb +1 -1
  58. data/lib/axlsx/rels/relationships.rb +7 -4
  59. data/lib/axlsx/stylesheet/border_pr.rb +2 -2
  60. data/lib/axlsx/stylesheet/cell_alignment.rb +1 -3
  61. data/lib/axlsx/stylesheet/cell_protection.rb +1 -3
  62. data/lib/axlsx/stylesheet/cell_style.rb +1 -3
  63. data/lib/axlsx/stylesheet/color.rb +1 -3
  64. data/lib/axlsx/stylesheet/font.rb +1 -1
  65. data/lib/axlsx/stylesheet/gradient_stop.rb +1 -1
  66. data/lib/axlsx/stylesheet/num_fmt.rb +10 -3
  67. data/lib/axlsx/stylesheet/pattern_fill.rb +1 -1
  68. data/lib/axlsx/stylesheet/styles.rb +7 -7
  69. data/lib/axlsx/stylesheet/table_style_element.rb +1 -3
  70. data/lib/axlsx/util/accessors.rb +6 -6
  71. data/lib/axlsx/util/constants.rb +107 -99
  72. data/lib/axlsx/util/mime_type_utils.rb +11 -0
  73. data/lib/axlsx/util/options_parser.rb +2 -1
  74. data/lib/axlsx/util/parser.rb +4 -4
  75. data/lib/axlsx/util/serialized_attributes.rb +16 -6
  76. data/lib/axlsx/util/simple_typed_list.rb +28 -52
  77. data/lib/axlsx/util/storage.rb +4 -4
  78. data/lib/axlsx/util/validators.rb +29 -17
  79. data/lib/axlsx/version.rb +1 -1
  80. data/lib/axlsx/workbook/defined_name.rb +11 -12
  81. data/lib/axlsx/workbook/defined_names.rb +2 -2
  82. data/lib/axlsx/workbook/shared_strings_table.rb +5 -5
  83. data/lib/axlsx/workbook/workbook.rb +36 -11
  84. data/lib/axlsx/workbook/workbook_view.rb +80 -0
  85. data/lib/axlsx/workbook/workbook_views.rb +22 -0
  86. data/lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb +2 -2
  87. data/lib/axlsx/workbook/worksheet/auto_filter/filters.rb +1 -3
  88. data/lib/axlsx/workbook/worksheet/break.rb +1 -3
  89. data/lib/axlsx/workbook/worksheet/cell.rb +136 -74
  90. data/lib/axlsx/workbook/worksheet/cell_serializer.rb +63 -43
  91. data/lib/axlsx/workbook/worksheet/cfvo.rb +1 -3
  92. data/lib/axlsx/workbook/worksheet/cfvos.rb +4 -1
  93. data/lib/axlsx/workbook/worksheet/col.rb +7 -10
  94. data/lib/axlsx/workbook/worksheet/col_breaks.rb +2 -2
  95. data/lib/axlsx/workbook/worksheet/cols.rb +5 -2
  96. data/lib/axlsx/workbook/worksheet/comment.rb +5 -6
  97. data/lib/axlsx/workbook/worksheet/comments.rb +9 -12
  98. data/lib/axlsx/workbook/worksheet/conditional_formatting.rb +1 -1
  99. data/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb +1 -1
  100. data/lib/axlsx/workbook/worksheet/data_bar.rb +4 -6
  101. data/lib/axlsx/workbook/worksheet/data_validation.rb +6 -4
  102. data/lib/axlsx/workbook/worksheet/dimension.rb +2 -2
  103. data/lib/axlsx/workbook/worksheet/header_footer.rb +6 -8
  104. data/lib/axlsx/workbook/worksheet/icon_set.rb +3 -5
  105. data/lib/axlsx/workbook/worksheet/merged_cells.rb +4 -2
  106. data/lib/axlsx/workbook/worksheet/outline_pr.rb +33 -0
  107. data/lib/axlsx/workbook/worksheet/page_margins.rb +1 -3
  108. data/lib/axlsx/workbook/worksheet/page_set_up_pr.rb +1 -1
  109. data/lib/axlsx/workbook/worksheet/page_setup.rb +21 -23
  110. data/lib/axlsx/workbook/worksheet/pane.rb +1 -3
  111. data/lib/axlsx/workbook/worksheet/pivot_table.rb +44 -28
  112. data/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb +4 -4
  113. data/lib/axlsx/workbook/worksheet/print_options.rb +1 -3
  114. data/lib/axlsx/workbook/worksheet/protected_range.rb +1 -3
  115. data/lib/axlsx/workbook/worksheet/protected_ranges.rb +5 -2
  116. data/lib/axlsx/workbook/worksheet/rich_text.rb +55 -0
  117. data/lib/axlsx/workbook/worksheet/rich_text_run.rb +250 -0
  118. data/lib/axlsx/workbook/worksheet/row.rb +40 -51
  119. data/lib/axlsx/workbook/worksheet/row_breaks.rb +2 -2
  120. data/lib/axlsx/workbook/worksheet/selection.rb +1 -3
  121. data/lib/axlsx/workbook/worksheet/sheet_data.rb +3 -1
  122. data/lib/axlsx/workbook/worksheet/sheet_pr.rb +21 -3
  123. data/lib/axlsx/workbook/worksheet/sheet_protection.rb +1 -3
  124. data/lib/axlsx/workbook/worksheet/table.rb +6 -6
  125. data/lib/axlsx/workbook/worksheet/table_style_info.rb +1 -3
  126. data/lib/axlsx/workbook/worksheet/tables.rb +4 -1
  127. data/lib/axlsx/workbook/worksheet/worksheet.rb +64 -78
  128. data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +10 -10
  129. data/lib/axlsx/workbook/worksheet/worksheet_hyperlinks.rb +3 -3
  130. data/lib/axlsx.rb +34 -15
  131. data/test/drawing/tc_area_chart.rb +39 -0
  132. data/test/drawing/tc_area_series.rb +71 -0
  133. data/test/drawing/tc_axis.rb +27 -0
  134. data/test/drawing/tc_bar_chart.rb +71 -0
  135. data/test/drawing/tc_bubble_chart.rb +44 -0
  136. data/test/drawing/tc_bubble_series.rb +21 -0
  137. data/test/drawing/tc_chart.rb +23 -10
  138. data/test/drawing/tc_data_source.rb +6 -0
  139. data/test/drawing/tc_drawing.rb +2 -2
  140. data/test/drawing/tc_line_chart.rb +5 -5
  141. data/test/drawing/tc_line_series.rb +47 -6
  142. data/test/drawing/tc_pic.rb +11 -15
  143. data/test/drawing/tc_scatter_series.rb +36 -1
  144. data/test/drawing/tc_str_val.rb +9 -0
  145. data/test/drawing/tc_title.rb +5 -0
  146. data/test/stylesheet/tc_styles.rb +2 -2
  147. data/test/tc_axlsx.rb +31 -0
  148. data/test/tc_helper.rb +2 -0
  149. data/test/tc_package.rb +19 -1
  150. data/test/util/tc_mime_type_utils.rb +13 -0
  151. data/test/util/tc_simple_typed_list.rb +2 -3
  152. data/test/util/tc_validators.rb +34 -10
  153. data/test/workbook/tc_defined_name.rb +12 -4
  154. data/test/workbook/tc_shared_strings_table.rb +16 -1
  155. data/test/workbook/tc_workbook.rb +38 -3
  156. data/test/workbook/tc_workbook_view.rb +50 -0
  157. data/test/workbook/worksheet/auto_filter/tc_filters.rb +1 -1
  158. data/test/workbook/worksheet/tc_break.rb +1 -1
  159. data/test/workbook/worksheet/tc_cell.rb +76 -8
  160. data/test/workbook/worksheet/tc_col.rb +2 -2
  161. data/test/workbook/worksheet/tc_conditional_formatting.rb +2 -2
  162. data/test/workbook/worksheet/tc_data_bar.rb +1 -1
  163. data/test/workbook/worksheet/tc_data_validation.rb +11 -11
  164. data/test/workbook/worksheet/tc_header_footer.rb +2 -2
  165. data/test/workbook/worksheet/tc_icon_set.rb +1 -1
  166. data/test/workbook/worksheet/tc_outline_pr.rb +19 -0
  167. data/test/workbook/worksheet/tc_page_setup.rb +3 -3
  168. data/test/workbook/worksheet/tc_pivot_table.rb +21 -6
  169. data/test/workbook/worksheet/tc_print_options.rb +1 -1
  170. data/test/workbook/worksheet/tc_rich_text.rb +44 -0
  171. data/test/workbook/worksheet/tc_rich_text_run.rb +172 -0
  172. data/test/workbook/worksheet/tc_row.rb +7 -2
  173. data/test/workbook/worksheet/tc_sheet_calc_pr.rb +1 -1
  174. data/test/workbook/worksheet/tc_sheet_format_pr.rb +4 -4
  175. data/test/workbook/worksheet/tc_sheet_pr.rb +26 -4
  176. data/test/workbook/worksheet/tc_sheet_protection.rb +5 -5
  177. data/test/workbook/worksheet/tc_sheet_view.rb +4 -4
  178. data/test/workbook/worksheet/tc_table.rb +2 -3
  179. data/test/workbook/worksheet/tc_worksheet.rb +99 -45
  180. metadata +142 -64
@@ -20,15 +20,18 @@ module Axlsx
20
20
  elsif cells.is_a?(SimpleTypedList) || cells.is_a?(Array)
21
21
  Axlsx::cell_range(cells, false)
22
22
  end
23
- @list << ProtectedRange.new(:sqref => sqref, :name => "Range#{size}")
23
+ self << ProtectedRange.new(:sqref => sqref, :name => "Range#{size}")
24
24
  last
25
25
  end
26
26
 
27
+ # Serializes the protected ranges
28
+ # @param [String] str
29
+ # @return [String]
27
30
  def to_xml_string(str = '')
28
31
  return if empty?
29
32
  str << '<protectedRanges>'
30
33
  each { |range| range.to_xml_string(str) }
31
- str << '</protectedRanges>'
34
+ str << '</protectedRanges>'
32
35
  end
33
36
  end
34
37
  end
@@ -0,0 +1,55 @@
1
+ module Axlsx
2
+
3
+ # A simple, self serializing class for storing TextRuns
4
+ class RichText < SimpleTypedList
5
+
6
+ # creates a new RichText collection
7
+ # @param [String] text -optional The text to use in creating the first RichTextRun
8
+ # @param [Object] options -optional The options to use in creating the first RichTextRun
9
+ # @yield [RichText] self
10
+ def initialize(text = nil, options={})
11
+ super(RichTextRun)
12
+ add_run(text, options) unless text.nil?
13
+ yield self if block_given?
14
+ end
15
+
16
+ # The cell that owns this RichText collection
17
+ attr_reader :cell
18
+
19
+ # Assign the cell for this RichText collection
20
+ # @param [Cell] cell The cell which all RichTextRuns in the collection will belong to
21
+ def cell=(cell)
22
+ @cell = cell
23
+ each { |run| run.cell = cell }
24
+ end
25
+
26
+ # Calculates the longest autowidth of the RichTextRuns in this collection
27
+ # @return [Number]
28
+ def autowidth
29
+ widtharray = [0] # Are arrays the best way of solving this problem?
30
+ each { |run| run.autowidth(widtharray) }
31
+ widtharray.max
32
+ end
33
+
34
+ # Creates and adds a RichTextRun to this collectino
35
+ # @param [String] text The text to use in creating a new RichTextRun
36
+ # @param [Object] options The options to use in creating the new RichTextRun
37
+ def add_run(text, options={})
38
+ self << RichTextRun.new(text, options)
39
+ end
40
+
41
+ # The RichTextRuns we own
42
+ # @return [RichText]
43
+ def runs
44
+ self
45
+ end
46
+
47
+ # renders the RichTextRuns in this collection
48
+ # @param [String] str
49
+ # @return [String]
50
+ def to_xml_string(str='')
51
+ each{ |run| run.to_xml_string(str) }
52
+ str
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,250 @@
1
+ module Axlsx
2
+
3
+ # The RichTextRun class creates and self serializing text run.
4
+ class RichTextRun
5
+
6
+ include Axlsx::OptionsParser
7
+
8
+ attr_reader :value
9
+
10
+ # A list of allowed inline style attributes used for validation
11
+ INLINE_STYLES = [:font_name, :charset,
12
+ :family, :b, :i, :strike, :outline,
13
+ :shadow, :condense, :extend, :u,
14
+ :vertAlign, :sz, :color, :scheme].freeze
15
+
16
+ def initialize(value, options={})
17
+ self.value = value
18
+ parse_options(options)
19
+ end
20
+
21
+ def value=(value)
22
+ @value = value
23
+ end
24
+
25
+ attr_accessor :cell
26
+
27
+ # The inline font_name property for the cell
28
+ # @return [String]
29
+ attr_reader :font_name
30
+ # @see font_name
31
+ def font_name=(v) set_run_style :validate_string, :font_name, v; end
32
+
33
+ # The inline charset property for the cell
34
+ # As far as I can tell, this is pretty much ignored. However, based on the spec it should be one of the following:
35
+ # 0  ANSI_CHARSET
36
+ # 1 DEFAULT_CHARSET
37
+ # 2 SYMBOL_CHARSET
38
+ # 77 MAC_CHARSET
39
+ # 128 SHIFTJIS_CHARSET
40
+ # 129  HANGUL_CHARSET
41
+ # 130  JOHAB_CHARSET
42
+ # 134  GB2312_CHARSET
43
+ # 136  CHINESEBIG5_CHARSET
44
+ # 161  GREEK_CHARSET
45
+ # 162  TURKISH_CHARSET
46
+ # 163  VIETNAMESE_CHARSET
47
+ # 177  HEBREW_CHARSET
48
+ # 178  ARABIC_CHARSET
49
+ # 186  BALTIC_CHARSET
50
+ # 204  RUSSIAN_CHARSET
51
+ # 222  THAI_CHARSET
52
+ # 238  EASTEUROPE_CHARSET
53
+ # 255  OEM_CHARSET
54
+ # @return [String]
55
+ attr_reader :charset
56
+ # @see charset
57
+ def charset=(v) set_run_style :validate_unsigned_int, :charset, v; end
58
+
59
+ # The inline family property for the cell
60
+ # @return [Integer]
61
+ # 1 Roman
62
+ # 2 Swiss
63
+ # 3 Modern
64
+ # 4 Script
65
+ # 5 Decorative
66
+ attr_reader :family
67
+ # @see family
68
+ def family=(v)
69
+ set_run_style :validate_family, :family, v.to_i
70
+ end
71
+
72
+ # The inline bold property for the cell
73
+ # @return [Boolean]
74
+ attr_reader :b
75
+ # @see b
76
+ def b=(v) set_run_style :validate_boolean, :b, v; end
77
+
78
+ # The inline italic property for the cell
79
+ # @return [Boolean]
80
+ attr_reader :i
81
+ # @see i
82
+ def i=(v) set_run_style :validate_boolean, :i, v; end
83
+
84
+ # The inline strike property for the cell
85
+ # @return [Boolean]
86
+ attr_reader :strike
87
+ # @see strike
88
+ def strike=(v) set_run_style :validate_boolean, :strike, v; end
89
+
90
+ # The inline outline property for the cell
91
+ # @return [Boolean]
92
+ attr_reader :outline
93
+ # @see outline
94
+ def outline=(v) set_run_style :validate_boolean, :outline, v; end
95
+
96
+ # The inline shadow property for the cell
97
+ # @return [Boolean]
98
+ attr_reader :shadow
99
+ # @see shadow
100
+ def shadow=(v) set_run_style :validate_boolean, :shadow, v; end
101
+
102
+ # The inline condense property for the cell
103
+ # @return [Boolean]
104
+ attr_reader :condense
105
+ # @see condense
106
+ def condense=(v) set_run_style :validate_boolean, :condense, v; end
107
+
108
+ # The inline extend property for the cell
109
+ # @return [Boolean]
110
+ attr_reader :extend
111
+ # @see extend
112
+ def extend=(v) set_run_style :validate_boolean, :extend, v; end
113
+
114
+ # The inline underline property for the cell.
115
+ # It must be one of :none, :single, :double, :singleAccounting, :doubleAccounting, true
116
+ # @return [Boolean]
117
+ # @return [String]
118
+ # @note true is for backwards compatability and is reassigned to :single
119
+ attr_reader :u
120
+ # @see u
121
+ def u=(v)
122
+ v = :single if (v == true || v == 1 || v == :true || v == 'true')
123
+ set_run_style :validate_cell_u, :u, v
124
+ end
125
+
126
+ # The inline color property for the cell
127
+ # @return [Color]
128
+ attr_reader :color
129
+ # @param [String] v The 8 character representation for an rgb color #FFFFFFFF"
130
+ def color=(v)
131
+ @color = v.is_a?(Color) ? v : Color.new(:rgb=>v)
132
+ end
133
+
134
+ # The inline sz property for the cell
135
+ # @return [Inteter]
136
+ attr_reader :sz
137
+ # @see sz
138
+ def sz=(v) set_run_style :validate_unsigned_int, :sz, v; end
139
+
140
+ # The inline vertical alignment property for the cell
141
+ # this must be one of [:baseline, :subscript, :superscript]
142
+ # @return [Symbol]
143
+ attr_reader :vertAlign
144
+ # @see vertAlign
145
+ def vertAlign=(v)
146
+ RestrictionValidator.validate :cell_vertAlign, [:baseline, :subscript, :superscript], v
147
+ set_run_style nil, :vertAlign, v
148
+ end
149
+
150
+ # The inline scheme property for the cell
151
+ # this must be one of [:none, major, minor]
152
+ # @return [Symbol]
153
+ attr_reader :scheme
154
+ # @see scheme
155
+ def scheme=(v)
156
+ RestrictionValidator.validate :cell_scheme, [:none, :major, :minor], v
157
+ set_run_style nil, :scheme, v
158
+ end
159
+
160
+ # Tries to work out the width of the longest line in the run
161
+ # @param [Array] widtharray this array is populated with the widths of each line in the run.
162
+ # @return [Array]
163
+ def autowidth(widtharray)
164
+ return if value.nil?
165
+ if styles.cellXfs[style].alignment && styles.cellXfs[style].alignment.wrap_text
166
+ first = true
167
+ value.to_s.split(/\r?\n/, -1).each do |line|
168
+ if first
169
+ first = false
170
+ else
171
+ widtharray << 0
172
+ end
173
+ widtharray[-1] += string_width(line, font_size)
174
+ end
175
+ else
176
+ widtharray[-1] += string_width(value.to_s, font_size)
177
+ end
178
+ widtharray
179
+ end
180
+
181
+ # Utility method for setting inline style attributes
182
+ def set_run_style(validator, attr, value)
183
+ return unless INLINE_STYLES.include?(attr.to_sym)
184
+ Axlsx.send(validator, value) unless validator.nil?
185
+ self.instance_variable_set :"@#{attr.to_s}", value
186
+ end
187
+
188
+ # Serializes the RichTextRun
189
+ # @param [String] str
190
+ # @return [String]
191
+ def to_xml_string(str = '')
192
+ valid = RichTextRun::INLINE_STYLES
193
+ data = Hash[self.instance_values.map{ |k, v| [k.to_sym, v] }]
194
+ data = data.select { |key, value| valid.include?(key) && !value.nil? }
195
+
196
+ str << '<r><rPr>'
197
+ data.keys.each do |key|
198
+ case key
199
+ when :font_name
200
+ str << ('<rFont val="' << font_name << '"/>')
201
+ when :color
202
+ str << data[key].to_xml_string
203
+ else
204
+ str << ('<' << key.to_s << ' val="' << xml_value(data[key]) << '"/>')
205
+ end
206
+ end
207
+ clean_value = Axlsx::trust_input ? @value.to_s : ::CGI.escapeHTML(Axlsx::sanitize(@value.to_s))
208
+ str << ('</rPr><t>' << clean_value << '</t></r>')
209
+ end
210
+
211
+ private
212
+
213
+ # Returns the width of a string according to the current style
214
+ # This is still not perfect...
215
+ # - scaling is not linear as font sizes increase
216
+ def string_width(string, font_size)
217
+ font_scale = font_size / 10.0
218
+ string.count(Worksheet::THIN_CHARS) * font_scale
219
+ end
220
+
221
+ # we scale the font size if bold style is applied to either the style font or
222
+ # the cell itself. Yes, it is a bit of a hack, but it is much better than using
223
+ # imagemagick and loading metrics for every character.
224
+ def font_size
225
+ return sz if sz
226
+ font = styles.fonts[styles.cellXfs[style].fontId] || styles.fonts[0]
227
+ (font.b || (defined?(@b) && @b)) ? (font.sz * 1.5) : font.sz
228
+ end
229
+
230
+ def style
231
+ cell.style
232
+ end
233
+
234
+ def styles
235
+ cell.row.worksheet.styles
236
+ end
237
+
238
+ # Converts the value to the correct XML representation (fixes issues with
239
+ # Numbers)
240
+ def xml_value value
241
+ if value == true
242
+ 1
243
+ elsif value == false
244
+ 0
245
+ else
246
+ value
247
+ end.to_s
248
+ end
249
+ end
250
+ end
@@ -3,10 +3,10 @@ module Axlsx
3
3
  # A Row is a single row in a worksheet.
4
4
  # @note The recommended way to manage rows and cells is to use Worksheet#add_row
5
5
  # @see Worksheet#add_row
6
- class Row
7
-
6
+ class Row < SimpleTypedList
8
7
  include SerializedAttributes
9
8
  include Accessors
9
+
10
10
  # No support is provided for the following attributes
11
11
  # spans
12
12
  # thickTop
@@ -28,11 +28,10 @@ module Axlsx
28
28
  # @see Row#array_to_cells
29
29
  # @see Cell
30
30
  def initialize(worksheet, values=[], options={})
31
- @ht = nil
32
31
  self.worksheet = worksheet
33
- @cells = SimpleTypedList.new Cell
34
- @worksheet.rows << self
35
- self.height = options.delete(:height) if options[:height]
32
+ super(Cell, nil, values.size)
33
+ self.height = options.delete(:height)
34
+ worksheet.rows << self
36
35
  array_to_cells(values, options)
37
36
  end
38
37
 
@@ -46,14 +45,10 @@ module Axlsx
46
45
  # @return [Worksheet]
47
46
  attr_reader :worksheet
48
47
 
49
- # The cells this row holds
50
- # @return [SimpleTypedList]
51
- attr_reader :cells
52
-
53
48
  # Row height measured in point size. There is no margin padding on row height.
54
49
  # @return [Float]
55
50
  def height
56
- @ht
51
+ defined?(@ht) ? @ht : nil
57
52
  end
58
53
 
59
54
  # Outlining level of the row, when outlining is on
@@ -77,11 +72,12 @@ module Axlsx
77
72
  Axlsx.validate_unsigned_numeric(v)
78
73
  @outline_level = v
79
74
  end
75
+
80
76
  alias :outlineLevel= :outline_level=
81
77
 
82
78
  # The index of this row in the worksheet
83
79
  # @return [Integer]
84
- def index
80
+ def row_index
85
81
  worksheet.rows.index(self)
86
82
  end
87
83
 
@@ -90,50 +86,55 @@ module Axlsx
90
86
  # @param [String] str The string this rows xml will be appended to.
91
87
  # @return [String]
92
88
  def to_xml_string(r_index, str = '')
93
- str << '<row '
94
- serialized_attributes(str, { :r => r_index + 1 })
95
- str << '>'
96
- @cells.each_with_index { |cell, c_index| cell.to_xml_string(r_index, c_index, str) }
97
- str << '</row>'
89
+ serialized_tag('row', str, :r => r_index + 1) do
90
+ tmp = '' # time / memory tradeoff, lots of calls to rubyzip costs more
91
+ # time..
92
+ each_with_index { |cell, c_index| cell.to_xml_string(r_index, c_index, tmp) }
93
+ str << tmp
94
+ end
98
95
  end
99
96
 
100
- # Adds a single sell to the row based on the data provided and updates the worksheet's autofit data.
97
+ # Adds a single cell to the row based on the data provided and updates the worksheet's autofit data.
101
98
  # @return [Cell]
102
- def add_cell(value="", options={})
99
+ def add_cell(value = '', options = {})
103
100
  c = Cell.new(self, value, options)
104
- worksheet.send(:update_column_info, self.cells, [])
101
+ self << c
102
+ worksheet.send(:update_column_info, self, [])
105
103
  c
106
104
  end
107
105
 
108
- # sets the style for every cell in this row
109
- def style=(style)
110
- cells.each_with_index do | cell, index |
111
- s = style.is_a?(Array) ? style[index] : style
112
- cell.style = s
106
+ # sets the color for every cell in this row
107
+ def color=(color)
108
+ each_with_index do | cell, index |
109
+ cell.color = color.is_a?(Array) ? color[index] : color
113
110
  end
114
111
  end
115
112
 
116
- # returns the cells in this row as an array
117
- # This lets us transpose the rows into columns
118
- # @return [Array]
119
- def to_ary
120
- @cells.to_ary
113
+ # sets the style for every cell in this row
114
+ def style=(style)
115
+ each_with_index do | cell, index |
116
+ cell.style = style.is_a?(Array) ? style[index] : style
117
+ end
121
118
  end
122
119
 
123
120
  # @see height
124
121
  def height=(v)
125
- Axlsx::validate_unsigned_numeric(v)
126
122
  unless v.nil?
127
- @ht = v
123
+ Axlsx::validate_unsigned_numeric(v)
128
124
  @custom_height = true
125
+ @ht = v
129
126
  end
130
- @ht
127
+ end
128
+
129
+ # return cells
130
+ def cells
131
+ self
131
132
  end
132
133
 
133
134
  private
134
135
 
135
136
  # assigns the owning worksheet for this row
136
- def worksheet=(v) DataTypeValidator.validate "Row.worksheet", Worksheet, v; @worksheet=v; end
137
+ def worksheet=(v) DataTypeValidator.validate :row_worksheet, Worksheet, v; @worksheet=v; end
137
138
 
138
139
  # Converts values, types, and style options into cells and associates them with this row.
139
140
  # A new cell is created for each item in the values array.
@@ -145,26 +146,14 @@ module Axlsx
145
146
  # @option options [Array, Symbol] types
146
147
  # @option options [Array, Integer] style
147
148
  def array_to_cells(values, options={})
148
- values = values
149
- DataTypeValidator.validate 'Row.array_to_cells', Array, values
149
+ DataTypeValidator.validate :array_to_cells, Array, values
150
150
  types, style, formula_values = options.delete(:types), options.delete(:style), options.delete(:formula_values)
151
151
  values.each_with_index do |value, index|
152
+ options[:style] = style.is_a?(Array) ? style[index] : style if style
153
+ options[:type] = types.is_a?(Array) ? types[index] : types if types
154
+ options[:formula_value] = formula_values[index] if formula_values.is_a?(Array)
152
155
 
153
- #WTF IS THIS PAP?
154
- cell_style = style.is_a?(Array) ? style[index] : style
155
- options[:style] = cell_style if cell_style
156
-
157
- cell_type = types.is_a?(Array)? types[index] : types
158
- options[:type] = cell_type if cell_type
159
-
160
- formula_value = formula_values[index] if formula_values.is_a?(Array)
161
- options[:formula_value] = formula_value if formula_value
162
-
163
- Cell.new(self, value, options)
164
-
165
- options.delete(:style)
166
- options.delete(:type)
167
- options.delete(:formula_value)
156
+ self[index] = Cell.new(self, value, options)
168
157
  end
169
158
  end
170
159
  end
@@ -14,7 +14,7 @@ module Axlsx
14
14
  # @see Break
15
15
  def add_break(options)
16
16
  # force feed the excel default
17
- @list << Break.new(options.merge(:max => 16383, :man => true))
17
+ self << Break.new(options.merge(:max => 16383, :man => true))
18
18
  last
19
19
  end
20
20
 
@@ -25,7 +25,7 @@ module Axlsx
25
25
  # </rowBreaks>
26
26
  def to_xml_string(str='')
27
27
  return if empty?
28
- str << '<rowBreaks count="' << @list.size.to_s << '" manualBreakCount="' << @list.size.to_s << '">'
28
+ str << ('<rowBreaks count="' << self.size.to_s << '" manualBreakCount="' << self.size.to_s << '">')
29
29
  each { |brk| brk.to_xml_string(str) }
30
30
  str << '</rowBreaks>'
31
31
  end
@@ -95,9 +95,7 @@ module Axlsx
95
95
  # @param [String] str
96
96
  # @return [String]
97
97
  def to_xml_string(str = '')
98
- str << '<selection '
99
- serialized_attributes str
100
- str << '/>'
98
+ serialized_tag 'selection', str
101
99
  end
102
100
  end
103
101
  end
@@ -17,7 +17,9 @@ module Axlsx
17
17
  # @return [String]
18
18
  def to_xml_string(str = '')
19
19
  str << '<sheetData>'
20
- worksheet.rows.each_with_index{ |row, index| row.to_xml_string(index, str) }
20
+ worksheet.rows.each_with_index do |row, index|
21
+ row.to_xml_string(index, str)
22
+ end
21
23
  str << '</sheetData>'
22
24
  end
23
25
 
@@ -1,6 +1,6 @@
1
1
  module Axlsx
2
2
 
3
- # The SheetPr class manages serialization fo a worksheet's sheetPr element.
3
+ # The SheetPr class manages serialization of a worksheet's sheetPr element.
4
4
  class SheetPr
5
5
  include Axlsx::OptionsParser
6
6
  include Axlsx::Accessors
@@ -8,7 +8,7 @@ module Axlsx
8
8
 
9
9
  serializable_attributes :sync_horizontal,
10
10
  :sync_vertical,
11
- :transtion_evaluation,
11
+ :transition_evaluation,
12
12
  :transition_entry,
13
13
  :published,
14
14
  :filter_mode,
@@ -20,7 +20,7 @@ module Axlsx
20
20
  # waving magic show to set up the attriubte accessors
21
21
  boolean_attr_accessor :sync_horizontal,
22
22
  :sync_vertical,
23
- :transtion_evaluation,
23
+ :transition_evaluation,
24
24
  :transition_entry,
25
25
  :published,
26
26
  :filter_mode,
@@ -33,6 +33,7 @@ module Axlsx
33
33
  def initialize(worksheet, options={})
34
34
  raise ArgumentError, "you must provide a worksheet" unless worksheet.is_a?(Worksheet)
35
35
  @worksheet = worksheet
36
+ @outline_pr = nil
36
37
  parse_options options
37
38
  end
38
39
 
@@ -40,12 +41,18 @@ module Axlsx
40
41
  # @return [Worksheet]
41
42
  attr_reader :worksheet
42
43
 
44
+ # The tab color of the sheet.
45
+ # @return [Color]
46
+ attr_reader :tab_color
47
+
43
48
  # Serialize the object
44
49
  # @param [String] str serialized output will be appended to this object if provided.
45
50
  # @return [String]
46
51
  def to_xml_string(str = '')
47
52
  update_properties
48
53
  str << "<sheetPr #{serialized_attributes}>"
54
+ tab_color.to_xml_string(str, 'tabColor') if tab_color
55
+ outline_pr.to_xml_string(str) if @outline_pr
49
56
  page_setup_pr.to_xml_string(str)
50
57
  str << "</sheetPr>"
51
58
  end
@@ -55,6 +62,17 @@ module Axlsx
55
62
  def page_setup_pr
56
63
  @page_setup_pr ||= PageSetUpPr.new
57
64
  end
65
+
66
+ # The OutlinePr for this sheet pr object
67
+ # @return [OutlinePr]
68
+ def outline_pr
69
+ @outline_pr ||= OutlinePr.new
70
+ end
71
+
72
+ # @see tab_color
73
+ def tab_color=(v)
74
+ @tab_color ||= Color.new(:rgb => v)
75
+ end
58
76
 
59
77
  private
60
78
 
@@ -76,9 +76,7 @@ module Axlsx
76
76
  # @param [String] str
77
77
  # @return [String]
78
78
  def to_xml_string(str = '')
79
- str << '<sheetProtection '
80
- serialized_attributes str
81
- str << '/>'
79
+ serialized_tag('sheetProtection', str)
82
80
  end
83
81
 
84
82
  private
@@ -58,7 +58,7 @@ module Axlsx
58
58
  # @param [String, Cell] v
59
59
  # @return [Title]
60
60
  def name=(v)
61
- DataTypeValidator.validate "#{self.class}.name", [String], v
61
+ DataTypeValidator.validate :table_name, [String], v
62
62
  if v.is_a?(String)
63
63
  @name = v
64
64
  end
@@ -75,12 +75,12 @@ module Axlsx
75
75
  # @return [String]
76
76
  def to_xml_string(str = '')
77
77
  str << '<?xml version="1.0" encoding="UTF-8"?>'
78
- str << '<table xmlns="' << XML_NS << '" id="' << (index+1).to_s << '" name="' << @name << '" displayName="' << @name.gsub(/\s/,'_') << '" '
79
- str << 'ref="' << @ref << '" totalsRowShown="0">'
80
- str << '<autoFilter ref="' << @ref << '"/>'
81
- str << '<tableColumns count="' << header_cells.length.to_s << '">'
78
+ str << ('<table xmlns="' << XML_NS << '" id="' << (index+1).to_s << '" name="' << @name << '" displayName="' << @name.gsub(/\s/,'_') << '" ')
79
+ str << ('ref="' << @ref << '" totalsRowShown="0">')
80
+ str << ('<autoFilter ref="' << @ref << '"/>')
81
+ str << ('<tableColumns count="' << header_cells.length.to_s << '">')
82
82
  header_cells.each_with_index do |cell,index|
83
- str << '<tableColumn id ="' << (index+1).to_s << '" name="' << cell.value << '"/>'
83
+ str << ('<tableColumn id ="' << (index+1).to_s << '" name="' << cell.value << '"/>')
84
84
  end
85
85
  str << '</tableColumns>'
86
86
  table_style_info.to_xml_string(str)
@@ -43,9 +43,7 @@ module Axlsx
43
43
  # seralizes this object to an xml string
44
44
  # @param [String] str the string to contact this objects serialization to.
45
45
  def to_xml_string(str = '')
46
- str << '<tableStyleInfo '
47
- serialized_attributes str
48
- str << '/>'
46
+ serialized_tag('tableStyleInfo', str)
49
47
  end
50
48
  end
51
49
  end
@@ -20,10 +20,13 @@ module Axlsx
20
20
  map{ |table| Relationship.new(table, TABLE_R, "../#{table.pn}") }
21
21
  end
22
22
 
23
+ # renders the tables xml
24
+ # @param [String] str
25
+ # @return [String]
23
26
  def to_xml_string(str = "")
24
27
  return if empty?
25
28
  str << "<tableParts count='#{size}'>"
26
- @list.each { |table| str << "<tablePart r:id='#{table.rId}'/>" }
29
+ each { |table| str << "<tablePart r:id='#{table.rId}'/>" }
27
30
  str << '</tableParts>'
28
31
  end
29
32
  end