axlsx 1.2.0 → 1.3.3

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 (161) hide show
  1. data/.yardopts +3 -2
  2. data/CHANGELOG.md +34 -1
  3. data/README.md +47 -33
  4. data/Rakefile +1 -1
  5. data/examples/auto_filter.rb +16 -0
  6. data/examples/basic_charts.rb +4 -0
  7. data/examples/colored_links.rb +59 -0
  8. data/examples/doc/_index.html +88 -0
  9. data/examples/doc/class_list.html +53 -0
  10. data/examples/doc/css/common.css +1 -0
  11. data/examples/doc/css/full_list.css +57 -0
  12. data/examples/doc/css/style.css +328 -0
  13. data/examples/doc/file_list.html +52 -0
  14. data/examples/doc/frames.html +28 -0
  15. data/examples/doc/index.html +88 -0
  16. data/examples/doc/js/app.js +214 -0
  17. data/examples/doc/js/full_list.js +173 -0
  18. data/examples/doc/js/jquery.js +4 -0
  19. data/examples/doc/method_list.html +52 -0
  20. data/examples/doc/top-level-namespace.html +102 -0
  21. data/examples/example.rb +447 -257
  22. data/examples/finance.rb +82 -0
  23. data/examples/hyperlinks.rb +23 -0
  24. data/examples/page_setup.rb +11 -0
  25. data/examples/skydrive/axlsx.csv +1 -0
  26. data/examples/skydrive/axlsx.xlsx +0 -0
  27. data/examples/skydrive/real_example.rb +8 -8
  28. data/examples/sprk2012/Screen Shot 2012-09-11 at 10.42.06 PM.png +0 -0
  29. data/examples/sprk2012/Screen Shot 2012-09-11 at 11.07.48 PM.png +0 -0
  30. data/examples/sprk2012/Screen Shot 2012-09-11 at 8.31.50 PM.png +0 -0
  31. data/examples/sprk2012/Screen Shot 2012-09-11 at 9.23.27 PM.png +0 -0
  32. data/examples/sprk2012/Screen Shot 2012-09-11 at 9.32.06 PM.png +0 -0
  33. data/examples/sprk2012/Screen Shot 2012-09-11 at 9.33.35 PM.png +0 -0
  34. data/examples/sprk2012/Screen Shot 2012-09-11 at 9.46.44 PM.png +0 -0
  35. data/examples/sprk2012/Screen Shot 2012-09-12 at 5.07.23 PM.png +0 -0
  36. data/examples/sprk2012/basics.rb +11 -0
  37. data/examples/sprk2012/basics.xlsx +0 -0
  38. data/examples/sprk2012/gravatar.jpeg +0 -0
  39. data/examples/sprk2012/hair_club.jpg +0 -0
  40. data/examples/sprk2012/images.rb +9 -0
  41. data/examples/{example.xlsx → sprk2012/images.xlsx} +0 -0
  42. data/examples/sprk2012/line_chart.rb +56 -0
  43. data/examples/sprk2012/line_chart.xlsx +0 -0
  44. data/examples/sprk2012/sprk2012.key +0 -0
  45. data/examples/sprk2012/styles.rb +20 -0
  46. data/examples/sprk2012/styles.xlsx +0 -0
  47. data/examples/styles.rb +62 -0
  48. data/lib/axlsx/content_type/abstract_content_type.rb +32 -0
  49. data/lib/axlsx/content_type/content_type.rb +1 -1
  50. data/lib/axlsx/content_type/default.rb +6 -37
  51. data/lib/axlsx/content_type/override.rb +6 -38
  52. data/lib/axlsx/doc_props/app.rb +10 -7
  53. data/lib/axlsx/drawing/axis.rb +4 -4
  54. data/lib/axlsx/drawing/chart.rb +2 -3
  55. data/lib/axlsx/drawing/d_lbls.rb +21 -31
  56. data/lib/axlsx/drawing/drawing.rb +6 -0
  57. data/lib/axlsx/drawing/hyperlink.rb +40 -32
  58. data/lib/axlsx/drawing/marker.rb +13 -13
  59. data/lib/axlsx/drawing/num_data.rb +6 -6
  60. data/lib/axlsx/drawing/num_data_source.rb +17 -16
  61. data/lib/axlsx/drawing/one_cell_anchor.rb +20 -22
  62. data/lib/axlsx/drawing/pic.rb +25 -27
  63. data/lib/axlsx/drawing/picture_locking.rb +12 -44
  64. data/lib/axlsx/drawing/scaling.rb +13 -13
  65. data/lib/axlsx/drawing/scatter_chart.rb +3 -3
  66. data/lib/axlsx/drawing/series.rb +3 -6
  67. data/lib/axlsx/drawing/str_data.rb +3 -3
  68. data/lib/axlsx/drawing/str_val.rb +7 -8
  69. data/lib/axlsx/drawing/view_3D.rb +52 -38
  70. data/lib/axlsx/drawing/vml_shape.rb +23 -23
  71. data/lib/axlsx/package.rb +14 -17
  72. data/lib/axlsx/stylesheet/border.rb +29 -20
  73. data/lib/axlsx/stylesheet/border_pr.rb +5 -4
  74. data/lib/axlsx/stylesheet/cell_alignment.rb +55 -29
  75. data/lib/axlsx/stylesheet/cell_protection.rb +7 -4
  76. data/lib/axlsx/stylesheet/cell_style.rb +19 -14
  77. data/lib/axlsx/stylesheet/color.rb +19 -16
  78. data/lib/axlsx/stylesheet/dxf.rb +4 -4
  79. data/lib/axlsx/stylesheet/font.rb +22 -22
  80. data/lib/axlsx/stylesheet/gradient_fill.rb +45 -21
  81. data/lib/axlsx/stylesheet/num_fmt.rb +22 -13
  82. data/lib/axlsx/stylesheet/pattern_fill.rb +12 -21
  83. data/lib/axlsx/stylesheet/styles.rb +11 -2
  84. data/lib/axlsx/stylesheet/table_style.rb +17 -16
  85. data/lib/axlsx/stylesheet/table_style_element.rb +15 -11
  86. data/lib/axlsx/stylesheet/table_styles.rb +14 -11
  87. data/lib/axlsx/stylesheet/xf.rb +28 -26
  88. data/lib/axlsx/util/accessors.rb +49 -0
  89. data/lib/axlsx/util/constants.rb +105 -4
  90. data/lib/axlsx/util/options_parser.rb +15 -0
  91. data/lib/axlsx/util/serialized_attributes.rb +46 -0
  92. data/lib/axlsx/util/simple_typed_list.rb +16 -2
  93. data/lib/axlsx/util/validators.rb +33 -8
  94. data/lib/axlsx/version.rb +2 -2
  95. data/lib/axlsx/workbook/defined_name.rb +13 -58
  96. data/lib/axlsx/workbook/workbook.rb +33 -2
  97. data/lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb +77 -0
  98. data/lib/axlsx/workbook/worksheet/auto_filter/filter_column.rb +94 -0
  99. data/lib/axlsx/workbook/worksheet/auto_filter/filters.rb +246 -0
  100. data/lib/axlsx/workbook/worksheet/cell.rb +82 -45
  101. data/lib/axlsx/workbook/worksheet/cfvo.rb +15 -15
  102. data/lib/axlsx/workbook/worksheet/cfvos.rb +18 -0
  103. data/lib/axlsx/workbook/worksheet/col.rb +34 -27
  104. data/lib/axlsx/workbook/worksheet/color_scale.rb +7 -13
  105. data/lib/axlsx/workbook/worksheet/comment.rb +14 -11
  106. data/lib/axlsx/workbook/worksheet/conditional_formatting.rb +11 -11
  107. data/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb +27 -25
  108. data/lib/axlsx/workbook/worksheet/data_bar.rb +44 -34
  109. data/lib/axlsx/workbook/worksheet/data_validation.rb +61 -62
  110. data/lib/axlsx/workbook/worksheet/date_time_converter.rb +1 -1
  111. data/lib/axlsx/workbook/worksheet/dimension.rb +0 -1
  112. data/lib/axlsx/workbook/worksheet/icon_set.rb +20 -20
  113. data/lib/axlsx/workbook/worksheet/page_margins.rb +21 -19
  114. data/lib/axlsx/workbook/worksheet/page_set_up_pr.rb +44 -0
  115. data/lib/axlsx/workbook/worksheet/page_setup.rb +152 -23
  116. data/lib/axlsx/workbook/worksheet/pane.rb +48 -51
  117. data/lib/axlsx/workbook/worksheet/print_options.rb +8 -30
  118. data/lib/axlsx/workbook/worksheet/protected_range.rb +16 -13
  119. data/lib/axlsx/workbook/worksheet/row.rb +48 -81
  120. data/lib/axlsx/workbook/worksheet/selection.rb +30 -38
  121. data/lib/axlsx/workbook/worksheet/sheet_calc_pr.rb +29 -0
  122. data/lib/axlsx/workbook/worksheet/sheet_pr.rb +49 -4
  123. data/lib/axlsx/workbook/worksheet/sheet_protection.rb +51 -155
  124. data/lib/axlsx/workbook/worksheet/sheet_view.rb +68 -234
  125. data/lib/axlsx/workbook/worksheet/table.rb +22 -17
  126. data/lib/axlsx/workbook/worksheet/table_style_info.rb +51 -0
  127. data/lib/axlsx/workbook/worksheet/worksheet.rb +51 -14
  128. data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +1 -1
  129. data/lib/axlsx/workbook/worksheet/worksheet_hyperlink.rb +79 -0
  130. data/lib/axlsx/workbook/worksheet/worksheet_hyperlinks.rb +38 -0
  131. data/lib/axlsx.rb +19 -5
  132. data/test/content_type/tc_default.rb +0 -11
  133. data/test/content_type/tc_override.rb +0 -13
  134. data/test/drawing/tc_d_lbls.rb +14 -4
  135. data/test/stylesheet/tc_styles.rb +13 -0
  136. data/test/tc_axlsx.rb +20 -2
  137. data/test/tc_package.rb +1 -0
  138. data/test/util/tc_validators.rb +22 -1
  139. data/test/workbook/tc_defined_name.rb +2 -2
  140. data/test/workbook/tc_workbook.rb +15 -0
  141. data/test/workbook/worksheet/auto_filter/tc_auto_filter.rb +38 -0
  142. data/test/workbook/worksheet/auto_filter/tc_filter_column.rb +76 -0
  143. data/test/workbook/worksheet/auto_filter/tc_filters.rb +50 -0
  144. data/test/workbook/worksheet/tc_cell.rb +35 -5
  145. data/test/workbook/worksheet/tc_col.rb +11 -1
  146. data/test/workbook/worksheet/tc_page_set_up_pr.rb +15 -0
  147. data/test/workbook/worksheet/tc_page_setup.rb +6 -1
  148. data/test/workbook/worksheet/tc_pane.rb +5 -45
  149. data/test/workbook/worksheet/tc_row.rb +4 -4
  150. data/test/workbook/worksheet/tc_selection.rb +9 -48
  151. data/test/workbook/worksheet/tc_sheet_calc_pr.rb +18 -0
  152. data/test/workbook/worksheet/tc_sheet_pr.rb +27 -0
  153. data/test/workbook/worksheet/{table/tc_table.rb → tc_table.rb} +6 -1
  154. data/test/workbook/worksheet/tc_table_style_info.rb +53 -0
  155. data/test/workbook/worksheet/tc_worksheet.rb +17 -3
  156. data/test/workbook/worksheet/tc_worksheet_hyperlink.rb +64 -0
  157. metadata +74 -10
  158. data/examples/example_streamed.xlsx +0 -0
  159. data/examples/no-use_autowidth.xlsx +0 -0
  160. data/examples/shared_strings_example.xlsx +0 -0
  161. data/lib/axlsx/workbook/worksheet/auto_filter.rb +0 -34
@@ -0,0 +1,94 @@
1
+ module Axlsx
2
+ # The filterColumn collection identifies a particular column in the AutoFilter
3
+ # range and specifies filter information that has been applied to this column.
4
+ # If a column in the AutoFilter range has no criteria specified,
5
+ # then there is no corresponding filterColumn collection expressed for that column.
6
+ class FilterColumn
7
+
8
+ include Axlsx::OptionsParser
9
+ include Axlsx::SerializedAttributes
10
+
11
+ # Creates a new FilterColumn object
12
+ # @note This class yeilds its filter object as that is where the vast majority of processing will be done
13
+ # @param [Integer|Cell] col_id The zero based index for the column to which this filter will be applied
14
+ # @param [Symbol] filter_type The symbolized class name of the filter to apply to this column.
15
+ # @param [Hash] options options for this object and the filter
16
+ # @option [Boolean] hidden_button @see hidden_button
17
+ # @option [Boolean] show_button @see show_button
18
+ def initialize(col_id, filter_type, options = {})
19
+ RestrictionValidator.validate 'FilterColumn.filter', FILTERS, filter_type
20
+ #Axlsx::validate_unsigned_int(col_id)
21
+ self.col_id = col_id
22
+ parse_options options
23
+ @filter = Axlsx.const_get(Axlsx.camel(filter_type)).new(options)
24
+ yield @filter if block_given?
25
+ end
26
+
27
+ serializable_attributes :col_id, :hidden_button, :show_button
28
+
29
+ # Allowed filters
30
+ FILTERS = [:filters] #, :top10, :custom_filters, :dynamic_filters, :color_filters, :icon_filters]
31
+
32
+ # Zero-based index indicating the AutoFilter column to which this filter information applies.
33
+ # @return [Integer]
34
+ attr_reader :col_id
35
+
36
+ # The actual filter being dealt with here
37
+ # This could be any one of the allowed filter types
38
+ attr_reader :filter
39
+
40
+ # Flag indicating whether the filter button is visible.
41
+ # When the cell containing the filter button is merged with another cell,
42
+ # the filter button can be hidden, and not drawn.
43
+ # @return [Boolean]
44
+ def show_button
45
+ @show_button ||= true
46
+ end
47
+
48
+ # Flag indicating whether the AutoFilter button for this column is hidden.
49
+ # @return [Boolean]
50
+ def hidden_button
51
+ @hidden_button ||= false
52
+ end
53
+
54
+ # Sets the col_id attribute for this filter column.
55
+ # @param [Integer | Cell] column_index The zero based index of the column to which this filter applies.
56
+ # When you specify a cell, the column index will be read off the cell
57
+ # @return [Integer]
58
+ def col_id=(column_index)
59
+ column_index = column_index.col if column_index.is_a?(Cell)
60
+ Axlsx.validate_unsigned_int column_index
61
+ @col_id = column_index
62
+ end
63
+
64
+ # Apply the filters for this column
65
+ # @param [Array] row A row from a worksheet that needs to be
66
+ # filtered.
67
+ def apply(row, offset)
68
+ row.hidden = @filter.apply(row.cells[offset+col_id.to_i])
69
+ end
70
+ # @param [Boolean] hidden Flag indicating whether the AutoFilter button for this column is hidden.
71
+ # @return [Boolean]
72
+ def hidden_button=(hidden)
73
+ Axlsx.validate_boolean hidden
74
+ @hidden_button = hidden
75
+ end
76
+
77
+ # Flag indicating whether the AutoFilter button is show. This is
78
+ # undocumented in the spec, but exists in the schema file as an
79
+ # optional attribute.
80
+ # @param [Boolean] show Show or hide the button
81
+ # @return [Boolean]
82
+ def show_button=(show)
83
+ Axlsx.validate_boolean show
84
+ @show_botton = show
85
+ end
86
+
87
+ # Serialize the object to xml
88
+ def to_xml_string(str='')
89
+ str << "<filterColumn #{serialized_attributes}>"
90
+ @filter.to_xml_string(str)
91
+ str << "</filterColumn>"
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,246 @@
1
+ module Axlsx
2
+
3
+ # When multiple values are chosen to filter by, or when a group of date values are chosen to filter by,
4
+ # this object groups those criteria together.
5
+ class Filters
6
+ include Axlsx::OptionsParser
7
+ include Axlsx::SerializedAttributes
8
+
9
+ # Creates a new Filters object
10
+ # @param [Hash] options Options used to set this objects attributes and
11
+ # create filter and/or date group items
12
+ # @option [Boolean] blank @see blank
13
+ # @option [String] calendar_type @see calendar_type
14
+ # @option [Array] filter_items An array of values that will be used to create filter objects.
15
+ # @option [Array] date_group_items An array of hases defining date group item filters to apply.
16
+ # @note The recommended way to interact with filter objects is via AutoFilter#add_column
17
+ # @example
18
+ # ws.auto_filter.add_column(0, :filters, :blank => true, :calendar_type => 'japan', :filter_items => [100, 'a'])
19
+ def initialize(options={})
20
+ parse_options options
21
+ end
22
+
23
+ serializable_attributes :blank, :calendar_type
24
+
25
+ # Allowed calendar types
26
+ CALENDAR_TYPES = %w(gregorian gregorianUs gregorianMeFrench gregorianArabic hijri hebrew taiwan japan thai korea saka gregorianXlitEnglish gregorianXlitFrench none)
27
+
28
+ # Flag indicating whether to filter by blank.
29
+ # @return [Boolean]
30
+ attr_reader :blank
31
+
32
+ # Calendar type for date grouped items.
33
+ # Used to interpret the values in dateGroupItem.
34
+ # This is the calendar type used to evaluate all dates in the filter column,
35
+ # even when those dates are not using the same calendar system / date formatting.
36
+ attr_reader :calendar_type
37
+
38
+ # Tells us if the row of the cell provided should be filterd as it
39
+ # does not meet any of the specified filter_items or
40
+ # date_group_items restrictions.
41
+ # @param [Cell] cell The cell to test against items
42
+ # TODO implement this for date filters as well!
43
+ def apply(cell)
44
+ return false unless cell
45
+ filter_items.each do |filter|
46
+ return false if cell.value == filter.val
47
+ end
48
+ true
49
+ end
50
+
51
+ # The filter values in this filters object
52
+ def filter_items
53
+ @filter_items ||= []
54
+ end
55
+
56
+ # the date group values in this filters object
57
+ def date_group_items
58
+ @date_group_items ||= []
59
+ end
60
+
61
+ # @see calendar_type
62
+ # @param [String] calendar The calendar type to use. This must be one of the types defined in CALENDAR_TYPES
63
+ # @return [String]
64
+ def calendar_type=(calendar)
65
+ RestrictionValidator.validate 'Filters.calendar_type', CALENDAR_TYPES, calendar
66
+ @calendar_type = calendar
67
+ end
68
+
69
+ # Set the value for blank
70
+ # @see blank
71
+ def blank=(use_blank)
72
+ Axlsx.validate_boolean use_blank
73
+ @blank = use_blank
74
+ end
75
+
76
+ # Serialize the object to xml
77
+ def to_xml_string(str = '')
78
+ str << "<filters #{serialized_attributes}>"
79
+ filter_items.each { |filter| filter.to_xml_string(str) }
80
+ date_group_items.each { |date_group_item| date_group_item.to_xml_string(str) }
81
+ str << '</filters>'
82
+ end
83
+
84
+ # not entirely happy with this.
85
+ # filter_items should be a simple typed list that overrides << etc
86
+ # to create Filter objects from the inserted values. However this
87
+ # is most likely so rarely used...(really? do you know that?)
88
+ def filter_items=(values)
89
+ values.each do |value|
90
+ filter_items << Filter.new(value)
91
+ end
92
+ end
93
+
94
+ # Date group items are date group filter items where you specify the
95
+ # date_group and a value for that option as part of the auto_filter
96
+ # @note This can be specified, but will not be applied to the date
97
+ # values in your workbook at this time.
98
+ def date_group_items=(options)
99
+ options.each do |date_group|
100
+ raise ArgumentError, "date_group_items should be an array of hashes specifying the options for each date_group_item" unless date_group.is_a?(Hash)
101
+ date_group_items << DateGroupItem.new(date_group)
102
+ end
103
+ end
104
+
105
+ # This class expresses a filter criteria value.
106
+ class Filter
107
+
108
+ # Creates a new filter value object
109
+ # @param [Any] value The value of the filter. This is not restricted, but
110
+ # will be serialized via to_s so if you are passing an object
111
+ # be careful.
112
+ def initialize(value)
113
+ @val = value
114
+ end
115
+
116
+
117
+ #Filter value used in the criteria.
118
+ attr_accessor :val
119
+
120
+ # Serializes the filter value object
121
+ # @param [String] str The string to concact the serialization information to.
122
+ def to_xml_string(str = '')
123
+ str << "<filter val='#{@val.to_s}' />"
124
+ end
125
+ end
126
+
127
+
128
+ # This collection is used to express a group of dates or times which are
129
+ # used in an AutoFilter criteria. Values are always written in the calendar
130
+ # type of the first date encountered in the filter range, so that all
131
+ # subsequent dates, even when formatted or represented by other calendar
132
+ # types, can be correctly compared for the purposes of filtering.
133
+ class DateGroupItem
134
+ include Axlsx::OptionsParser
135
+ include Axlsx::SerializedAttributes
136
+
137
+ # Creates a new DateGroupItem
138
+ # @param [Hash] options A hash of options to use when
139
+ # instanciating the object
140
+ # @option [String] date_time_grouping the part of the date this
141
+ # filter should apply for grouping
142
+ # @option [Integer|String] year @see year
143
+ # @option [Integer] month @see month
144
+ # @option [Integer] day @see day
145
+ # @option [Integer] hour @see hour
146
+ # @option [Integer] minute @see minute
147
+ # @option [Integer] second @see second
148
+ def initialize(options={})
149
+ raise ArgumentError, "You must specify a year for date time grouping" unless options[:year]
150
+ raise ArgumentError, "You must specify a date_time_grouping when creating a DateGroupItem for auto filter" unless options[:date_time_grouping]
151
+ parse_options options
152
+ end
153
+
154
+ serializable_attributes :date_time_grouping, :year, :month, :day, :hour, :minute, :second
155
+
156
+ # Allowed date time groupings
157
+ DATE_TIME_GROUPING = %w(year month day hour minute second)
158
+
159
+ # Grouping level
160
+ # This must be one of year, month, day, hour, minute or second.
161
+ # @return [String]
162
+ attr_reader :date_time_grouping
163
+
164
+ # Year (4 digits)
165
+ # @return [Integer|String]
166
+ attr_reader :year
167
+
168
+ # Month (1..12)
169
+ # @return [Integer]
170
+ attr_reader :month
171
+
172
+ # Day (1-31)
173
+ # @return [Integer]
174
+ attr_reader :day
175
+
176
+ # Hour (0..23)
177
+ # @return [Integer]
178
+ attr_reader :hour
179
+
180
+ # Minute (0..59(
181
+ # @return [Integer]
182
+ attr_reader :minute
183
+
184
+ # Second (0..59)
185
+ # @return [Integer]
186
+ attr_reader :second
187
+
188
+ # The year value for the date group item
189
+ # This must be a four digit value
190
+ def year=(value)
191
+ RegexValidator.validate "DateGroupItem.year", /\d{4}/, value
192
+ @year = value
193
+ end
194
+
195
+ # The month value for the date group item
196
+ # This must be between 1 and 12
197
+ def month=(value)
198
+ RangeValidator.validate "DateGroupItem.month", 0, 12, value
199
+ @month = value
200
+ end
201
+
202
+ # The day value for the date group item
203
+ # This must be between 1 and 31
204
+ # @note no attempt is made to ensure the date value is valid for any given month
205
+ def day=(value)
206
+ RangeValidator.validate "DateGroupItem.day", 0, 31, value
207
+ @day = value
208
+ end
209
+
210
+ # The hour value for the date group item
211
+ # # this must be between 0 and 23
212
+ def hour=(value)
213
+ RangeValidator.validate "DateGroupItem.hour", 0, 23, value
214
+ @hour = value
215
+ end
216
+
217
+ # The minute value for the date group item
218
+ # This must be between 0 and 59
219
+ def minute=(value)
220
+ RangeValidator.validate "DateGroupItem.minute", 0, 59, value
221
+ @minute = value
222
+ end
223
+
224
+ # The second value for the date group item
225
+ # This must be between 0 and 59
226
+ def second=(value)
227
+ RangeValidator.validate "DateGroupItem.second", 0, 59, value
228
+ @second = value
229
+ end
230
+
231
+ # The date time grouping for this filter.
232
+ def date_time_grouping=(grouping)
233
+ RestrictionValidator.validate 'DateGroupItem.date_time_grouping', DATE_TIME_GROUPING, grouping.to_s
234
+ @date_time_grouping = grouping.to_s
235
+ end
236
+
237
+ # Serialize the object to xml
238
+ # @param [String] str The string object this serialization will be concatenated to.
239
+ def to_xml_string(str = '')
240
+ str << '<dateGroupItem '
241
+ serialized_attributes str
242
+ str << '/>'
243
+ end
244
+ end
245
+ end
246
+ end
@@ -8,6 +8,38 @@ module Axlsx
8
8
  # @see Worksheet#add_row
9
9
  class Cell
10
10
 
11
+ include Axlsx::OptionsParser
12
+
13
+ # @param [Row] row The row this cell belongs to.
14
+ # @param [Any] value The value associated with this cell.
15
+ # @option options [Symbol] type The intended data type for this cell. If not specified the data type will be determined internally based on the vlue provided.
16
+ # @option options [Integer] style The index of the cellXfs item to be applied to this cell. If not specified, the default style (0) will be applied.
17
+ # @option options [String] font_name
18
+ # @option options [Integer] charset
19
+ # @option options [String] family
20
+ # @option options [Boolean] b
21
+ # @option options [Boolean] i
22
+ # @option options [Boolean] strike
23
+ # @option options [Boolean] outline
24
+ # @option options [Boolean] shadow
25
+ # @option options [Boolean] condense
26
+ # @option options [Boolean] extend
27
+ # @option options [Boolean] u
28
+ # @option options [Symbol] vertAlign must be one of :baseline, :subscript, :superscript
29
+ # @option options [Integer] sz
30
+ # @option options [String] color an 8 letter rgb specification
31
+ # @option options [Symbol] scheme must be one of :none, major, :minor
32
+ def initialize(row, value="", options={})
33
+ self.row=row
34
+ @value = @font_name = @charset = @family = @b = @i = @strike = @outline = @shadow = nil
35
+ @condense = @u = @vertAlign = @sz = @color = @scheme = @extend = @ssti = nil
36
+ @styles = row.worksheet.workbook.styles
37
+ @row.cells << self
38
+ parse_options options
39
+ @style ||= 0
40
+ @type ||= cell_type_from_value(value)
41
+ @value = cast_value(value)
42
+ end
11
43
 
12
44
  # An array of available inline styes.
13
45
  # TODO change this to a hash where each key defines attr name and validator (and any info the validator requires)
@@ -16,9 +48,9 @@ module Axlsx
16
48
  # set_attr method that kicks the suplied validator and updates the instance_variable
17
49
  # for the key
18
50
  INLINE_STYLES = ['value', 'type', 'font_name', 'charset',
19
- 'family', 'b', 'i', 'strike','outline',
20
- 'shadow', 'condense', 'extend', 'u',
21
- 'vertAlign', 'sz', 'color', 'scheme']
51
+ 'family', 'b', 'i', 'strike','outline',
52
+ 'shadow', 'condense', 'extend', 'u',
53
+ 'vertAlign', 'sz', 'color', 'scheme']
22
54
 
23
55
  # The index of the cellXfs item to be applied to this cell.
24
56
  # @return [Integer]
@@ -80,16 +112,43 @@ module Axlsx
80
112
  def font_name=(v) set_run_style :validate_string, :font_name, v; end
81
113
 
82
114
  # The inline charset property for the cell
115
+ # As far as I can tell, this is pretty much ignored. However, based on the spec it should be one of the following:
116
+ # 0  ANSI_CHARSET
117
+ # 1 DEFAULT_CHARSET
118
+ # 2 SYMBOL_CHARSET
119
+ # 77 MAC_CHARSET
120
+ # 128 SHIFTJIS_CHARSET
121
+ # 129  HANGUL_CHARSET
122
+ # 130  JOHAB_CHARSET
123
+ # 134  GB2312_CHARSET
124
+ # 136  CHINESEBIG5_CHARSET
125
+ # 161  GREEK_CHARSET
126
+ # 162  TURKISH_CHARSET
127
+ # 163  VIETNAMESE_CHARSET
128
+ # 177  HEBREW_CHARSET
129
+ # 178  ARABIC_CHARSET
130
+ # 186  BALTIC_CHARSET
131
+ # 204  RUSSIAN_CHARSET
132
+ # 222  THAI_CHARSET
133
+ # 238  EASTEUROPE_CHARSET
134
+ # 255  OEM_CHARSET
83
135
  # @return [String]
84
136
  attr_reader :charset
85
137
  # @see charset
86
138
  def charset=(v) set_run_style :validate_unsigned_int, :charset, v; end
87
139
 
88
140
  # The inline family property for the cell
89
- # @return [String]
141
+ # @return [Integer]
142
+ # 1 Roman
143
+ # 2 Swiss
144
+ # 3 Modern
145
+ # 4 Script
146
+ # 5 Decorative
90
147
  attr_reader :family
91
148
  # @see family
92
- def family=(v) set_run_style :validate_string, :family, v; end
149
+ def family=(v)
150
+ set_run_style :validate_family, :family, v.to_i
151
+ end
93
152
 
94
153
  # The inline bold property for the cell
95
154
  # @return [Boolean]
@@ -133,11 +192,17 @@ module Axlsx
133
192
  # @see extend
134
193
  def extend=(v) set_run_style :validate_boolean, :extend, v; end
135
194
 
136
- # The inline underline property for the cell
195
+ # The inline underline property for the cell.
196
+ # It must be one of :none, :single, :double, :singleAccounting, :doubleAccounting, true
137
197
  # @return [Boolean]
198
+ # @return [String]
199
+ # @note true is for backwards compatability and is reassigned to :single
138
200
  attr_reader :u
139
201
  # @see u
140
- def u=(v) set_run_style :validate_boolean, :u, v; end
202
+ def u=(v)
203
+ v = :single if (v == true || v == 1 || v == :true || v == 'true')
204
+ set_run_style :validate_cell_u, :u, v
205
+ end
141
206
 
142
207
  # The inline color property for the cell
143
208
  # @return [Color]
@@ -174,39 +239,6 @@ module Axlsx
174
239
  set_run_style nil, :scheme, v
175
240
  end
176
241
 
177
- # @param [Row] row The row this cell belongs to.
178
- # @param [Any] value The value associated with this cell.
179
- # @option options [Symbol] type The intended data type for this cell. If not specified the data type will be determined internally based on the vlue provided.
180
- # @option options [Integer] style The index of the cellXfs item to be applied to this cell. If not specified, the default style (0) will be applied.
181
- # @option options [String] font_name
182
- # @option options [Integer] charset
183
- # @option options [String] family
184
- # @option options [Boolean] b
185
- # @option options [Boolean] i
186
- # @option options [Boolean] strike
187
- # @option options [Boolean] outline
188
- # @option options [Boolean] shadow
189
- # @option options [Boolean] condense
190
- # @option options [Boolean] extend
191
- # @option options [Boolean] u
192
- # @option options [Symbol] vertAlign must be one of :baseline, :subscript, :superscript
193
- # @option options [Integer] sz
194
- # @option options [String] color an 8 letter rgb specification
195
- # @option options [Symbol] scheme must be one of :none, major, :minor
196
- def initialize(row, value="", options={})
197
- self.row=row
198
- @value = @font_name = @charset = @family = @b = @i = @strike = @outline = @shadow = nil
199
- @condense = @u = @vertAlign = @sz = @color = @scheme = @extend = @ssti = nil
200
- @styles = row.worksheet.workbook.styles
201
- @row.cells << self
202
- options.each do |o|
203
- self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
204
- end
205
- @style ||= 0
206
- @type ||= cell_type_from_value(value)
207
- @value = cast_value(value)
208
- end
209
-
210
242
  # The Shared Strings Table index for this cell
211
243
  # @return [Integer]
212
244
  attr_reader :ssti
@@ -330,7 +362,7 @@ module Axlsx
330
362
  font_scale = (font_size/10.0).to_f
331
363
  ((value.to_s.count(Worksheet.thin_chars) * mdw + 5) / mdw * 256) / 256.0 * font_scale
332
364
  end
333
-
365
+
334
366
  # returns the absolute or relative string style reference for
335
367
  # this cell.
336
368
  # @param [Boolean] absolute -when false a relative reference will be
@@ -338,12 +370,17 @@ module Axlsx
338
370
  # @return [String]
339
371
  def reference(absolute=true)
340
372
  absolute ? r_abs : r
341
- end
342
-
373
+ end
374
+
343
375
  private
344
376
 
377
+ # we scale the font size if bold style is applied to either the style font or
378
+ # the cell itself. Yes, it is a bit of a hack, but it is much better than using
379
+ # imagemagick and loading metrics for every character.
345
380
  def font_size
346
- sz || @styles.fonts[@styles.cellXfs[style].fontId].sz
381
+ font = @styles.fonts[@styles.cellXfs[style].fontId] || @styles.fonts[0]
382
+ size_from_styles = (font.b || b) ? font.sz * 1.5 : font.sz
383
+ sz || size_from_styles
347
384
  end
348
385
 
349
386
  # Utility method for setting inline style attributes
@@ -380,7 +417,7 @@ module Axlsx
380
417
  :boolean
381
418
  elsif v.to_s.match(/\A[+-]?\d+?\Z/) #numeric
382
419
  :integer
383
- elsif v.to_s.match(/\A[+-]?\d+\.\d+?\Z/) #float
420
+ elsif v.to_s.match(/\A[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?\Z/) #float
384
421
  :float
385
422
  else
386
423
  :string
@@ -8,35 +8,36 @@ module Axlsx
8
8
  #
9
9
  class Cfvo
10
10
 
11
+ include Axlsx::OptionsParser
12
+ include Axlsx::SerializedAttributes
13
+
14
+ # Creates a new Cfvo object
15
+ # @option options [Symbol] type The type of conditional formatting value object
16
+ # @option options [Boolean] gte threshold value usage indicator
17
+ # @option options [String] val The value of the conditional formatting object
18
+ def initialize(options={})
19
+ @gte = true
20
+ parse_options options
21
+ end
22
+
23
+ serializable_attributes :type, :gte, :val
24
+
11
25
  # Type (ST_CfvoType)
12
26
  # The type of this conditional formatting value object. options are num, percent, max, min, formula and percentile
13
27
  # @return [Symbol]
14
28
  attr_reader :type
15
29
 
16
-
17
30
  # Type (xsd:boolean)
18
31
  # For icon sets, determines whether this threshold value uses the greater than or equal to operator. 0 indicates 'greater than' is used instead of 'greater than or equal to'.
19
32
  # The default value is true
20
33
  # @return [Boolean]
21
34
  attr_reader :gte
22
35
 
23
-
24
36
  # Type (ST_Xstring)
25
37
  # The value of the conditional formatting object
26
38
  # This library will accept any value so long as it supports to_s
27
39
  attr_reader :val
28
40
 
29
- # Creates a new Cfvo object
30
- # @option options [Symbol] type The type of conditional formatting value object
31
- # @option options [Boolean] gte threshold value usage indicator
32
- # @option options [String] val The value of the conditional formatting object
33
- def initialize(options={})
34
- @gte = true
35
- options.each do |o|
36
- self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
37
- end
38
- end
39
-
40
41
  # @see type
41
42
  def type=(v); Axlsx::validate_conditional_formatting_value_object_type(v); @type = v end
42
43
 
@@ -54,9 +55,8 @@ module Axlsx
54
55
  # @return [String]
55
56
  def to_xml_string(str = '')
56
57
  str << '<cfvo '
57
- str << instance_values.map { |key, value| '' << key << '="' << value.to_s << '"' }.join(' ')
58
+ serialized_attributes str
58
59
  str << ' />'
59
60
  end
60
-
61
61
  end
62
62
  end
@@ -0,0 +1,18 @@
1
+ module Axlsx
2
+
3
+ #A collection of Cfvo objects that initializes with the required
4
+ #first two items
5
+ class Cfvos < SimpleTypedList
6
+
7
+ def initialize
8
+ super(Cfvo)
9
+ @list << Cfvo.new(:type => :min, :val => 0)
10
+ @list << Cfvo.new(:type => :max, :val => 0)
11
+ lock
12
+ end
13
+
14
+ def to_xml_string(str='')
15
+ @list.each { |cfvo| cfvo.to_xml_string(str) }
16
+ end
17
+ end
18
+ end