axlsx 1.1.4 → 1.1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. data/README.md +10 -3
  2. data/Rakefile +7 -1
  3. data/examples/chart_colors.rb +1 -1
  4. data/examples/chart_colors.xlsx +0 -0
  5. data/examples/doc/_index.html +84 -0
  6. data/examples/doc/class_list.html +47 -0
  7. data/examples/doc/css/common.css +1 -0
  8. data/examples/doc/css/full_list.css +55 -0
  9. data/examples/doc/css/style.css +322 -0
  10. data/examples/doc/file_list.html +46 -0
  11. data/examples/doc/frames.html +13 -0
  12. data/examples/doc/index.html +84 -0
  13. data/examples/doc/js/app.js +205 -0
  14. data/examples/doc/js/full_list.js +173 -0
  15. data/examples/doc/js/jquery.js +16 -0
  16. data/examples/doc/method_list.html +46 -0
  17. data/examples/doc/top-level-namespace.html +95 -0
  18. data/examples/example.rb +12 -5
  19. data/examples/example.xlsx +0 -0
  20. data/examples/example_streamed.xlsx +0 -0
  21. data/examples/extractive.rb +3 -0
  22. data/lib/axlsx.rb +4 -4
  23. data/lib/axlsx/drawing/drawing.rb +7 -2
  24. data/lib/axlsx/drawing/graphic_frame.rb +2 -1
  25. data/lib/axlsx/drawing/num_data_source.rb +3 -0
  26. data/lib/axlsx/drawing/vml_drawing.rb +42 -0
  27. data/lib/axlsx/drawing/vml_drawing.rb~ +6 -0
  28. data/lib/axlsx/drawing/vml_shape.rb +128 -0
  29. data/lib/axlsx/drawing/vml_shape.rb~ +61 -0
  30. data/lib/axlsx/package.rb +24 -0
  31. data/lib/axlsx/rels/relationships.rb +0 -10
  32. data/lib/axlsx/stylesheet/gradient_fill.rb +1 -1
  33. data/lib/axlsx/util/constants.rb +24 -0
  34. data/lib/axlsx/util/validators.rb +32 -4
  35. data/lib/axlsx/version.rb +1 -1
  36. data/lib/axlsx/workbook/workbook.rb +21 -0
  37. data/lib/axlsx/workbook/worksheet/cell.rb +4 -2
  38. data/lib/axlsx/workbook/worksheet/comment.rb +107 -0
  39. data/lib/axlsx/workbook/worksheet/comment.rb~ +91 -0
  40. data/lib/axlsx/workbook/worksheet/comments.rb +77 -0
  41. data/lib/axlsx/workbook/worksheet/comments.rb~ +86 -0
  42. data/lib/axlsx/workbook/worksheet/page_setup.rb +90 -0
  43. data/lib/axlsx/workbook/worksheet/print_options.rb +63 -0
  44. data/lib/axlsx/workbook/worksheet/row.rb +2 -2
  45. data/lib/axlsx/workbook/worksheet/worksheet.rb +72 -9
  46. data/test/doc_props/tc_core.rb +3 -1
  47. data/test/drawing/tc_hyperlink.rb +4 -0
  48. data/test/drawing/tc_line_series.rb +6 -2
  49. data/test/drawing/tc_pie_series.rb +6 -1
  50. data/test/drawing/tc_vml_drawing.rb +25 -0
  51. data/{examples/#extractive.csv# → test/drawing/tc_vml_drawing.rb~} +0 -0
  52. data/test/drawing/tc_vml_shape.rb +100 -0
  53. data/test/rels/tc_relationship.rb +1 -0
  54. data/test/stylesheet/tc_gradient_fill.rb +8 -0
  55. data/test/stylesheet/tc_pattern_fill.rb +7 -1
  56. data/test/tc_helper.rb +1 -0
  57. data/test/tc_package.rb +16 -5
  58. data/test/util/tc_validators.rb +29 -0
  59. data/test/workbook/worksheet/tc_cell.rb +17 -0
  60. data/test/workbook/worksheet/tc_comment.rb +56 -0
  61. data/test/workbook/worksheet/tc_comments.rb +50 -0
  62. data/test/workbook/worksheet/tc_page_setup.rb +103 -0
  63. data/test/workbook/worksheet/tc_print_options.rb +72 -0
  64. data/test/workbook/worksheet/tc_row.rb +19 -13
  65. data/test/workbook/worksheet/tc_worksheet.rb +60 -7
  66. metadata +56 -24
  67. data/examples/#extractive.rb# +0 -45
  68. data/examples/chart_colors.rb~ +0 -0
  69. data/examples/colored_series_data.xlsx +0 -0
  70. data/examples/example.csv +0 -1000
  71. data/examples/extractive.csv +0 -1
  72. data/examples/extractive.csv~ +0 -1
  73. data/examples/extractive.rb~ +0 -3
  74. data/examples/extractive.xlsx +0 -0
  75. data/examples/no-use_autowidth.xlsx +0 -0
  76. data/examples/shared_strings_example.xlsx +0 -0
  77. data/examples/stack.rb +0 -21
  78. data/examples/stack.rb~ +0 -27
  79. data/examples/stack.xlsx +0 -0
  80. data/examples/~$chart_colors.xlsx +0 -0
  81. data/examples/~$extractive.xlsx +0 -0
@@ -0,0 +1,61 @@
1
+ module Axlsx
2
+ class VmlShape
3
+
4
+ attr_reader :row
5
+
6
+ attr_reader :column
7
+
8
+ attr_reader :left_column
9
+ attr_reader :left_offset
10
+ attr_reader :top_row
11
+ attr_reader :top_offset
12
+ attr_reader :right_column
13
+ attr_reader :right_offset
14
+ attr_reader :bottom_row
15
+ attr_reader :bottom_offset
16
+
17
+ def initialize(comment, options={})
18
+ @row = @column = 0
19
+ @left_column = 0
20
+ @left_offset = 15
21
+ @top_row = 0
22
+ @top_offset = 2
23
+ @right_column = 0
24
+ @right_offset = 50
25
+ @bottom_row = 0
26
+ @bottom_offset = 5
27
+ options.each do |o|
28
+ self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
29
+ end
30
+
31
+
32
+ end
33
+
34
+ def xml_to_string(str ='') str << <<SHAME_ON_YOU
35
+
36
+ <v:shape id="_x0000_s#{@comments.worksheet.index+1}07#{index+1}" type="#_x0000_t202"
37
+ style='position:absolute;margin-left:104pt;margin-top:2pt;width:800px;height:27pt;z-index:1;mso-wrap-style:tight'
38
+ fillcolor="#ffffa1 [80]" o:insetmode="auto">
39
+ <v:fill color2="#ffffa1 [80]"/>
40
+ <v:shadow on="t" obscured="t"/>
41
+ <v:path o:connecttype="none"/>
42
+ <v:textbox style='mso-fit-text-with-word-wrap:t'>
43
+ <div style='text-align:left'></div>
44
+ </v:textbox>
45
+
46
+ <x:ClientData ObjectType="Note">
47
+ <x:MoveWithCells/>
48
+ <x:SizeWithCells/>
49
+ # LeftColumn, LeftOffset, TopRow, TopOffset, RightColumn, RightOffset, BottomRow, BottomOffset.
50
+ <x:Anchor>#{comment.comments.worksheet[comment.ref].index + 1}, 15, #{comment.comments.worksheet[comment.ref].row.index}, 2, #{comment.comments.worksheet[comment.ref].index + 5}, 50, #{comment.comments.worksheet[comment.ref].row.index + 5}, 5</x:Anchor>
51
+ <x:AutoFill>False</x:AutoFill>
52
+ <x:Row>#{comment.comments.worksheet[comment.ref].row.index}</x:Row>
53
+ <x:Column>#{comment.comments.worksheet[comment.ref].index}</x:Column>
54
+ <x:Visible/>
55
+ </x:ClientData>
56
+ </v:shape>
57
+ SHAME_ON_YOU
58
+
59
+ end
60
+ end
61
+ end
@@ -180,15 +180,24 @@ module Axlsx
180
180
  {:entry => CONTENT_TYPES_PN, :doc => content_types.to_xml_string, :schema => CONTENT_TYPES_XSD},
181
181
  {:entry => WORKBOOK_PN, :doc => workbook.to_xml_string, :schema => SML_XSD}
182
182
  ]
183
+
183
184
  workbook.drawings.each do |drawing|
184
185
  @parts << {:entry => "xl/#{drawing.rels_pn}", :doc => drawing.relationships.to_xml_string, :schema => RELS_XSD}
185
186
  @parts << {:entry => "xl/#{drawing.pn}", :doc => drawing.to_xml_string, :schema => DRAWING_XSD}
186
187
  end
187
188
 
189
+
188
190
  workbook.tables.each do |table|
189
191
  @parts << {:entry => "xl/#{table.pn}", :doc => table.to_xml_string, :schema => SML_XSD}
190
192
  end
191
193
 
194
+ workbook.comments.each do|comment|
195
+ if comment.size > 0
196
+ @parts << { :entry => "xl/#{comment.pn}", :doc => comment.to_xml_string, :schema => SML_XSD }
197
+ @parts << { :entry => "xl/#{comment.vml_drawing.pn}", :doc => comment.vml_drawing.to_xml_string, :schema => nil }
198
+ end
199
+ end
200
+
192
201
  workbook.charts.each do |chart|
193
202
  @parts << {:entry => "xl/#{chart.pn}", :doc => chart.to_xml_string, :schema => DRAWING_XSD}
194
203
  end
@@ -229,18 +238,33 @@ module Axlsx
229
238
  # @private
230
239
  def content_types
231
240
  c_types = base_content_types
241
+
232
242
  workbook.drawings.each do |drawing|
233
243
  c_types << Axlsx::Override.new(:PartName => "/xl/#{drawing.pn}",
234
244
  :ContentType => DRAWING_CT)
235
245
  end
246
+
236
247
  workbook.charts.each do |chart|
237
248
  c_types << Axlsx::Override.new(:PartName => "/xl/#{chart.pn}",
238
249
  :ContentType => CHART_CT)
239
250
  end
251
+
240
252
  workbook.tables.each do |table|
241
253
  c_types << Axlsx::Override.new(:PartName => "/xl/#{table.pn}",
242
254
  :ContentType => TABLE_CT)
243
255
  end
256
+
257
+ workbook.comments.each do |comment|
258
+ if comment.size > 0
259
+ c_types << Axlsx::Override.new(:PartName => "/xl/#{comment.pn}",
260
+ :ContentType => COMMENT_CT)
261
+ end
262
+ end
263
+
264
+ if workbook.comments.size > 0
265
+ c_types << Axlsx::Default.new(:Extension => "vml", :ContentType => VML_DRAWING_CT)
266
+ end
267
+
244
268
  workbook.worksheets.each do |sheet|
245
269
  c_types << Axlsx::Override.new(:PartName => "/xl/#{sheet.pn}",
246
270
  :ContentType => WORKSHEET_CT)
@@ -17,16 +17,6 @@ require 'axlsx/rels/relationship.rb'
17
17
  each_with_index { |rel, index| rel.to_xml_string(index+1, str) }
18
18
  str << '</Relationships>'
19
19
  end
20
- # Serializes the relationships document.
21
- # @return [String]
22
- def to_xml()
23
- builder = Nokogiri::XML::Builder.new(:encoding => ENCODING) do |xml|
24
- xml.Relationships(:xmlns => Axlsx::RELS_R) {
25
- each_with_index { |rel, index| rel.to_xml(xml, "rId#{index+1}") }
26
- }
27
- end
28
- builder.to_xml(:save_with => 0)
29
- end
30
20
 
31
21
  end
32
22
  end
@@ -68,7 +68,7 @@ module Axlsx
68
68
  # @param [String] str
69
69
  # @return [String]
70
70
  def to_xml_string(str = '')
71
- str << '<gradientFill'
71
+ str << '<gradientFill '
72
72
  h = self.instance_values.reject { |k,v| k.to_sym == :stop }
73
73
  str << h.map { |key, value| '' << key.to_s << '="' << value.to_s << '"' }.join(' ')
74
74
  str << '>'
@@ -79,6 +79,18 @@ module Axlsx
79
79
  # image rels namespace
80
80
  HYPERLINK_R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"
81
81
 
82
+ # comment rels namespace
83
+ COMMENT_R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments"
84
+
85
+ # comment relation for nil target
86
+ COMMENT_R_NULL = "http://purl.oclc.org/ooxml/officeDocument/relationships/comments"
87
+
88
+ #vml drawing relation namespace
89
+ VML_DRAWING_R = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing'
90
+
91
+ # VML Drawing content type
92
+ VML_DRAWING_CT = "application/vnd.openxmlformats-officedocument.vmlDrawing"
93
+
82
94
  # table content type
83
95
  TABLE_CT = "application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml"
84
96
 
@@ -109,6 +121,9 @@ module Axlsx
109
121
  # chart content type
110
122
  CHART_CT = "application/vnd.openxmlformats-officedocument.drawingml.chart+xml"
111
123
 
124
+ # comments content type
125
+ COMMENT_CT = "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml"
126
+
112
127
  # jpeg content type
113
128
  JPEG_CT = "image/jpeg"
114
129
 
@@ -172,6 +187,9 @@ module Axlsx
172
187
  # drawing rels part
173
188
  DRAWING_RELS_PN = "drawings/_rels/drawing%d.xml.rels"
174
189
 
190
+ # vml drawing part
191
+ VML_DRAWING_PN = "drawings/vmlDrawing%d.vml"
192
+
175
193
  # drawing part
176
194
  TABLE_PN = "tables/table%d.xml"
177
195
 
@@ -181,6 +199,9 @@ module Axlsx
181
199
  # chart part
182
200
  IMAGE_PN = "media/image%d.%s"
183
201
 
202
+ # comment part
203
+ COMMENT_PN = "comments%d.xml"
204
+
184
205
  # location of schema files for validation
185
206
  SCHEMA_BASE = File.dirname(__FILE__)+'/../../schema/'
186
207
 
@@ -240,4 +261,7 @@ module Axlsx
240
261
 
241
262
  # error message for invalid angles
242
263
  ERR_ANGLE = "Angles must be a value between -90 and 90. You provided: %s"
264
+
265
+ # error message for non 'integerish' value
266
+ ERR_INTEGERISH = "You value must be, or be castable via to_i, an Integer. You provided %s"
243
267
  end
@@ -45,8 +45,20 @@ module Axlsx
45
45
  true
46
46
  end
47
47
 
48
+
49
+ # Requires that the value can be converted to an integer
50
+ # @para, [Any] v the value to validate
51
+ # @raise [ArgumentError] raised if the value cannot be converted to an integer
52
+ def self.validate_integerish(v)
53
+ raise ArgumentError, (ERR_INTEGERISH % v.inspect) unless (v.respond_to?(:to_i) && v.to_i.is_a?(Integer))
54
+ end
55
+
56
+ # Requires that the value is between -54000000 and 54000000
57
+ # @param [Any] v The value validated
58
+ # @raise [ArgumentError] raised if the value cannot be converted to an integer between the allowed angle values for chart label rotation.
59
+ # @return [Boolean] true if the data is valid
48
60
  def self.validate_angle(v)
49
- raise ArgumentError, (ERR_ANGLE % v.inspect) unless (v >= -5400000 && v <= 5400000)
61
+ raise ArgumentError, (ERR_ANGLE % v.inspect) unless (v.to_i >= -5400000 && v.to_i <= 5400000)
50
62
  end
51
63
  # Requires that the value is a Fixnum or Integer and is greater or equal to 0
52
64
  # @param [Any] v The value validated
@@ -90,6 +102,22 @@ module Axlsx
90
102
  DataTypeValidator.validate :float, Float, v
91
103
  end
92
104
 
105
+ # Requires that the value is a string containing a positive decimal number followed by one of the following units:
106
+ # "mm", "cm", "in", "pt", "pc", "pi"
107
+ def self.validate_number_with_unit(v)
108
+ RegexValidator.validate "number_with_unit", /\A[0-9]+(\.[0-9]+)?(mm|cm|in|pt|pc|pi)\Z/, v
109
+ end
110
+
111
+ # Requires that the value is an integer ranging from 10 to 400.
112
+ def self.validate_page_scale(v)
113
+ DataTypeValidator.validate "page_scale", [Fixnum, Integer], v, lambda { |arg| arg >= 10 && arg <= 400 }
114
+ end
115
+
116
+ # Requires that the value is one of :default, :landscape, or :portrait.
117
+ def self.validate_page_orientation(v)
118
+ RestrictionValidator.validate "page_orientation", [:default, :landscape, :portrait], v
119
+ end
120
+
93
121
  # Requires that the value is valid pattern type.
94
122
  # valid pattern types must be one of :none, :solid, :mediumGray, :darkGray, :lightGray, :darkHorizontal, :darkVertical, :darkDown,
95
123
  # :darkUp, :darkGrid, :darkTrellis, :lightHorizontal, :lightVertical, :lightDown, :lightUp, :lightGrid, :lightTrellis, :gray125, or :gray0625.
@@ -169,17 +197,17 @@ module Axlsx
169
197
  end
170
198
 
171
199
  # Requires that the value is a valid content_type
172
- # TABLE_CT, WORKBOOK_CT, APP_CT, RELS_CT, STYLES_CT, XML_CT, WORKSHEET_CT, SHARED_STRINGS_CT, CORE_CT, CHART_CT, DRAWING_CT are allowed
200
+ # TABLE_CT, WORKBOOK_CT, APP_CT, RELS_CT, STYLES_CT, XML_CT, WORKSHEET_CT, SHARED_STRINGS_CT, CORE_CT, CHART_CT, DRAWING_CT, COMMENT_CT are allowed
173
201
  # @param [Any] v The value validated
174
202
  def self.validate_content_type(v)
175
- RestrictionValidator.validate :content_type, [TABLE_CT, WORKBOOK_CT, APP_CT, RELS_CT, STYLES_CT, XML_CT, WORKSHEET_CT, SHARED_STRINGS_CT, CORE_CT, CHART_CT, JPEG_CT, GIF_CT, PNG_CT, DRAWING_CT], v
203
+ RestrictionValidator.validate :content_type, [TABLE_CT, WORKBOOK_CT, APP_CT, RELS_CT, STYLES_CT, XML_CT, WORKSHEET_CT, SHARED_STRINGS_CT, CORE_CT, CHART_CT, JPEG_CT, GIF_CT, PNG_CT, DRAWING_CT, COMMENT_CT, VML_DRAWING_CT], v
176
204
  end
177
205
 
178
206
  # Requires that the value is a valid relationship_type
179
207
  # XML_NS_R, TABLE_R, WORKBOOK_R, WORKSHEET_R, APP_R, RELS_R, CORE_R, STYLES_R, CHART_R, DRAWING_R, IMAGE_R, HYPERLINK_R, SHARED_STRINGS_R are allowed
180
208
  # @param [Any] v The value validated
181
209
  def self.validate_relationship_type(v)
182
- RestrictionValidator.validate :relationship_type, [XML_NS_R, TABLE_R, WORKBOOK_R, WORKSHEET_R, APP_R, RELS_R, CORE_R, STYLES_R, CHART_R, DRAWING_R, IMAGE_R, HYPERLINK_R, SHARED_STRINGS_R], v
210
+ RestrictionValidator.validate :relationship_type, [XML_NS_R, TABLE_R, WORKBOOK_R, WORKSHEET_R, APP_R, RELS_R, CORE_R, STYLES_R, CHART_R, DRAWING_R, IMAGE_R, HYPERLINK_R, SHARED_STRINGS_R, COMMENT_R, VML_DRAWING_R, COMMENT_R_NULL], v
183
211
  end
184
212
 
185
213
  # Requires that the value is a valid table element type
@@ -5,6 +5,6 @@ module Axlsx
5
5
  # When using bunle exec rake and referencing the gem on github or locally
6
6
  # it will use the gemspec, which preloads this constant for the gem's version.
7
7
  # We check to make sure that it has not already been loaded
8
- VERSION="1.1.4" unless defined? Axlsx::VERSION
8
+ VERSION="1.1.5" unless defined? Axlsx::VERSION
9
9
 
10
10
  end
@@ -4,6 +4,8 @@ module Axlsx
4
4
  require 'axlsx/workbook/worksheet/date_time_converter.rb'
5
5
  require 'axlsx/workbook/worksheet/cell.rb'
6
6
  require 'axlsx/workbook/worksheet/page_margins.rb'
7
+ require 'axlsx/workbook/worksheet/page_setup.rb'
8
+ require 'axlsx/workbook/worksheet/print_options.rb'
7
9
  require 'axlsx/workbook/worksheet/cfvo.rb'
8
10
  require 'axlsx/workbook/worksheet/color_scale.rb'
9
11
  require 'axlsx/workbook/worksheet/data_bar.rb'
@@ -12,6 +14,8 @@ require 'axlsx/workbook/worksheet/conditional_formatting.rb'
12
14
  require 'axlsx/workbook/worksheet/conditional_formatting_rule.rb'
13
15
  require 'axlsx/workbook/worksheet/row.rb'
14
16
  require 'axlsx/workbook/worksheet/col.rb'
17
+ require 'axlsx/workbook/worksheet/comments.rb'
18
+ require 'axlsx/workbook/worksheet/comment.rb'
15
19
  require 'axlsx/workbook/worksheet/worksheet.rb'
16
20
  require 'axlsx/workbook/shared_strings_table.rb'
17
21
  require 'axlsx/workbook/worksheet/table.rb'
@@ -82,6 +86,9 @@ require 'axlsx/workbook/worksheet/table.rb'
82
86
  # @return [SimpleTypedList]
83
87
  attr_reader :drawings
84
88
 
89
+ # pretty sure this two are always empty and can be removed.
90
+
91
+
85
92
  # A colllection of tables associated with this workbook
86
93
  # @note The recommended way to manage drawings is Worksheet#add_table
87
94
  # @see Worksheet#add_table
@@ -90,6 +97,15 @@ require 'axlsx/workbook/worksheet/table.rb'
90
97
  attr_reader :tables
91
98
 
92
99
 
100
+ # A colllection of comments associated with this workbook
101
+ # @note The recommended way to manage comments is Worksheet#add_comment
102
+ # @see Worksheet#add_comment
103
+ # @see Comment
104
+ # @return [Comments]
105
+ def comments
106
+ self.worksheets.map { |ws| ws.comments }.compact
107
+ end
108
+
93
109
  # The styles associated with this workbook
94
110
  # @note The recommended way to manage styles is Styles#add_style
95
111
  # @see Style#add_style
@@ -123,7 +139,12 @@ require 'axlsx/workbook/worksheet/table.rb'
123
139
  @drawings = SimpleTypedList.new Drawing
124
140
  @charts = SimpleTypedList.new Chart
125
141
  @images = SimpleTypedList.new Pic
142
+
143
+ # Are these even used????? Check package serialization parts
126
144
  @tables = SimpleTypedList.new Table
145
+ @comments = SimpleTypedList.new Comments
146
+
147
+
127
148
  @use_autowidth = true
128
149
 
129
150
  self.date1904= !options[:date1904].nil? && options[:date1904]
@@ -288,13 +288,15 @@ module Axlsx
288
288
  # @param [String] str The string index the cell content will be appended to. Defaults to empty string.
289
289
  # @return [String] xml text for the cell
290
290
  def to_xml_string(r_index, c_index, str = '')
291
- return str if @value.nil?
292
291
  str << '<c r="' << Axlsx::cell_r(c_index, r_index) << '" s="' << @style.to_s << '" '
292
+ return str << '/>' if @value.nil?
293
+
293
294
  case @type
295
+
294
296
  when :string
295
297
  #parse formula
296
298
  if @value.start_with?('=')
297
- str << 't="str"><f>' << @value.to_s.gsub('=', '') << '</f>'
299
+ str << 't="str"><f>' << @value.to_s.sub('=', '') << '</f>'
298
300
  else
299
301
  #parse shared
300
302
  if @ssti
@@ -0,0 +1,107 @@
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
+ # The index of this comment
45
+ # @return [Integer]
46
+ def index
47
+ @comments.index(self)
48
+ end
49
+
50
+ #
51
+ # The index of this author in a unique sorted list of all authors in
52
+ # the comment.
53
+ # @return [Integer]
54
+ def author_index
55
+ @comments.authors.index(author)
56
+ end
57
+
58
+ # @see ref
59
+ def ref=(v)
60
+ Axlsx::DataTypeValidator.validate "Comment.ref", [String, Cell], v
61
+ @ref = v if v.is_a?(String)
62
+ @ref = v.r if v.is_a?(Cell)
63
+ end
64
+
65
+ # @see text
66
+ def text=(v)
67
+ Axlsx::validate_string(v)
68
+ @text = v
69
+ end
70
+
71
+ # @see author
72
+ def author=(v)
73
+ @author = v
74
+ end
75
+
76
+ # serialize the object
77
+ # @param [String] str
78
+ # @return [String]
79
+ def to_xml_string(str = "")
80
+ author = @comments.authors[author_index]
81
+ str << '<comment ref="' << ref << '" authorId="' << author_index.to_s << '">'
82
+ str << '<text><r>'
83
+ str << '<rPr> <b/><color indexed="81"/></rPr>'
84
+ str << '<t>' << author.to_s << ':
85
+ </t></r>'
86
+ str << '<r>'
87
+ str << '<rPr><color indexed="81"/></rPr>'
88
+ str << '<t>' << text << '</t></r></text>'
89
+ str << '</comment>'
90
+ end
91
+
92
+ private
93
+
94
+ # initialize the vml shape based on this comment's ref/position in the worksheet.
95
+ # by default, all columns are 5 columns wide and 5 rows high
96
+ def initialize_vml_shape
97
+ pos = Axlsx::name_to_indices(ref)
98
+ @vml_shape = VmlShape.new(:row => pos[1], :column => pos[0]) do |vml|
99
+ vml.left_column = vml.row + 1
100
+ vml.right_column = vml.column + 4
101
+ vml.top_row = vml.row
102
+ vml.bottom_row = vml.row + 4
103
+ end
104
+ end
105
+
106
+ end
107
+ end