axlsx 1.2.0 → 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 (208) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +3 -2
  3. data/.yardopts_guide +19 -0
  4. data/CHANGELOG.md +64 -1
  5. data/README.md +105 -87
  6. data/Rakefile +0 -5
  7. data/examples/2010_comments.rb +17 -0
  8. data/examples/anchor_swapping.rb +28 -0
  9. data/examples/auto_filter.rb +16 -0
  10. data/examples/basic_charts.rb +4 -0
  11. data/examples/colored_links.rb +59 -0
  12. data/examples/conditional_formatting/example_conditional_formatting.rb +4 -2
  13. data/examples/example.rb +569 -258
  14. data/examples/ios_preview.rb +14 -0
  15. data/examples/page_setup.rb +11 -0
  16. data/examples/pivot_table.rb +39 -0
  17. data/examples/skydrive/real_example.rb +8 -8
  18. data/examples/styles.rb +66 -0
  19. data/examples/underline.rb +13 -0
  20. data/examples/wrap_text.rb +21 -0
  21. data/lib/axlsx/content_type/abstract_content_type.rb +32 -0
  22. data/lib/axlsx/content_type/content_type.rb +1 -1
  23. data/lib/axlsx/content_type/default.rb +6 -37
  24. data/lib/axlsx/content_type/override.rb +6 -38
  25. data/lib/axlsx/doc_props/app.rb +10 -7
  26. data/lib/axlsx/doc_props/core.rb +6 -1
  27. data/lib/axlsx/drawing/axes.rb +61 -0
  28. data/lib/axlsx/drawing/axis.rb +20 -17
  29. data/lib/axlsx/drawing/bar_3D_chart.rb +31 -22
  30. data/lib/axlsx/drawing/cat_axis.rb +2 -10
  31. data/lib/axlsx/drawing/chart.rb +33 -6
  32. data/lib/axlsx/drawing/d_lbls.rb +21 -31
  33. data/lib/axlsx/drawing/drawing.rb +11 -17
  34. data/lib/axlsx/drawing/graphic_frame.rb +3 -3
  35. data/lib/axlsx/drawing/hyperlink.rb +42 -36
  36. data/lib/axlsx/drawing/line_3D_chart.rb +28 -70
  37. data/lib/axlsx/drawing/line_chart.rb +99 -0
  38. data/lib/axlsx/drawing/line_series.rb +20 -2
  39. data/lib/axlsx/drawing/marker.rb +38 -18
  40. data/lib/axlsx/drawing/num_data.rb +6 -6
  41. data/lib/axlsx/drawing/num_data_source.rb +17 -16
  42. data/lib/axlsx/drawing/one_cell_anchor.rb +28 -21
  43. data/lib/axlsx/drawing/pic.rb +43 -45
  44. data/lib/axlsx/drawing/picture_locking.rb +12 -44
  45. data/lib/axlsx/drawing/pie_3D_chart.rb +2 -1
  46. data/lib/axlsx/drawing/scaling.rb +13 -13
  47. data/lib/axlsx/drawing/scatter_chart.rb +32 -21
  48. data/lib/axlsx/drawing/ser_axis.rb +15 -16
  49. data/lib/axlsx/drawing/series.rb +3 -6
  50. data/lib/axlsx/drawing/str_data.rb +3 -3
  51. data/lib/axlsx/drawing/str_val.rb +7 -8
  52. data/lib/axlsx/drawing/two_cell_anchor.rb +7 -27
  53. data/lib/axlsx/drawing/val_axis.rb +14 -13
  54. data/lib/axlsx/drawing/view_3D.rb +52 -38
  55. data/lib/axlsx/drawing/vml_shape.rb +20 -79
  56. data/lib/axlsx/package.rb +58 -28
  57. data/lib/axlsx/rels/relationship.rb +75 -9
  58. data/lib/axlsx/rels/relationships.rb +8 -1
  59. data/lib/axlsx/stylesheet/border.rb +29 -20
  60. data/lib/axlsx/stylesheet/border_pr.rb +5 -4
  61. data/lib/axlsx/stylesheet/cell_alignment.rb +55 -29
  62. data/lib/axlsx/stylesheet/cell_protection.rb +7 -4
  63. data/lib/axlsx/stylesheet/cell_style.rb +19 -14
  64. data/lib/axlsx/stylesheet/color.rb +20 -17
  65. data/lib/axlsx/stylesheet/dxf.rb +4 -4
  66. data/lib/axlsx/stylesheet/font.rb +22 -22
  67. data/lib/axlsx/stylesheet/gradient_fill.rb +45 -21
  68. data/lib/axlsx/stylesheet/num_fmt.rb +23 -14
  69. data/lib/axlsx/stylesheet/pattern_fill.rb +12 -21
  70. data/lib/axlsx/stylesheet/styles.rb +37 -22
  71. data/lib/axlsx/stylesheet/table_style.rb +17 -16
  72. data/lib/axlsx/stylesheet/table_style_element.rb +15 -11
  73. data/lib/axlsx/stylesheet/table_styles.rb +14 -11
  74. data/lib/axlsx/stylesheet/xf.rb +28 -26
  75. data/lib/axlsx/util/accessors.rb +64 -0
  76. data/lib/axlsx/util/constants.rb +127 -6
  77. data/lib/axlsx/util/options_parser.rb +15 -0
  78. data/lib/axlsx/util/serialized_attributes.rb +79 -0
  79. data/lib/axlsx/util/simple_typed_list.rb +50 -15
  80. data/lib/axlsx/util/validators.rb +51 -16
  81. data/lib/axlsx/version.rb +2 -2
  82. data/lib/axlsx/workbook/defined_name.rb +14 -59
  83. data/lib/axlsx/workbook/shared_strings_table.rb +13 -4
  84. data/lib/axlsx/workbook/workbook.rb +85 -6
  85. data/lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb +77 -0
  86. data/lib/axlsx/workbook/worksheet/auto_filter/filter_column.rb +94 -0
  87. data/lib/axlsx/workbook/worksheet/auto_filter/filters.rb +246 -0
  88. data/lib/axlsx/workbook/worksheet/break.rb +37 -0
  89. data/lib/axlsx/workbook/worksheet/cell.rb +109 -107
  90. data/lib/axlsx/workbook/worksheet/cell_serializer.rb +144 -0
  91. data/lib/axlsx/workbook/worksheet/cfvo.rb +15 -15
  92. data/lib/axlsx/workbook/worksheet/cfvos.rb +15 -0
  93. data/lib/axlsx/workbook/worksheet/col.rb +43 -29
  94. data/lib/axlsx/workbook/worksheet/col_breaks.rb +35 -0
  95. data/lib/axlsx/workbook/worksheet/color_scale.rb +62 -28
  96. data/lib/axlsx/workbook/worksheet/comment.rb +28 -37
  97. data/lib/axlsx/workbook/worksheet/comments.rb +3 -3
  98. data/lib/axlsx/workbook/worksheet/conditional_formatting.rb +11 -11
  99. data/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb +31 -27
  100. data/lib/axlsx/workbook/worksheet/data_bar.rb +75 -41
  101. data/lib/axlsx/workbook/worksheet/data_validation.rb +61 -62
  102. data/lib/axlsx/workbook/worksheet/date_time_converter.rb +6 -5
  103. data/lib/axlsx/workbook/worksheet/dimension.rb +0 -1
  104. data/lib/axlsx/workbook/worksheet/header_footer.rb +54 -0
  105. data/lib/axlsx/workbook/worksheet/icon_set.rb +20 -20
  106. data/lib/axlsx/workbook/worksheet/page_margins.rb +21 -19
  107. data/lib/axlsx/workbook/worksheet/page_set_up_pr.rb +44 -0
  108. data/lib/axlsx/workbook/worksheet/page_setup.rb +152 -23
  109. data/lib/axlsx/workbook/worksheet/pane.rb +48 -51
  110. data/lib/axlsx/workbook/worksheet/pivot_table.rb +273 -0
  111. data/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb +66 -0
  112. data/lib/axlsx/workbook/worksheet/pivot_tables.rb +24 -0
  113. data/lib/axlsx/workbook/worksheet/print_options.rb +8 -30
  114. data/lib/axlsx/workbook/worksheet/protected_range.rb +16 -13
  115. data/lib/axlsx/workbook/worksheet/row.rb +59 -83
  116. data/lib/axlsx/workbook/worksheet/row_breaks.rb +33 -0
  117. data/lib/axlsx/workbook/worksheet/selection.rb +30 -38
  118. data/lib/axlsx/workbook/worksheet/sheet_calc_pr.rb +29 -0
  119. data/lib/axlsx/workbook/worksheet/sheet_format_pr.rb +60 -0
  120. data/lib/axlsx/workbook/worksheet/sheet_pr.rb +49 -4
  121. data/lib/axlsx/workbook/worksheet/sheet_protection.rb +51 -155
  122. data/lib/axlsx/workbook/worksheet/sheet_view.rb +68 -234
  123. data/lib/axlsx/workbook/worksheet/table.rb +25 -19
  124. data/lib/axlsx/workbook/worksheet/table_style_info.rb +51 -0
  125. data/lib/axlsx/workbook/worksheet/tables.rb +1 -1
  126. data/lib/axlsx/workbook/worksheet/worksheet.rb +174 -35
  127. data/lib/axlsx/workbook/worksheet/worksheet_comments.rb +6 -5
  128. data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +4 -10
  129. data/lib/axlsx/workbook/worksheet/worksheet_hyperlink.rb +74 -0
  130. data/lib/axlsx/workbook/worksheet/worksheet_hyperlinks.rb +38 -0
  131. data/lib/axlsx.rb +55 -5
  132. data/lib/schema/sml.xsd +4 -0
  133. data/test/axlsx.qcachegrind +2226 -0
  134. data/test/benchmark.rb +2 -3
  135. data/test/content_type/tc_default.rb +0 -11
  136. data/test/content_type/tc_override.rb +0 -13
  137. data/test/doc_props/tc_core.rb +7 -0
  138. data/test/drawing/tc_axes.rb +8 -0
  139. data/test/drawing/tc_axis.rb +15 -17
  140. data/test/drawing/tc_bar_3D_chart.rb +6 -0
  141. data/test/drawing/tc_cat_axis.rb +9 -9
  142. data/test/drawing/tc_chart.rb +20 -0
  143. data/test/drawing/tc_d_lbls.rb +14 -4
  144. data/test/drawing/tc_drawing.rb +0 -5
  145. data/test/drawing/tc_graphic_frame.rb +5 -3
  146. data/test/drawing/tc_hyperlink.rb +0 -4
  147. data/test/drawing/tc_line_chart.rb +39 -0
  148. data/test/drawing/tc_line_series.rb +8 -2
  149. data/test/drawing/tc_pic.rb +14 -3
  150. data/test/drawing/tc_ser_axis.rb +13 -12
  151. data/test/drawing/tc_two_cell_anchor.rb +3 -3
  152. data/test/drawing/tc_val_axis.rb +6 -6
  153. data/test/drawing/tc_vml_shape.rb +9 -3
  154. data/test/profile.rb +11 -21
  155. data/test/rels/tc_relationship.rb +32 -9
  156. data/test/rels/tc_relationships.rb +12 -1
  157. data/test/stylesheet/tc_color.rb +6 -0
  158. data/test/stylesheet/tc_styles.rb +15 -2
  159. data/test/tc_axlsx.rb +35 -2
  160. data/test/tc_helper.rb +7 -1
  161. data/test/tc_package.rb +44 -5
  162. data/test/util/tc_serialized_attributes.rb +19 -0
  163. data/test/util/tc_validators.rb +26 -1
  164. data/test/workbook/tc_defined_name.rb +2 -2
  165. data/test/workbook/tc_shared_strings_table.rb +6 -0
  166. data/test/workbook/tc_workbook.rb +38 -1
  167. data/test/workbook/worksheet/auto_filter/tc_auto_filter.rb +38 -0
  168. data/test/workbook/worksheet/auto_filter/tc_filter_column.rb +76 -0
  169. data/test/workbook/worksheet/auto_filter/tc_filters.rb +50 -0
  170. data/test/workbook/worksheet/tc_break.rb +49 -0
  171. data/test/workbook/worksheet/tc_cell.rb +40 -6
  172. data/test/workbook/worksheet/tc_col.rb +11 -1
  173. data/test/workbook/worksheet/tc_color_scale.rb +31 -2
  174. data/test/workbook/worksheet/tc_comment.rb +21 -6
  175. data/test/workbook/worksheet/tc_comments.rb +2 -2
  176. data/test/workbook/worksheet/tc_conditional_formatting.rb +7 -0
  177. data/test/workbook/worksheet/tc_data_bar.rb +7 -0
  178. data/test/workbook/worksheet/tc_date_time_converter.rb +3 -11
  179. data/test/workbook/worksheet/tc_header_footer.rb +151 -0
  180. data/test/workbook/worksheet/tc_page_set_up_pr.rb +15 -0
  181. data/test/workbook/worksheet/tc_page_setup.rb +6 -1
  182. data/test/workbook/worksheet/tc_pane.rb +5 -45
  183. data/test/workbook/worksheet/tc_pivot_table.rb +120 -0
  184. data/test/workbook/worksheet/tc_pivot_table_cache_definition.rb +54 -0
  185. data/test/workbook/worksheet/tc_row.rb +4 -4
  186. data/test/workbook/worksheet/tc_selection.rb +9 -48
  187. data/test/workbook/worksheet/tc_sheet_calc_pr.rb +18 -0
  188. data/test/workbook/worksheet/tc_sheet_format_pr.rb +88 -0
  189. data/test/workbook/worksheet/tc_sheet_pr.rb +27 -0
  190. data/test/workbook/worksheet/tc_sheet_view.rb +39 -39
  191. data/test/workbook/worksheet/{table/tc_table.rb → tc_table.rb} +8 -3
  192. data/test/workbook/worksheet/tc_table_style_info.rb +53 -0
  193. data/test/workbook/worksheet/tc_worksheet.rb +131 -16
  194. data/test/workbook/worksheet/tc_worksheet_hyperlink.rb +55 -0
  195. metadata +97 -64
  196. data/examples/example.xlsx +0 -0
  197. data/examples/example_streamed.xlsx +0 -0
  198. data/examples/extractive.pdf +0 -0
  199. data/examples/image1.gif +0 -0
  200. data/examples/image1.jpg +0 -0
  201. data/examples/image1.png +0 -0
  202. data/examples/no-use_autowidth.xlsx +0 -0
  203. data/examples/sample.png +0 -0
  204. data/examples/scraping_html.rb +0 -91
  205. data/examples/shared_strings_example.xlsx +0 -0
  206. data/examples/sheet_view.rb +0 -34
  207. data/examples/two_cell_anchor_image.rb +0 -11
  208. data/lib/axlsx/workbook/worksheet/auto_filter.rb +0 -34
@@ -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
@@ -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
+
@@ -8,6 +8,44 @@ 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 [Number] formula_value The value to cache for a formula cell.
32
+ # @option options [Symbol] scheme must be one of :none, major, :minor
33
+ def initialize(row, value="", options={})
34
+ self.row=row
35
+ @value = nil
36
+ #@value = @font_name = @charset = @family = @b = @i = @strike = @outline = @shadow = nil
37
+ #@formula_value = @condense = @u = @vertAlign = @sz = @color = @scheme = @extend = @ssti = nil
38
+ @styles = row.worksheet.workbook.styles
39
+ @row.cells << self
40
+ parse_options options
41
+ @style ||= 0
42
+ @type ||= cell_type_from_value(value)
43
+ @value = cast_value(value)
44
+ end
45
+
46
+ # this is the cached value for formula cells. If you want the values to render in iOS/Mac OSX preview
47
+ # you need to set this.
48
+ attr_accessor :formula_value
11
49
 
12
50
  # An array of available inline styes.
13
51
  # TODO change this to a hash where each key defines attr name and validator (and any info the validator requires)
@@ -16,9 +54,9 @@ module Axlsx
16
54
  # set_attr method that kicks the suplied validator and updates the instance_variable
17
55
  # for the key
18
56
  INLINE_STYLES = ['value', 'type', 'font_name', 'charset',
19
- 'family', 'b', 'i', 'strike','outline',
20
- 'shadow', 'condense', 'extend', 'u',
21
- 'vertAlign', 'sz', 'color', 'scheme']
57
+ 'family', 'b', 'i', 'strike','outline',
58
+ 'shadow', 'condense', 'extend', 'u',
59
+ 'vertAlign', 'sz', 'color', 'scheme']
22
60
 
23
61
  # The index of the cellXfs item to be applied to this cell.
24
62
  # @return [Integer]
@@ -43,14 +81,14 @@ module Axlsx
43
81
  attr_reader :type
44
82
  # @see type
45
83
  def type=(v)
46
- RestrictionValidator.validate "Cell.type", [:date, :time, :float, :integer, :string, :boolean], v
84
+ RestrictionValidator.validate "Cell.type", [:date, :time, :float, :integer, :string, :boolean, :iso_8601], v
47
85
  @type=v
48
86
  self.value = @value unless @value.nil?
49
87
  end
50
88
 
51
89
 
52
90
  # The value of this cell.
53
- # @return [String, Integer, Float, Time] casted value based on cell's type attribute.
91
+ # @return [String, Integer, Float, Time, Boolean] casted value based on cell's type attribute.
54
92
  attr_reader :value
55
93
  # @see value
56
94
  def value=(v)
@@ -80,16 +118,43 @@ module Axlsx
80
118
  def font_name=(v) set_run_style :validate_string, :font_name, v; end
81
119
 
82
120
  # The inline charset property for the cell
121
+ # As far as I can tell, this is pretty much ignored. However, based on the spec it should be one of the following:
122
+ # 0  ANSI_CHARSET
123
+ # 1 DEFAULT_CHARSET
124
+ # 2 SYMBOL_CHARSET
125
+ # 77 MAC_CHARSET
126
+ # 128 SHIFTJIS_CHARSET
127
+ # 129  HANGUL_CHARSET
128
+ # 130  JOHAB_CHARSET
129
+ # 134  GB2312_CHARSET
130
+ # 136  CHINESEBIG5_CHARSET
131
+ # 161  GREEK_CHARSET
132
+ # 162  TURKISH_CHARSET
133
+ # 163  VIETNAMESE_CHARSET
134
+ # 177  HEBREW_CHARSET
135
+ # 178  ARABIC_CHARSET
136
+ # 186  BALTIC_CHARSET
137
+ # 204  RUSSIAN_CHARSET
138
+ # 222  THAI_CHARSET
139
+ # 238  EASTEUROPE_CHARSET
140
+ # 255  OEM_CHARSET
83
141
  # @return [String]
84
142
  attr_reader :charset
85
143
  # @see charset
86
144
  def charset=(v) set_run_style :validate_unsigned_int, :charset, v; end
87
145
 
88
146
  # The inline family property for the cell
89
- # @return [String]
147
+ # @return [Integer]
148
+ # 1 Roman
149
+ # 2 Swiss
150
+ # 3 Modern
151
+ # 4 Script
152
+ # 5 Decorative
90
153
  attr_reader :family
91
154
  # @see family
92
- def family=(v) set_run_style :validate_string, :family, v; end
155
+ def family=(v)
156
+ set_run_style :validate_family, :family, v.to_i
157
+ end
93
158
 
94
159
  # The inline bold property for the cell
95
160
  # @return [Boolean]
@@ -133,11 +198,17 @@ module Axlsx
133
198
  # @see extend
134
199
  def extend=(v) set_run_style :validate_boolean, :extend, v; end
135
200
 
136
- # The inline underline property for the cell
201
+ # The inline underline property for the cell.
202
+ # It must be one of :none, :single, :double, :singleAccounting, :doubleAccounting, true
137
203
  # @return [Boolean]
204
+ # @return [String]
205
+ # @note true is for backwards compatability and is reassigned to :single
138
206
  attr_reader :u
139
207
  # @see u
140
- def u=(v) set_run_style :validate_boolean, :u, v; end
208
+ def u=(v)
209
+ v = :single if (v == true || v == 1 || v == :true || v == 'true')
210
+ set_run_style :validate_cell_u, :u, v
211
+ end
141
212
 
142
213
  # The inline color property for the cell
143
214
  # @return [Color]
@@ -149,7 +220,7 @@ module Axlsx
149
220
  end
150
221
 
151
222
  # The inline sz property for the cell
152
- # @return [Boolean]
223
+ # @return [Inteter]
153
224
  attr_reader :sz
154
225
  # @see sz
155
226
  def sz=(v) set_run_style :validate_unsigned_int, :sz, v; end
@@ -174,39 +245,6 @@ module Axlsx
174
245
  set_run_style nil, :scheme, v
175
246
  end
176
247
 
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
248
  # The Shared Strings Table index for this cell
211
249
  # @return [Integer]
212
250
  attr_reader :ssti
@@ -256,65 +294,13 @@ module Axlsx
256
294
  self.row.worksheet.merge_cells "#{self.r}:#{range_end}" unless range_end.nil?
257
295
  end
258
296
 
259
- # builds an xml text run based on this cells attributes.
260
- # @param [String] str The string instance this run will be concated to.
261
- # @return [String]
262
- def run_xml_string(str = '')
263
- if is_text_run?
264
- data = instance_values.reject{|key, value| value == nil || key == 'value' || key == 'type' }
265
- keys = data.keys & INLINE_STYLES
266
- str << "<r><rPr>"
267
- keys.each do |key|
268
- case key
269
- when 'font_name'
270
- str << "<rFont val='"<< @font_name << "'/>"
271
- when 'color'
272
- str << data[key].to_xml_string
273
- else
274
- str << "<" << key.to_s << " val='" << data[key].to_s << "'/>"
275
- end
276
- end
277
- str << "</rPr>" << "<t>" << value.to_s << "</t></r>"
278
- else
279
- str << "<t>" << value.to_s << "</t>"
280
- end
281
- str
282
- end
283
-
284
297
  # Serializes the cell
285
298
  # @param [Integer] r_index The row index for the cell
286
299
  # @param [Integer] c_index The cell index in the row.
287
300
  # @param [String] str The string index the cell content will be appended to. Defaults to empty string.
288
301
  # @return [String] xml text for the cell
289
302
  def to_xml_string(r_index, c_index, str = '')
290
- str << '<c r="' << Axlsx::cell_r(c_index, r_index) << '" s="' << @style.to_s << '" '
291
- return str << '/>' if @value.nil?
292
-
293
- case @type
294
-
295
- when :string
296
- #parse formula
297
- if @value.start_with?('=')
298
- str << 't="str"><f>' << @value.to_s.sub('=', '') << '</f>'
299
- else
300
- #parse shared
301
- if @ssti
302
- str << 't="s"><v>' << @ssti.to_s << '</v>'
303
- else
304
- str << 't="inlineStr"><is>' << run_xml_string << '</is>'
305
- end
306
- end
307
- when :date
308
- # TODO: See if this is subject to the same restriction as Time below
309
- str << '><v>' << DateTimeConverter::date_to_serial(@value).to_s << '</v>'
310
- when :time
311
- str << '><v>' << DateTimeConverter::time_to_serial(@value).to_s << '</v>'
312
- when :boolean
313
- str << 't="b"><v>' << @value.to_s << '</v>'
314
- else
315
- str << '><v>' << @value.to_s << '</v>'
316
- end
317
- str << '</c>'
303
+ CellSerializer.to_xml_string r_index, c_index, self, str
318
304
  end
319
305
 
320
306
  def is_formula?
@@ -330,20 +316,25 @@ module Axlsx
330
316
  font_scale = (font_size/10.0).to_f
331
317
  ((value.to_s.count(Worksheet.thin_chars) * mdw + 5) / mdw * 256) / 256.0 * font_scale
332
318
  end
333
-
319
+
334
320
  # returns the absolute or relative string style reference for
335
- # this cell.
321
+ # this cell.
336
322
  # @param [Boolean] absolute -when false a relative reference will be
337
- # returned.
323
+ # returned.
338
324
  # @return [String]
339
325
  def reference(absolute=true)
340
326
  absolute ? r_abs : r
341
- end
342
-
327
+ end
328
+
343
329
  private
344
330
 
331
+ # we scale the font size if bold style is applied to either the style font or
332
+ # the cell itself. Yes, it is a bit of a hack, but it is much better than using
333
+ # imagemagick and loading metrics for every character.
345
334
  def font_size
346
- sz || @styles.fonts[@styles.cellXfs[style].fontId].sz
335
+ font = @styles.fonts[@styles.cellXfs[style].fontId] || @styles.fonts[0]
336
+ size_from_styles = (font.b || b) ? font.sz * 1.5 : font.sz
337
+ sz || size_from_styles
347
338
  end
348
339
 
349
340
  # Utility method for setting inline style attributes
@@ -361,7 +352,7 @@ module Axlsx
361
352
  end
362
353
 
363
354
  # assigns the owning row for this cell.
364
- def row=(v) DataTypeValidator.validate "Cell.row", Row, v; @row=v end
355
+ def row=(v) @row=v end
365
356
 
366
357
  # Determines the cell type based on the cell value.
367
358
  # @note This is only used when a cell is created but no :type option is specified, the following rules apply:
@@ -378,10 +369,15 @@ module Axlsx
378
369
  :time
379
370
  elsif v.is_a?(TrueClass) || v.is_a?(FalseClass)
380
371
  :boolean
381
- elsif v.to_s.match(/\A[+-]?\d+?\Z/) #numeric
372
+ elsif v.to_s =~ /\A[+-]?\d+?\Z/ #numeric
382
373
  :integer
383
- elsif v.to_s.match(/\A[+-]?\d+\.\d+?\Z/) #float
374
+ elsif v.to_s =~ /\A[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?\Z/ #float
384
375
  :float
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
+ # 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
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
+ :iso_8601
385
381
  else
386
382
  :string
387
383
  end
@@ -389,7 +385,7 @@ module Axlsx
389
385
 
390
386
  # Cast the value into this cells data type.
391
387
  # @note
392
- # About Time - Time in OOXML is *different* from what you might expect. The history as to why is interesting, but you can safely assume that if you are generating docs on a mac, you will want to specify Workbook.1904 as true when using time typed values.
388
+ # About Time - Time in OOXML is *different* from what you might expect. The history as to why is interesting, but you can safely assume that if you are generating docs on a mac, you will want to specify Workbook.1904 as true when using time typed values.
393
389
  # @see Axlsx#date1904
394
390
  def cast_value(v)
395
391
  return nil if v.nil?
@@ -405,10 +401,16 @@ module Axlsx
405
401
  v.to_i
406
402
  elsif @type == :boolean
407
403
  v ? 1 : 0
404
+ elsif @type == :iso_8601
405
+ #consumer is responsible for ensuring the iso_8601 format when specifying this type
406
+ v
408
407
  else
409
408
  @type = :string
410
- ::CGI.escapeHTML(v.to_s)
409
+ # TODO find a better way to do this as it accounts for 30% of
410
+ # processing time in benchmarking...
411
+ Axlsx::trust_input ? v.to_s : ::CGI.escapeHTML(v.to_s)
411
412
  end
412
413
  end
414
+
413
415
  end
414
416
  end