axlsx 1.1.4 → 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 (196) hide show
  1. data/.yardopts +5 -2
  2. data/CHANGELOG.md +39 -0
  3. data/README.md +108 -31
  4. data/Rakefile +11 -3
  5. data/examples/basic_charts.rb +54 -0
  6. data/examples/chart_colors.rb +17 -2
  7. data/examples/data_validation.rb +50 -0
  8. data/examples/example.rb +130 -47
  9. data/examples/example.xlsx +0 -0
  10. data/examples/example_streamed.xlsx +0 -0
  11. data/examples/extractive.pdf +0 -0
  12. data/examples/extractive.rb +3 -0
  13. data/examples/no-use_autowidth.xlsx +0 -0
  14. data/examples/scraping_html.rb +91 -0
  15. data/examples/shared_strings_example.xlsx +0 -0
  16. data/examples/sheet_protection.rb +10 -0
  17. data/examples/sheet_view.rb +34 -0
  18. data/examples/two_cell_anchor_image.rb +11 -0
  19. data/lib/axlsx/content_type/content_type.rb +2 -0
  20. data/lib/axlsx/content_type/default.rb +30 -15
  21. data/lib/axlsx/content_type/override.rb +29 -14
  22. data/lib/axlsx/doc_props/app.rb +161 -104
  23. data/lib/axlsx/doc_props/core.rb +9 -5
  24. data/lib/axlsx/drawing/ax_data_source.rb +7 -6
  25. data/lib/axlsx/drawing/axis.rb +82 -36
  26. data/lib/axlsx/drawing/bar_3D_chart.rb +49 -45
  27. data/lib/axlsx/drawing/bar_series.rb +2 -1
  28. data/lib/axlsx/drawing/cat_axis.rb +43 -39
  29. data/lib/axlsx/drawing/chart.rb +65 -54
  30. data/lib/axlsx/drawing/d_lbls.rb +100 -0
  31. data/lib/axlsx/drawing/drawing.rb +20 -8
  32. data/lib/axlsx/drawing/graphic_frame.rb +2 -1
  33. data/lib/axlsx/drawing/line_3D_chart.rb +3 -10
  34. data/lib/axlsx/drawing/num_data.rb +2 -2
  35. data/lib/axlsx/drawing/num_data_source.rb +4 -1
  36. data/lib/axlsx/drawing/pic.rb +44 -4
  37. data/lib/axlsx/drawing/pie_3D_chart.rb +10 -7
  38. data/lib/axlsx/drawing/scatter_chart.rb +2 -8
  39. data/lib/axlsx/drawing/title.rb +21 -9
  40. data/lib/axlsx/drawing/two_cell_anchor.rb +46 -9
  41. data/lib/axlsx/drawing/view_3D.rb +41 -31
  42. data/lib/axlsx/drawing/vml_drawing.rb +42 -0
  43. data/lib/axlsx/drawing/vml_shape.rb +125 -0
  44. data/lib/axlsx/package.rb +44 -16
  45. data/lib/axlsx/rels/relationship.rb +3 -3
  46. data/lib/axlsx/rels/relationships.rb +1 -11
  47. data/lib/axlsx/stylesheet/gradient_fill.rb +1 -1
  48. data/lib/axlsx/stylesheet/styles.rb +1 -1
  49. data/lib/axlsx/stylesheet/table_style.rb +3 -3
  50. data/lib/axlsx/util/constants.rb +28 -0
  51. data/lib/axlsx/util/simple_typed_list.rb +15 -21
  52. data/lib/axlsx/util/validators.rb +80 -7
  53. data/lib/axlsx/version.rb +2 -7
  54. data/lib/axlsx/workbook/defined_name.rb +174 -0
  55. data/lib/axlsx/workbook/defined_names.rb +21 -0
  56. data/lib/axlsx/workbook/workbook.rb +65 -13
  57. data/lib/axlsx/workbook/worksheet/auto_filter.rb +34 -0
  58. data/lib/axlsx/workbook/worksheet/cell.rb +35 -7
  59. data/lib/axlsx/workbook/worksheet/col.rb +15 -0
  60. data/lib/axlsx/workbook/worksheet/cols.rb +20 -0
  61. data/lib/axlsx/workbook/worksheet/comment.rb +101 -0
  62. data/lib/axlsx/workbook/worksheet/comments.rb +85 -0
  63. data/lib/axlsx/workbook/worksheet/conditional_formattings.rb +25 -0
  64. data/lib/axlsx/workbook/worksheet/data_bar.rb +1 -1
  65. data/lib/axlsx/workbook/worksheet/data_validation.rb +245 -0
  66. data/lib/axlsx/workbook/worksheet/data_validations.rb +28 -0
  67. data/lib/axlsx/workbook/worksheet/dimension.rb +65 -0
  68. data/lib/axlsx/workbook/worksheet/merged_cells.rb +35 -0
  69. data/lib/axlsx/workbook/worksheet/page_setup.rb +113 -0
  70. data/lib/axlsx/workbook/worksheet/pane.rb +144 -0
  71. data/lib/axlsx/workbook/worksheet/print_options.rb +63 -0
  72. data/lib/axlsx/workbook/worksheet/protected_range.rb +46 -0
  73. data/lib/axlsx/workbook/worksheet/protected_ranges.rb +34 -0
  74. data/lib/axlsx/workbook/worksheet/row.rb +36 -20
  75. data/lib/axlsx/workbook/worksheet/selection.rb +111 -0
  76. data/lib/axlsx/workbook/worksheet/sheet_data.rb +25 -0
  77. data/lib/axlsx/workbook/worksheet/sheet_pr.rb +24 -0
  78. data/lib/axlsx/workbook/worksheet/sheet_protection.rb +224 -0
  79. data/lib/axlsx/workbook/worksheet/sheet_view.rb +379 -0
  80. data/lib/axlsx/workbook/worksheet/table.rb +2 -2
  81. data/lib/axlsx/workbook/worksheet/tables.rb +31 -0
  82. data/lib/axlsx/workbook/worksheet/worksheet.rb +377 -255
  83. data/lib/axlsx/workbook/worksheet/worksheet_comments.rb +57 -0
  84. data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +64 -0
  85. data/lib/axlsx.rb +30 -15
  86. data/test/content_type/tc_content_type.rb +1 -6
  87. data/test/doc_props/tc_app.rb +31 -1
  88. data/test/doc_props/tc_core.rb +3 -1
  89. data/test/drawing/tc_axis.rb +38 -3
  90. data/test/drawing/tc_bar_3D_chart.rb +12 -12
  91. data/test/drawing/tc_bar_series.rb +1 -2
  92. data/test/drawing/tc_cat_axis.rb +3 -3
  93. data/test/drawing/tc_chart.rb +29 -9
  94. data/test/drawing/tc_d_lbls.rb +47 -0
  95. data/test/drawing/tc_drawing.rb +11 -5
  96. data/test/drawing/tc_hyperlink.rb +4 -5
  97. data/test/drawing/tc_line_series.rb +7 -3
  98. data/test/drawing/tc_num_data.rb +5 -1
  99. data/test/drawing/tc_pic.rb +22 -2
  100. data/test/drawing/tc_pie_3D_chart.rb +4 -8
  101. data/test/drawing/tc_pie_series.rb +7 -2
  102. data/test/drawing/tc_scatter_chart.rb +6 -1
  103. data/test/drawing/tc_scatter_series.rb +1 -1
  104. data/test/drawing/tc_series.rb +1 -1
  105. data/test/drawing/tc_title.rb +16 -0
  106. data/test/drawing/tc_two_cell_anchor.rb +1 -2
  107. data/test/drawing/tc_view_3D.rb +18 -18
  108. data/test/drawing/tc_vml_drawing.rb +25 -0
  109. data/test/drawing/tc_vml_shape.rb +100 -0
  110. data/test/rels/tc_relationship.rb +1 -0
  111. data/test/stylesheet/tc_gradient_fill.rb +8 -0
  112. data/test/stylesheet/tc_pattern_fill.rb +7 -1
  113. data/test/stylesheet/tc_styles.rb +3 -4
  114. data/test/stylesheet/tc_table_style.rb +8 -0
  115. data/test/stylesheet/tc_table_style_element.rb +10 -1
  116. data/test/tc_helper.rb +1 -0
  117. data/test/tc_package.rb +93 -17
  118. data/test/util/tc_simple_typed_list.rb +13 -0
  119. data/test/util/tc_validators.rb +95 -9
  120. data/test/workbook/tc_defined_name.rb +41 -0
  121. data/test/workbook/tc_workbook.rb +5 -3
  122. data/test/workbook/worksheet/table/tc_table.rb +3 -11
  123. data/test/workbook/worksheet/tc_cell.rb +30 -6
  124. data/test/workbook/worksheet/tc_col.rb +9 -0
  125. data/test/workbook/worksheet/tc_comment.rb +57 -0
  126. data/test/workbook/worksheet/tc_comments.rb +57 -0
  127. data/test/workbook/worksheet/tc_conditional_formatting.rb +44 -0
  128. data/test/workbook/worksheet/tc_data_bar.rb +1 -1
  129. data/test/workbook/worksheet/tc_data_validation.rb +265 -0
  130. data/test/workbook/worksheet/tc_page_setup.rb +138 -0
  131. data/test/workbook/worksheet/tc_pane.rb +94 -0
  132. data/test/workbook/worksheet/tc_print_options.rb +72 -0
  133. data/test/workbook/worksheet/tc_protected_range.rb +17 -0
  134. data/test/workbook/worksheet/tc_row.rb +32 -14
  135. data/test/workbook/worksheet/tc_selection.rb +94 -0
  136. data/test/workbook/worksheet/tc_sheet_protection.rb +117 -0
  137. data/test/workbook/worksheet/tc_sheet_view.rb +214 -0
  138. data/test/workbook/worksheet/tc_worksheet.rb +138 -48
  139. metadata +140 -80
  140. data/examples/#extractive.csv# +0 -0
  141. data/examples/#extractive.rb# +0 -45
  142. data/examples/chart_colors.rb~ +0 -0
  143. data/examples/chart_colors.xlsx +0 -0
  144. data/examples/colored_series_data.xlsx +0 -0
  145. data/examples/conditional_formatting/getting_barred.xlsx +0 -0
  146. data/examples/example.csv +0 -1000
  147. data/examples/extractive.csv +0 -1
  148. data/examples/extractive.csv~ +0 -1
  149. data/examples/extractive.rb~ +0 -3
  150. data/examples/extractive.xlsx +0 -0
  151. data/examples/stack.rb +0 -21
  152. data/examples/stack.rb~ +0 -27
  153. data/examples/stack.xlsx +0 -0
  154. data/examples/~$chart_colors.xlsx +0 -0
  155. data/examples/~$extractive.xlsx +0 -0
  156. data/lib/axlsx/drawing/ax_data_source.rb~ +0 -55
  157. data/lib/axlsx/drawing/data_source.rb~ +0 -51
  158. data/lib/axlsx/drawing/hlink_click.rb~ +0 -0
  159. data/lib/axlsx/drawing/hyperlink.rb~ +0 -64
  160. data/lib/axlsx/drawing/num_data.rb~ +0 -51
  161. data/lib/axlsx/drawing/num_data_source.rb~ +0 -54
  162. data/lib/axlsx/drawing/num_val.rb~ +0 -40
  163. data/lib/axlsx/drawing/picture_locking.rb~ +0 -36
  164. data/lib/axlsx/drawing/ref.rb~ +0 -41
  165. data/lib/axlsx/drawing/str_data.rb~ +0 -58
  166. data/lib/axlsx/drawing/str_val.rb~ +0 -35
  167. data/lib/axlsx/util/cbf.rb +0 -333
  168. data/lib/axlsx/util/cfb.rb~ +0 -201
  169. data/lib/axlsx/util/font_tables.rb~ +0 -0
  170. data/lib/axlsx/util/ms_off_crypto.rb +0 -189
  171. data/lib/axlsx/util/ms_off_crypto.rb~ +0 -3
  172. data/lib/axlsx/util/ms_offcrypto.rb~ +0 -0
  173. data/lib/axlsx/util/parser.rb~ +0 -6
  174. data/lib/axlsx/util/storage.rb~ +0 -0
  175. data/lib/axlsx/workbook/shared_strings_table.rb~ +0 -69
  176. data/lib/axlsx/workbook/worksheet/cfvo.rb~ +0 -0
  177. data/lib/axlsx/workbook/worksheet/col.rb~ +0 -0
  178. data/lib/axlsx/workbook/worksheet/color_scale.rb~ +0 -46
  179. data/lib/axlsx/workbook/worksheet/data_bar.rb~ +0 -0
  180. data/lib/axlsx/workbook/worksheet/icon_set.rb~ +0 -95
  181. data/lib/axlsx/workbook/worksheet/shared_strings_table.rb~ +0 -0
  182. data/lib/axlsx/workbook/worksheet/table.rb~ +0 -97
  183. data/lib/schema/dc.xsd~ +0 -118
  184. data/lib/schema/dcterms.xsd~ +0 -331
  185. data/lib/schema/opc-coreProperties.xsd~ +0 -50
  186. data/test/drawing/tc_data_source.rb~ +0 -30
  187. data/test/drawing/tc_num_data.rb~ +0 -35
  188. data/test/drawing/tc_num_val.rb~ +0 -29
  189. data/test/drawing/tc_str_data.rb~ +0 -30
  190. data/test/drawing/tc_str_val.rb~ +0 -26
  191. data/test/workbook/worksheet/table/tc_table.rb~ +0 -72
  192. data/test/workbook/worksheet/tc_cfvo.rb~ +0 -20
  193. data/test/workbook/worksheet/tc_col.rb~ +0 -10
  194. data/test/workbook/worksheet/tc_color_scale.rb~ +0 -0
  195. data/test/workbook/worksheet/tc_data_bar.rb~ +0 -0
  196. data/test/workbook/worksheet/tc_icon_set.rb~ +0 -0
@@ -0,0 +1,21 @@
1
+ module Axlsx
2
+ # a simple types list of DefinedName objects
3
+ class DefinedNames < SimpleTypedList
4
+
5
+ # creates the DefinedNames object
6
+ def initialize
7
+ super DefinedName
8
+ end
9
+
10
+ # Serialize to xml
11
+ # @param [String] str
12
+ # @return [String]
13
+ def to_xml_string(str = '')
14
+ return if @list.empty?
15
+ str << "<definedNames>"
16
+ each { |defined_name| defined_name.to_xml_string(str) }
17
+ str << '</definedNames>'
18
+ end
19
+ end
20
+ end
21
+
@@ -1,21 +1,43 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  module Axlsx
3
-
3
+ require 'axlsx/workbook/worksheet/auto_filter.rb'
4
4
  require 'axlsx/workbook/worksheet/date_time_converter.rb'
5
+ require 'axlsx/workbook/worksheet/protected_range.rb'
6
+ require 'axlsx/workbook/worksheet/protected_ranges.rb'
5
7
  require 'axlsx/workbook/worksheet/cell.rb'
6
8
  require 'axlsx/workbook/worksheet/page_margins.rb'
9
+ require 'axlsx/workbook/worksheet/page_setup.rb'
10
+ require 'axlsx/workbook/worksheet/print_options.rb'
7
11
  require 'axlsx/workbook/worksheet/cfvo.rb'
8
12
  require 'axlsx/workbook/worksheet/color_scale.rb'
9
13
  require 'axlsx/workbook/worksheet/data_bar.rb'
10
14
  require 'axlsx/workbook/worksheet/icon_set.rb'
11
15
  require 'axlsx/workbook/worksheet/conditional_formatting.rb'
12
16
  require 'axlsx/workbook/worksheet/conditional_formatting_rule.rb'
17
+ require 'axlsx/workbook/worksheet/conditional_formattings.rb'
13
18
  require 'axlsx/workbook/worksheet/row.rb'
14
19
  require 'axlsx/workbook/worksheet/col.rb'
20
+ require 'axlsx/workbook/worksheet/cols.rb'
21
+ require 'axlsx/workbook/worksheet/comments.rb'
22
+ require 'axlsx/workbook/worksheet/comment.rb'
23
+ require 'axlsx/workbook/worksheet/merged_cells.rb'
24
+ require 'axlsx/workbook/worksheet/sheet_protection.rb'
25
+ require 'axlsx/workbook/worksheet/sheet_pr.rb'
26
+ require 'axlsx/workbook/worksheet/dimension.rb'
27
+ require 'axlsx/workbook/worksheet/sheet_data.rb'
28
+ require 'axlsx/workbook/worksheet/worksheet_drawing.rb'
29
+ require 'axlsx/workbook/worksheet/worksheet_comments.rb'
15
30
  require 'axlsx/workbook/worksheet/worksheet.rb'
16
31
  require 'axlsx/workbook/shared_strings_table.rb'
32
+ require 'axlsx/workbook/defined_name.rb'
33
+ require 'axlsx/workbook/defined_names.rb'
17
34
  require 'axlsx/workbook/worksheet/table.rb'
18
-
35
+ require 'axlsx/workbook/worksheet/tables.rb'
36
+ require 'axlsx/workbook/worksheet/data_validation.rb'
37
+ require 'axlsx/workbook/worksheet/data_validations.rb'
38
+ require 'axlsx/workbook/worksheet/sheet_view.rb'
39
+ require 'axlsx/workbook/worksheet/pane.rb'
40
+ require 'axlsx/workbook/worksheet/selection.rb'
19
41
  # The Workbook class is an xlsx workbook that manages worksheets, charts, drawings and styles.
20
42
  # The following parts of the Office Open XML spreadsheet specification are not implimented in this version.
21
43
  #
@@ -82,6 +104,9 @@ require 'axlsx/workbook/worksheet/table.rb'
82
104
  # @return [SimpleTypedList]
83
105
  attr_reader :drawings
84
106
 
107
+ # pretty sure this two are always empty and can be removed.
108
+
109
+
85
110
  # A colllection of tables associated with this workbook
86
111
  # @note The recommended way to manage drawings is Worksheet#add_table
87
112
  # @see Worksheet#add_table
@@ -90,6 +115,23 @@ require 'axlsx/workbook/worksheet/table.rb'
90
115
  attr_reader :tables
91
116
 
92
117
 
118
+ # A collection of defined names for this workbook
119
+ # @note The recommended way to manage defined names is Workbook#add_defined_name
120
+ # @see DefinedName
121
+ # @return [DefinedNames]
122
+ def defined_names
123
+ @defined_names ||= DefinedNames.new
124
+ end
125
+
126
+ # A collection of comments associated with this workbook
127
+ # @note The recommended way to manage comments is WOrksheet#add_comment
128
+ # @see Worksheet#add_comment
129
+ # @see Comment
130
+ # @return [Comments]
131
+ def comments
132
+ worksheets.map { |sheet| sheet.comments }.compact
133
+ end
134
+
93
135
  # The styles associated with this workbook
94
136
  # @note The recommended way to manage styles is Styles#add_style
95
137
  # @see Style#add_style
@@ -123,7 +165,11 @@ require 'axlsx/workbook/worksheet/table.rb'
123
165
  @drawings = SimpleTypedList.new Drawing
124
166
  @charts = SimpleTypedList.new Chart
125
167
  @images = SimpleTypedList.new Pic
168
+ # Are these even used????? Check package serialization parts
126
169
  @tables = SimpleTypedList.new Table
170
+ @comments = SimpleTypedList.new Comments
171
+
172
+
127
173
  @use_autowidth = true
128
174
 
129
175
  self.date1904= !options[:date1904].nil? && options[:date1904]
@@ -146,12 +192,14 @@ require 'axlsx/workbook/worksheet/table.rb'
146
192
  def self.date1904() @@date1904; end
147
193
 
148
194
  # Indicates if the workbook should use autowidths or not.
149
- # this must be set before instantiating a worksheet to avoid Rmagix inclusion
195
+ # @note This gem no longer depends on RMagick for autowidth
196
+ # calculation. Thus the performance benefits of turning this off are
197
+ # marginal unless you are creating a very large sheet.
150
198
  # @return [Boolean]
151
199
  def use_autowidth() @use_autowidth; end
152
200
 
153
201
  # see @use_autowidth
154
- def use_autowidth=(v) Axlsx::validate_boolean v; @use_autowidth = v; end
202
+ def use_autowidth=(v=true) Axlsx::validate_boolean v; @use_autowidth = v; end
155
203
 
156
204
  # Adds a worksheet to this workbook
157
205
  # @return [Worksheet]
@@ -164,6 +212,14 @@ require 'axlsx/workbook/worksheet/table.rb'
164
212
  worksheet
165
213
  end
166
214
 
215
+ # Adds a defined name to this workbook
216
+ # @return [DefinedName]
217
+ # @param [String] formula @see DefinedName
218
+ # @param [Hash] options @see DefinedName
219
+ def add_defined_name(formula, options)
220
+ defined_names << DefinedName.new(formula, options)
221
+ end
222
+
167
223
  # The workbook relationships. This is managed automatically by the workbook
168
224
  # @return [Relationships]
169
225
  def relationships
@@ -205,17 +261,13 @@ require 'axlsx/workbook/worksheet/table.rb'
205
261
  str << '<workbookPr date1904="' << @@date1904.to_s << '"/>'
206
262
  str << '<sheets>'
207
263
  @worksheets.each_with_index do |sheet, index|
208
- str << '<sheet name="' << sheet.name << '" sheetId="' << (index+1).to_s << '" r:id="' << sheet.rId << '"/>'
209
- end
210
- str << '</sheets>'
211
- str << '<definedNames>'
212
- @worksheets.each_with_index do |sheet, index|
213
- if sheet.auto_filter
214
- str << '<definedName name="_xlnm._FilterDatabase" localSheetId="' << index.to_s << '" hidden="1">'
215
- str << sheet.abs_auto_filter << '</definedName>'
264
+ str << '<sheet name="' << sheet.name << '" sheetId="' << (index+1).to_s << '" r:id="' << sheet.rId << '"/>'
265
+ if defined_name = sheet.auto_filter.defined_name
266
+ add_defined_name defined_name, :name => '_xlnm._FilterDatabase', :local_sheet_id => index, :hidden => 1
216
267
  end
217
268
  end
218
- str << '</definedNames>'
269
+ str << '</sheets>'
270
+ defined_names.to_xml_string(str)
219
271
  str << '</workbook>'
220
272
  end
221
273
 
@@ -0,0 +1,34 @@
1
+ module Axlsx
2
+
3
+ #This class represents an auto filter range in a worksheet
4
+ class AutoFilter
5
+
6
+ # creates a new Autofilter object
7
+ # @param [Worksheet] worksheet
8
+ def initialize(worksheet)
9
+ raise ArgumentError, 'you must provide a worksheet' unless worksheet.is_a?(Worksheet)
10
+ @worksheet = worksheet
11
+ end
12
+
13
+ attr_reader :worksheet
14
+
15
+ # The range the autofilter should be applied to.
16
+ # This should be a string like 'A1:B8'
17
+ # @return [String]
18
+ attr_accessor :range
19
+
20
+ # the formula for the defined name required for this auto filter
21
+ # @return [String]
22
+ def defined_name
23
+ return unless range
24
+ Axlsx.cell_range(range.split(':').collect { |name| worksheet.name_to_cell(name)})
25
+ end
26
+
27
+ # serialize the object
28
+ # @return [String]
29
+ def to_xml_string(str='')
30
+ str << "<autoFilter ref='#{range}'></autoFilter>"
31
+ end
32
+
33
+ end
34
+ end
@@ -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)
@@ -102,6 +102,21 @@ module Axlsx
102
102
  self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
103
103
  end
104
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
105
120
 
106
121
  # Serialize this columns data to an xml string
107
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