axlsx 1.1.3 → 1.2.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 (187) hide show
  1. data/.yardopts +5 -2
  2. data/CHANGELOG.md +60 -0
  3. data/LICENSE +1 -1
  4. data/README.md +115 -415
  5. data/Rakefile +11 -3
  6. data/examples/basic_charts.rb +54 -0
  7. data/examples/chart_colors.rb +88 -0
  8. data/examples/data_validation.rb +50 -0
  9. data/examples/example.rb +299 -155
  10. data/examples/example.xlsx +0 -0
  11. data/examples/example_streamed.xlsx +0 -0
  12. data/examples/extractive.pdf +0 -0
  13. data/examples/extractive.rb +45 -0
  14. data/examples/no-use_autowidth.xlsx +0 -0
  15. data/examples/scraping_html.rb +91 -0
  16. data/examples/shared_strings_example.xlsx +0 -0
  17. data/examples/sheet_protection.rb +10 -0
  18. data/examples/sheet_view.rb +34 -0
  19. data/examples/two_cell_anchor_image.rb +11 -0
  20. data/lib/axlsx/content_type/content_type.rb +2 -0
  21. data/lib/axlsx/content_type/default.rb +30 -15
  22. data/lib/axlsx/content_type/override.rb +29 -14
  23. data/lib/axlsx/doc_props/app.rb +161 -104
  24. data/lib/axlsx/doc_props/core.rb +9 -5
  25. data/lib/axlsx/drawing/ax_data_source.rb +26 -0
  26. data/lib/axlsx/drawing/axis.rb +92 -37
  27. data/lib/axlsx/drawing/bar_3D_chart.rb +49 -45
  28. data/lib/axlsx/drawing/bar_series.rb +25 -7
  29. data/lib/axlsx/drawing/cat_axis.rb +50 -22
  30. data/lib/axlsx/drawing/chart.rb +69 -56
  31. data/lib/axlsx/drawing/d_lbls.rb +100 -0
  32. data/lib/axlsx/drawing/drawing.rb +28 -12
  33. data/lib/axlsx/drawing/graphic_frame.rb +2 -1
  34. data/lib/axlsx/drawing/line_3D_chart.rb +3 -10
  35. data/lib/axlsx/drawing/line_series.rb +20 -4
  36. data/lib/axlsx/drawing/num_data.rb +52 -0
  37. data/lib/axlsx/drawing/num_data_source.rb +61 -0
  38. data/lib/axlsx/drawing/num_val.rb +32 -0
  39. data/lib/axlsx/drawing/pic.rb +44 -4
  40. data/lib/axlsx/drawing/pie_3D_chart.rb +10 -7
  41. data/lib/axlsx/drawing/pie_series.rb +18 -4
  42. data/lib/axlsx/drawing/scatter_chart.rb +2 -8
  43. data/lib/axlsx/drawing/scatter_series.rb +28 -2
  44. data/lib/axlsx/drawing/ser_axis.rb +1 -1
  45. data/lib/axlsx/drawing/series.rb +1 -1
  46. data/lib/axlsx/drawing/str_data.rb +42 -0
  47. data/lib/axlsx/drawing/str_val.rb +33 -0
  48. data/lib/axlsx/drawing/title.rb +21 -9
  49. data/lib/axlsx/drawing/two_cell_anchor.rb +46 -9
  50. data/lib/axlsx/drawing/view_3D.rb +44 -31
  51. data/lib/axlsx/drawing/vml_drawing.rb +42 -0
  52. data/lib/axlsx/drawing/vml_shape.rb +125 -0
  53. data/lib/axlsx/package.rb +44 -16
  54. data/lib/axlsx/rels/relationship.rb +3 -3
  55. data/lib/axlsx/rels/relationships.rb +1 -11
  56. data/lib/axlsx/stylesheet/gradient_fill.rb +1 -1
  57. data/lib/axlsx/stylesheet/styles.rb +1 -1
  58. data/lib/axlsx/stylesheet/table_style.rb +3 -3
  59. data/lib/axlsx/util/constants.rb +28 -0
  60. data/lib/axlsx/util/simple_typed_list.rb +15 -21
  61. data/lib/axlsx/util/validators.rb +81 -8
  62. data/lib/axlsx/version.rb +2 -7
  63. data/lib/axlsx/workbook/defined_name.rb +174 -0
  64. data/lib/axlsx/workbook/defined_names.rb +21 -0
  65. data/lib/axlsx/workbook/workbook.rb +65 -13
  66. data/lib/axlsx/workbook/worksheet/auto_filter.rb +34 -0
  67. data/lib/axlsx/workbook/worksheet/cell.rb +35 -7
  68. data/lib/axlsx/workbook/worksheet/col.rb +17 -1
  69. data/lib/axlsx/workbook/worksheet/cols.rb +20 -0
  70. data/lib/axlsx/workbook/worksheet/comment.rb +101 -0
  71. data/lib/axlsx/workbook/worksheet/comments.rb +85 -0
  72. data/lib/axlsx/workbook/worksheet/conditional_formattings.rb +25 -0
  73. data/lib/axlsx/workbook/worksheet/data_bar.rb +1 -1
  74. data/lib/axlsx/workbook/worksheet/data_validation.rb +245 -0
  75. data/lib/axlsx/workbook/worksheet/data_validations.rb +28 -0
  76. data/lib/axlsx/workbook/worksheet/dimension.rb +65 -0
  77. data/lib/axlsx/workbook/worksheet/merged_cells.rb +35 -0
  78. data/lib/axlsx/workbook/worksheet/page_setup.rb +113 -0
  79. data/lib/axlsx/workbook/worksheet/pane.rb +144 -0
  80. data/lib/axlsx/workbook/worksheet/print_options.rb +63 -0
  81. data/lib/axlsx/workbook/worksheet/protected_range.rb +46 -0
  82. data/lib/axlsx/workbook/worksheet/protected_ranges.rb +34 -0
  83. data/lib/axlsx/workbook/worksheet/row.rb +67 -12
  84. data/lib/axlsx/workbook/worksheet/selection.rb +111 -0
  85. data/lib/axlsx/workbook/worksheet/sheet_data.rb +25 -0
  86. data/lib/axlsx/workbook/worksheet/sheet_pr.rb +24 -0
  87. data/lib/axlsx/workbook/worksheet/sheet_protection.rb +224 -0
  88. data/lib/axlsx/workbook/worksheet/sheet_view.rb +379 -0
  89. data/lib/axlsx/workbook/worksheet/table.rb +3 -3
  90. data/lib/axlsx/workbook/worksheet/tables.rb +31 -0
  91. data/lib/axlsx/workbook/worksheet/worksheet.rb +377 -255
  92. data/lib/axlsx/workbook/worksheet/worksheet_comments.rb +57 -0
  93. data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +64 -0
  94. data/lib/axlsx.rb +30 -15
  95. data/test/content_type/tc_content_type.rb +1 -6
  96. data/test/doc_props/tc_app.rb +31 -1
  97. data/test/doc_props/tc_core.rb +3 -1
  98. data/test/drawing/tc_axis.rb +38 -3
  99. data/test/drawing/tc_bar_3D_chart.rb +12 -12
  100. data/test/drawing/tc_bar_series.rb +17 -13
  101. data/test/drawing/tc_cat_axis.rb +3 -3
  102. data/test/drawing/tc_cat_axis_data.rb +23 -13
  103. data/test/drawing/tc_chart.rb +29 -11
  104. data/test/drawing/tc_d_lbls.rb +47 -0
  105. data/test/drawing/tc_data_source.rb +17 -0
  106. data/test/drawing/tc_drawing.rb +11 -5
  107. data/test/drawing/tc_hyperlink.rb +4 -5
  108. data/test/drawing/tc_line_series.rb +9 -11
  109. data/test/drawing/tc_named_axis_data.rb +27 -0
  110. data/test/drawing/tc_num_data.rb +31 -0
  111. data/test/drawing/tc_num_val.rb +29 -0
  112. data/test/drawing/tc_pic.rb +22 -2
  113. data/test/drawing/tc_pie_3D_chart.rb +4 -8
  114. data/test/drawing/tc_pie_series.rb +11 -13
  115. data/test/drawing/tc_scatter_chart.rb +6 -1
  116. data/test/drawing/tc_scatter_series.rb +6 -5
  117. data/test/drawing/tc_series.rb +1 -1
  118. data/test/drawing/tc_str_data.rb +18 -0
  119. data/test/drawing/tc_str_val.rb +21 -0
  120. data/test/drawing/tc_title.rb +16 -0
  121. data/test/drawing/tc_two_cell_anchor.rb +2 -3
  122. data/test/drawing/tc_view_3D.rb +18 -18
  123. data/test/drawing/tc_vml_drawing.rb +25 -0
  124. data/test/drawing/tc_vml_shape.rb +100 -0
  125. data/test/rels/tc_relationship.rb +1 -0
  126. data/test/stylesheet/tc_gradient_fill.rb +8 -0
  127. data/test/stylesheet/tc_pattern_fill.rb +7 -1
  128. data/test/stylesheet/tc_styles.rb +3 -4
  129. data/test/stylesheet/tc_table_style.rb +8 -0
  130. data/test/stylesheet/tc_table_style_element.rb +10 -1
  131. data/test/tc_helper.rb +1 -0
  132. data/test/tc_package.rb +93 -17
  133. data/test/util/tc_simple_typed_list.rb +13 -0
  134. data/test/util/tc_validators.rb +95 -9
  135. data/test/workbook/tc_defined_name.rb +41 -0
  136. data/test/workbook/tc_workbook.rb +5 -3
  137. data/test/workbook/worksheet/table/tc_table.rb +3 -11
  138. data/test/workbook/worksheet/tc_cell.rb +30 -6
  139. data/test/workbook/worksheet/tc_col.rb +9 -0
  140. data/test/workbook/worksheet/tc_comment.rb +57 -0
  141. data/test/workbook/worksheet/tc_comments.rb +57 -0
  142. data/test/workbook/worksheet/tc_conditional_formatting.rb +44 -0
  143. data/test/workbook/worksheet/tc_data_bar.rb +1 -1
  144. data/test/workbook/worksheet/tc_data_validation.rb +265 -0
  145. data/test/workbook/worksheet/tc_page_setup.rb +138 -0
  146. data/test/workbook/worksheet/tc_pane.rb +94 -0
  147. data/test/workbook/worksheet/tc_print_options.rb +72 -0
  148. data/test/workbook/worksheet/tc_protected_range.rb +17 -0
  149. data/test/workbook/worksheet/tc_row.rb +36 -12
  150. data/test/workbook/worksheet/tc_selection.rb +94 -0
  151. data/test/workbook/worksheet/tc_sheet_protection.rb +117 -0
  152. data/test/workbook/worksheet/tc_sheet_view.rb +214 -0
  153. data/test/workbook/worksheet/tc_worksheet.rb +138 -48
  154. metadata +164 -52
  155. data/examples/example.csv +0 -1000
  156. data/lib/axlsx/drawing/cat_axis_data.rb +0 -34
  157. data/lib/axlsx/drawing/hlink_click.rb~ +0 -0
  158. data/lib/axlsx/drawing/hyperlink.rb~ +0 -64
  159. data/lib/axlsx/drawing/named_axis_data.rb +0 -36
  160. data/lib/axlsx/drawing/picture_locking.rb~ +0 -36
  161. data/lib/axlsx/drawing/val_axis_data.rb +0 -27
  162. data/lib/axlsx/util/cbf.rb +0 -333
  163. data/lib/axlsx/util/cfb.rb~ +0 -201
  164. data/lib/axlsx/util/font_tables.rb~ +0 -0
  165. data/lib/axlsx/util/ms_off_crypto.rb +0 -189
  166. data/lib/axlsx/util/ms_off_crypto.rb~ +0 -3
  167. data/lib/axlsx/util/ms_offcrypto.rb~ +0 -0
  168. data/lib/axlsx/util/parser.rb~ +0 -6
  169. data/lib/axlsx/util/storage.rb~ +0 -0
  170. data/lib/axlsx/workbook/shared_strings_table.rb~ +0 -69
  171. data/lib/axlsx/workbook/worksheet/cfvo.rb~ +0 -0
  172. data/lib/axlsx/workbook/worksheet/col.rb~ +0 -0
  173. data/lib/axlsx/workbook/worksheet/color_scale.rb~ +0 -46
  174. data/lib/axlsx/workbook/worksheet/data_bar.rb~ +0 -0
  175. data/lib/axlsx/workbook/worksheet/icon_set.rb~ +0 -95
  176. data/lib/axlsx/workbook/worksheet/shared_strings_table.rb~ +0 -0
  177. data/lib/axlsx/workbook/worksheet/table.rb~ +0 -97
  178. data/lib/schema/dc.xsd~ +0 -118
  179. data/lib/schema/dcterms.xsd~ +0 -331
  180. data/lib/schema/opc-coreProperties.xsd~ +0 -50
  181. data/test/drawing/tc_val_axis_data.rb +0 -17
  182. data/test/workbook/worksheet/table/tc_table.rb~ +0 -72
  183. data/test/workbook/worksheet/tc_cfvo.rb~ +0 -20
  184. data/test/workbook/worksheet/tc_col.rb~ +0 -10
  185. data/test/workbook/worksheet/tc_color_scale.rb~ +0 -0
  186. data/test/workbook/worksheet/tc_data_bar.rb~ +0 -0
  187. data/test/workbook/worksheet/tc_icon_set.rb~ +0 -0
@@ -142,7 +142,7 @@ module Axlsx
142
142
  # The inline color property for the cell
143
143
  # @return [Color]
144
144
  attr_reader :color
145
- # @param [String] The 8 character representation for an rgb color #FFFFFFFF"
145
+ # @param [String] v The 8 character representation for an rgb color #FFFFFFFF"
146
146
  def color=(v)
147
147
  @color = v.is_a?(Color) ? v : Color.new(:rgb=>v)
148
148
  @is_text_run = true
@@ -195,7 +195,7 @@ module Axlsx
195
195
  # @option options [Symbol] scheme must be one of :none, major, :minor
196
196
  def initialize(row, value="", options={})
197
197
  self.row=row
198
- @font_name = @charset = @family = @b = @i = @strike = @outline = @shadow = nil
198
+ @value = @font_name = @charset = @family = @b = @i = @strike = @outline = @shadow = nil
199
199
  @condense = @u = @vertAlign = @sz = @color = @scheme = @extend = @ssti = nil
200
200
  @styles = row.worksheet.workbook.styles
201
201
  @row.cells << self
@@ -261,9 +261,8 @@ module Axlsx
261
261
  # @return [String]
262
262
  def run_xml_string(str = '')
263
263
  if is_text_run?
264
- data = self.instance_values.reject{|key, value| value == nil }
264
+ data = instance_values.reject{|key, value| value == nil || key == 'value' || key == 'type' }
265
265
  keys = data.keys & INLINE_STYLES
266
- keys.delete ['value', 'type']
267
266
  str << "<r><rPr>"
268
267
  keys.each do |key|
269
268
  case key
@@ -272,7 +271,7 @@ module Axlsx
272
271
  when 'color'
273
272
  str << data[key].to_xml_string
274
273
  else
275
- "<" << key.to_s << " val='" << data[key].to_s << "'/>"
274
+ str << "<" << key.to_s << " val='" << data[key].to_s << "'/>"
276
275
  end
277
276
  end
278
277
  str << "</rPr>" << "<t>" << value.to_s << "</t></r>"
@@ -288,13 +287,15 @@ module Axlsx
288
287
  # @param [String] str The string index the cell content will be appended to. Defaults to empty string.
289
288
  # @return [String] xml text for the cell
290
289
  def to_xml_string(r_index, c_index, str = '')
291
- return str if @value.nil?
292
290
  str << '<c r="' << Axlsx::cell_r(c_index, r_index) << '" s="' << @style.to_s << '" '
291
+ return str << '/>' if @value.nil?
292
+
293
293
  case @type
294
+
294
295
  when :string
295
296
  #parse formula
296
297
  if @value.start_with?('=')
297
- str << 't="str"><f>' << @value.to_s.gsub('=', '') << '</f>'
298
+ str << 't="str"><f>' << @value.to_s.sub('=', '') << '</f>'
298
299
  else
299
300
  #parse shared
300
301
  if @ssti
@@ -316,8 +317,35 @@ module Axlsx
316
317
  str << '</c>'
317
318
  end
318
319
 
320
+ def is_formula?
321
+ @type == :string && @value.to_s.start_with?('=')
322
+ end
323
+
324
+ # This is still not perfect...
325
+ # - scaling is not linear as font sizes increst
326
+ # - different fonts have different mdw and char widths
327
+ def autowidth
328
+ return if is_formula? || value == nil
329
+ mdw = 1.78 #This is the widest width of 0..9 in arial@10px)
330
+ font_scale = (font_size/10.0).to_f
331
+ ((value.to_s.count(Worksheet.thin_chars) * mdw + 5) / mdw * 256) / 256.0 * font_scale
332
+ end
333
+
334
+ # returns the absolute or relative string style reference for
335
+ # this cell.
336
+ # @param [Boolean] absolute -when false a relative reference will be
337
+ # returned.
338
+ # @return [String]
339
+ def reference(absolute=true)
340
+ absolute ? r_abs : r
341
+ end
342
+
319
343
  private
320
344
 
345
+ def font_size
346
+ sz || @styles.fonts[@styles.cellXfs[style].fontId].sz
347
+ end
348
+
321
349
  # Utility method for setting inline style attributes
322
350
  def set_run_style( validator, attr, value)
323
351
  return unless INLINE_STYLES.include?(attr.to_s)
@@ -60,7 +60,8 @@ module Axlsx
60
60
 
61
61
  # @see Col#outline
62
62
  def outlineLevel=(v)
63
- Axlsx.validate_boolean(v)
63
+ Axlsx.validate_unsigned_numeric(v)
64
+ raise ArgumentError, 'outlineLevel must be between 0 and 7' unless 0 <= v && v <= 7
64
65
  @outlineLevel = v
65
66
  end
66
67
 
@@ -101,6 +102,21 @@ module Axlsx
101
102
  self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
102
103
  end
103
104
  end
105
+
106
+ # updates the width for this col based on the cells autowidth and
107
+ # an optionally specified fixed width
108
+ # @param [Cell] cell The cell to use in updating this col's width
109
+ # @param [Integer] fixed_width If this is specified the width is set
110
+ # to this value and the cell's attributes are ignored.
111
+ # @param [Boolean] use_autowidth If this is false, the cell's
112
+ # autowidth value will be ignored.
113
+ def update_width(cell, fixed_width=nil, use_autowidth=true)
114
+ if fixed_width.is_a? Numeric
115
+ self.width = fixed_width
116
+ elsif use_autowidth
117
+ self.width = [width || 0, cell.autowidth || 0].max
118
+ end
119
+ end
104
120
 
105
121
  # Serialize this columns data to an xml string
106
122
  # @param [String] str
@@ -0,0 +1,20 @@
1
+ module Axlsx
2
+
3
+ # The cols class manages the col object used to manage column widths.
4
+ # This is where the magic happens with autowidth
5
+ class Cols < SimpleTypedList
6
+
7
+ def initialize(worksheet)
8
+ raise ArgumentError, "you must provide a worksheet" unless worksheet.is_a?(Worksheet)
9
+ super Col
10
+ @worksheet = worksheet
11
+ end
12
+
13
+ def to_xml_string(str = '')
14
+ return if empty?
15
+ str << '<cols>'
16
+ each { |item| item.to_xml_string(str) }
17
+ str << '</cols>'
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,101 @@
1
+ module Axlsx
2
+
3
+ # A comment is the text data for a comment
4
+ class Comment
5
+
6
+ # The text to render
7
+ # @return [String]
8
+ attr_reader :text
9
+
10
+ # The author of this comment
11
+ # @see Comments
12
+ # @return [String]
13
+ attr_reader :author
14
+
15
+ # The owning Comments object
16
+ # @return [Comments]
17
+ attr_reader :comments
18
+
19
+
20
+ # The string based cell position reference (e.g. 'A1') that determines the positioning of this comment
21
+ # @return [String]
22
+ attr_reader :ref
23
+
24
+ # TODO
25
+ # r (Rich Text Run)
26
+ # rPh (Phonetic Text Run)
27
+ # phoneticPr (Phonetic Properties)
28
+
29
+ def initialize(comments, options={})
30
+ raise ArgumentError, "A comment needs a parent comments object" unless comments.is_a?(Comments)
31
+ @comments = comments
32
+ options.each do |o|
33
+ self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
34
+ end
35
+ yield self if block_given?
36
+ end
37
+
38
+ # The vml shape that will render this comment
39
+ # @return [VmlShape]
40
+ def vml_shape
41
+ @vml_shape ||= initialize_vml_shape
42
+ end
43
+
44
+ #
45
+ # The index of this author in a unique sorted list of all authors in
46
+ # the comment.
47
+ # @return [Integer]
48
+ def author_index
49
+ @comments.authors.index(author)
50
+ end
51
+
52
+ # @see ref
53
+ def ref=(v)
54
+ Axlsx::DataTypeValidator.validate "Comment.ref", [String, Cell], v
55
+ @ref = v if v.is_a?(String)
56
+ @ref = v.r if v.is_a?(Cell)
57
+ end
58
+
59
+ # @see text
60
+ def text=(v)
61
+ Axlsx::validate_string(v)
62
+ @text = v
63
+ end
64
+
65
+ # @see author
66
+ def author=(v)
67
+ @author = v
68
+ end
69
+
70
+ # serialize the object
71
+ # @param [String] str
72
+ # @return [String]
73
+ def to_xml_string(str = "")
74
+ author = @comments.authors[author_index]
75
+ str << '<comment ref="' << ref << '" authorId="' << author_index.to_s << '">'
76
+ str << '<text><r>'
77
+ str << '<rPr> <b/><color indexed="81"/></rPr>'
78
+ str << '<t>' << author.to_s << ':
79
+ </t></r>'
80
+ str << '<r>'
81
+ str << '<rPr><color indexed="81"/></rPr>'
82
+ str << '<t>' << text << '</t></r></text>'
83
+ str << '</comment>'
84
+ end
85
+
86
+ private
87
+
88
+ # initialize the vml shape based on this comment's ref/position in the worksheet.
89
+ # by default, all columns are 5 columns wide and 5 rows high
90
+ def initialize_vml_shape
91
+ pos = Axlsx::name_to_indices(ref)
92
+ @vml_shape = VmlShape.new(:row => pos[1], :column => pos[0]) do |vml|
93
+ vml.left_column = vml.column
94
+ vml.right_column = vml.column + 2
95
+ vml.top_row = vml.row
96
+ vml.bottom_row = vml.row + 4
97
+ end
98
+ end
99
+
100
+ end
101
+ end
@@ -0,0 +1,85 @@
1
+ # -*- coding: utf-8 -*-
2
+ module Axlsx
3
+
4
+ # Comments is a collection of Comment objects for a worksheet
5
+ class Comments < SimpleTypedList
6
+
7
+ # the vml_drawing that holds the shapes for comments
8
+ # @return [VmlDrawing]
9
+ attr_reader :vml_drawing
10
+
11
+ # The worksheet that these comments belong to
12
+ # @return [Worksheet]
13
+ attr_reader :worksheet
14
+
15
+ # The index of this collection in the workbook. Effectively the index of the worksheet.
16
+ # @return [Integer]
17
+ def index
18
+ @worksheet.index
19
+ end
20
+
21
+ # The part name for this object
22
+ # @return [String]
23
+ def pn
24
+ "#{COMMENT_PN % (index+1)}"
25
+ end
26
+
27
+ # Creates a new Comments object
28
+ # @param [Worksheet] worksheet The sheet that these comments belong to.
29
+ def initialize(worksheet)
30
+ raise ArgumentError, "you must provide a worksheet" unless worksheet.is_a?(Worksheet)
31
+ super(Comment)
32
+ @worksheet = worksheet
33
+ @vml_drawing = VmlDrawing.new(self)
34
+ end
35
+
36
+ # Adds a new comment to the worksheet that owns these comments.
37
+ # @note the author, text and ref options are required
38
+ # @option options [String] author The name of the author for this comment
39
+ # @option options [String] text The text for this comment
40
+ # @option options [Stirng|Cell] ref The cell that this comment is attached to.
41
+ def add_comment(options={})
42
+ raise ArgumentError, "Comment require an author" unless options[:author]
43
+ raise ArgumentError, "Comment requires text" unless options[:text]
44
+ raise ArgumentError, "Comment requires ref" unless options[:ref]
45
+ @list << Comment.new(self, options)
46
+ yield @list.last if block_given?
47
+ @list.last
48
+ end
49
+
50
+ # A sorted list of the unique authors in the contained comments
51
+ # @return [Array]
52
+ def authors
53
+ @list.map { |comment| comment.author.to_s }.uniq.sort
54
+ end
55
+
56
+ # The relationships required by this object
57
+ # @return [Array]
58
+ def relationships
59
+ [Relationship.new(VML_DRAWING_R, "../#{vml_drawing.pn}"),
60
+ Relationship.new(COMMENT_R, "../#{pn}"),
61
+ Relationship.new(COMMENT_R_NULL, "NULL")]
62
+ end
63
+
64
+ # serialize the object
65
+ # @param [String] str
66
+ # @return [String]
67
+ def to_xml_string(str="")
68
+ str << '<?xml version="1.0" encoding="UTF-8"?>'
69
+ str << '<comments xmlns="' << XML_NS << '">'
70
+ str << '<authors>'
71
+ authors.each do |author|
72
+ str << '<author>' << author.to_s << '</author>'
73
+ end
74
+ str << '</authors>'
75
+ str << '<commentList>'
76
+ @list.each do |comment|
77
+ comment.to_xml_string str
78
+ end
79
+ str << '</commentList></comments>'
80
+
81
+ end
82
+
83
+ end
84
+
85
+ end
@@ -0,0 +1,25 @@
1
+ module Axlsx
2
+
3
+ # A simple, self serializing class for storing conditional formattings
4
+ class ConditionalFormattings < SimpleTypedList
5
+
6
+ # creates a new Tables object
7
+ def initialize(worksheet)
8
+ raise ArgumentError, "you must provide a worksheet" unless worksheet.is_a?(Worksheet)
9
+ super ConditionalFormatting
10
+ @worksheet = worksheet
11
+ end
12
+
13
+ # The worksheet that owns this collection of tables
14
+ # @return [Worksheet]
15
+ attr_reader :worksheet
16
+
17
+ # serialize the conditional formattings
18
+ def to_xml_string(str = "")
19
+ return if empty?
20
+ each { |item| item.to_xml_string(str) }
21
+ end
22
+ end
23
+
24
+ end
25
+
@@ -65,7 +65,7 @@ module Axlsx
65
65
  def showValue=(v); Axlsx.validate_boolean(v); @showValue = v end
66
66
 
67
67
  # Sets the color for the data bars.
68
- # @param [Color|String] The color object, or rgb string value to apply
68
+ # @param [Color|String] v The color object, or rgb string value to apply
69
69
  def color=(v)
70
70
  @color = v if v.is_a? Color
71
71
  self.color.rgb = v if v.is_a? String
@@ -0,0 +1,245 @@
1
+ # encoding: UTF-8
2
+ module Axlsx
3
+ # Data validation allows the validation of cell data
4
+ #
5
+ # @note The recommended way to manage data validations is via Worksheet#add_data_validation
6
+ # @see Worksheet#add_data_validation
7
+ class DataValidation
8
+
9
+ # instance values that must be serialized as their own elements - e.g. not attributes.
10
+ CHILD_ELEMENTS = [:formula1, :formula2]
11
+
12
+ # Formula1
13
+ # Available for type whole, decimal, date, time, textLength, list, custom
14
+ # @see type
15
+ # @return [String]
16
+ # default nil
17
+ attr_reader :formula1
18
+
19
+ # Formula2
20
+ # Available for type whole, decimal, date, time, textLength
21
+ # @see type
22
+ # @return [String]
23
+ # default nil
24
+ attr_reader :formula2
25
+
26
+ # Allow Blank
27
+ # A boolean value indicating whether the data validation allows the use of empty or blank
28
+ # entries. 1 means empty entries are OK and do not violate the validation constraints.
29
+ # Available for type whole, decimal, date, time, textLength, list, custom
30
+ # @see type
31
+ # @return [Boolean]
32
+ # default true
33
+ attr_reader :allowBlank
34
+
35
+ # Error Message
36
+ # Message text of error alert.
37
+ # Available for type whole, decimal, date, time, textLength, list, custom
38
+ # @see type
39
+ # @return [String]
40
+ # default nil
41
+ attr_reader :error
42
+
43
+ # Error Style (ST_DataValidationErrorStyle)
44
+ # The style of error alert used for this data validation.
45
+ # Options are:
46
+ # * information: This data validation error style uses an information icon in the error alert.
47
+ # * stop: This data validation error style uses a stop icon in the error alert.
48
+ # * warning: This data validation error style uses a warning icon in the error alert.
49
+ # Available for type whole, decimal, date, time, textLength, list, custom
50
+ # @see type
51
+ # @return [Symbol]
52
+ # default :stop
53
+ attr_reader :errorStyle
54
+
55
+ # Error Title
56
+ # Title bar text of error alert.
57
+ # Available for type whole, decimal, date, time, textLength, list, custom
58
+ # @see type
59
+ # @return [String]
60
+ # default nil
61
+ attr_reader :errorTitle
62
+
63
+ # Operator (ST_DataValidationOperator)
64
+ # The relational operator used with this data validation.
65
+ # Options are:
66
+ # * between: Data validation which checks if a value is between two other values.
67
+ # * equal: Data validation which checks if a value is equal to a specified value.
68
+ # * greater_than: Data validation which checks if a value is greater than a specified value.
69
+ # * greater_than_or_equal: Data validation which checks if a value is greater than or equal to a specified value.
70
+ # * less_than: Data validation which checks if a value is less than a specified value.
71
+ # * less_than_or_equal: Data validation which checks if a value is less than or equal to a specified value.
72
+ # * not_between: Data validation which checks if a value is not between two other values.
73
+ # * not_equal: Data validation which checks if a value is not equal to a specified value.
74
+ # Available for type whole, decimal, date, time, textLength
75
+ # @see type
76
+ # @return [Symbol]
77
+ # default nil
78
+ attr_reader :operator
79
+
80
+ # Input prompt
81
+ # Message text of input prompt.
82
+ # Available for type whole, decimal, date, time, textLength, list, custom
83
+ # @see type
84
+ # @return [String]
85
+ # default nil
86
+ attr_reader :prompt
87
+
88
+ # Prompt title
89
+ # Title bar text of input prompt.
90
+ # Available for type whole, decimal, date, time, textLength, list, custom
91
+ # @see type
92
+ # @return [String]
93
+ # default nil
94
+ attr_reader :promptTitle
95
+
96
+ # Show drop down
97
+ # A boolean value indicating whether to display a dropdown combo box for a list type data
98
+ # validation. Be careful: false shows the dropdown list!
99
+ # Available for type list
100
+ # @see type
101
+ # @return [Boolean]
102
+ # default false
103
+ attr_reader :showDropDown
104
+
105
+ # Show error message
106
+ # A boolean value indicating whether to display the error alert message when an invalid
107
+ # value has been entered, according to the criteria specified.
108
+ # Available for type whole, decimal, date, time, textLength, list, custom
109
+ # @see type
110
+ # @return [Boolean]
111
+ # default false
112
+ attr_reader :showErrorMessage
113
+
114
+ # Show input message
115
+ # A boolean value indicating whether to display the input prompt message.
116
+ # Available for type whole, decimal, date, time, textLength, list, custom
117
+ # @see type
118
+ # @return [Boolean]
119
+ # default false
120
+ attr_reader :showInputMessage
121
+
122
+ # Range over which data validation is applied, in "A1:B2" format
123
+ # Available for type whole, decimal, date, time, textLength, list, custom
124
+ # @see type
125
+ # @return [String]
126
+ # default nil
127
+ attr_reader :sqref
128
+
129
+ # The type (ST_DataValidationType) of data validation.
130
+ # Options are:
131
+ # * custom: Data validation which uses a custom formula to check the cell value.
132
+ # * date: Data validation which checks for date values satisfying the given condition.
133
+ # * decimal: Data validation which checks for decimal values satisfying the given condition.
134
+ # * list: Data validation which checks for a value matching one of list of values.
135
+ # * none: No data validation.
136
+ # * textLength: Data validation which checks for text values, whose length satisfies the given condition.
137
+ # * time: Data validation which checks for time values satisfying the given condition.
138
+ # * whole: Data validation which checks for whole number values satisfying the given condition.
139
+ # @return [Symbol]
140
+ # default none
141
+ attr_reader :type
142
+
143
+ # Creates a new {DataValidation} object
144
+ # @option options [String] formula1
145
+ # @option options [String] formula2
146
+ # @option options [Boolean] allowBlank - A boolean value indicating whether the data validation allows the use of empty or blank entries.
147
+ # @option options [String] error - Message text of error alert.
148
+ # @option options [Symbol] errorStyle - The style of error alert used for this data validation.
149
+ # @option options [String] errorTitle - itle bar text of error alert.
150
+ # @option options [Symbol] operator - The relational operator used with this data validation.
151
+ # @option options [String] prompt - Message text of input prompt.
152
+ # @option options [String] promptTitle - Title bar text of input prompt.
153
+ # @option options [Boolean] showDropDown - A boolean value indicating whether to display a dropdown combo box for a list type data validation
154
+ # @option options [Boolean] showErrorMessage - A boolean value indicating whether to display the error alert message when an invalid value has been entered, according to the criteria specified.
155
+ # @option options [Boolean] showInputMessage - A boolean value indicating whether to display the input prompt message.
156
+ # @option options [String] sqref - Range over which data validation is applied, in "A1:B2" format.
157
+ # @option options [Symbol] type - The type of data validation.
158
+ def initialize(options={})
159
+ # defaults
160
+ @formula1 = @formula2 = @error = @errorTitle = @operator = @prompt = @promptTitle = @sqref = nil
161
+ @allowBlank = @showErrorMessage = true
162
+ @showDropDown = @showInputMessage = false
163
+ @type = :none
164
+ @errorStyle = :stop
165
+
166
+ options.each do |o|
167
+ self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
168
+ end
169
+ end
170
+
171
+ # @see formula1
172
+ def formula1=(v); Axlsx::validate_string(v); @formula1 = v end
173
+
174
+ # @see formula2
175
+ def formula2=(v); Axlsx::validate_string(v); @formula2 = v end
176
+
177
+ # @see allowBlank
178
+ def allowBlank=(v); Axlsx::validate_boolean(v); @allowBlank = v end
179
+
180
+ # @see error
181
+ def error=(v); Axlsx::validate_string(v); @error = v end
182
+
183
+ # @see errorStyle
184
+ def errorStyle=(v); Axlsx::validate_data_validation_error_style(v); @errorStyle = v end
185
+
186
+ # @see errorTitle
187
+ def errorTitle=(v); Axlsx::validate_string(v); @errorTitle = v end
188
+
189
+ # @see operator
190
+ def operator=(v); Axlsx::validate_data_validation_operator(v); @operator = v end
191
+
192
+ # @see prompt
193
+ def prompt=(v); Axlsx::validate_string(v); @prompt = v end
194
+
195
+ # @see promptTitle
196
+ def promptTitle=(v); Axlsx::validate_string(v); @promptTitle = v end
197
+
198
+ # @see showDropDown
199
+ def showDropDown=(v); Axlsx::validate_boolean(v); @showDropDown = v end
200
+
201
+ # @see showErrorMessage
202
+ def showErrorMessage=(v); Axlsx::validate_boolean(v); @showErrorMessage = v end
203
+
204
+ # @see showInputMessage
205
+ def showInputMessage=(v); Axlsx::validate_boolean(v); @showInputMessage = v end
206
+
207
+ # @see sqref
208
+ def sqref=(v); Axlsx::validate_string(v); @sqref = v end
209
+
210
+ # @see type
211
+ def type=(v); Axlsx::validate_data_validation_type(v); @type = v end
212
+
213
+ # Serializes the data validation
214
+ # @param [String] str
215
+ # @return [String]
216
+ def to_xml_string(str = '')
217
+ valid_attributes = get_valid_attributes
218
+
219
+ str << '<dataValidation '
220
+ str << instance_values.map { |key, value| '' << key << '="' << value.to_s << '"' if (valid_attributes.include?(key.to_sym) and not CHILD_ELEMENTS.include?(key.to_sym)) }.join(' ')
221
+ str << '>'
222
+ str << '<formula1>' << self.formula1 << '</formula1>' if @formula1 and valid_attributes.include?(:formula1)
223
+ str << '<formula2>' << self.formula2 << '</formula2>' if @formula2 and valid_attributes.include?(:formula2)
224
+ str << '</dataValidation>'
225
+ end
226
+
227
+ private
228
+ def get_valid_attributes
229
+ attributes = [:allowBlank, :error, :errorStyle, :errorTitle, :prompt, :promptTitle, :showErrorMessage, :showInputMessage, :sqref, :type ]
230
+
231
+ if [:whole, :decimal, :data, :time, :textLength].include?(@type)
232
+ attributes << [:operator, :formula1]
233
+ attributes << [:formula2] if [:between, :notBetween].include?(@operator)
234
+ elsif @type == :list
235
+ attributes << [:showDropDown, :formula1]
236
+ elsif @type == :custom
237
+ attributes << [:formula1]
238
+ else
239
+ attributes = []
240
+ end
241
+
242
+ attributes.flatten!
243
+ end
244
+ end
245
+ end
@@ -0,0 +1,28 @@
1
+ module Axlsx
2
+
3
+ # A simple, self serializing class for storing conditional formattings
4
+ class DataValidations < SimpleTypedList
5
+
6
+ # creates a new Tables object
7
+ def initialize(worksheet)
8
+ raise ArgumentError, "you must provide a worksheet" unless worksheet.is_a?(Worksheet)
9
+ super DataValidation
10
+ @worksheet = worksheet
11
+ end
12
+
13
+ # The worksheet that owns this collection of tables
14
+ # @return [Worksheet]
15
+ attr_reader :worksheet
16
+
17
+ # serialize the conditional formattings
18
+ def to_xml_string(str = "")
19
+ return if empty?
20
+ str << "<dataValidations count='#{size}'>"
21
+ each { |item| item.to_xml_string(str) }
22
+ str << '</dataValidations>'
23
+ end
24
+ end
25
+
26
+ end
27
+
28
+