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.
- data/.yardopts +5 -2
- data/CHANGELOG.md +60 -0
- data/LICENSE +1 -1
- data/README.md +115 -415
- data/Rakefile +11 -3
- data/examples/basic_charts.rb +54 -0
- data/examples/chart_colors.rb +88 -0
- data/examples/data_validation.rb +50 -0
- data/examples/example.rb +299 -155
- data/examples/example.xlsx +0 -0
- data/examples/example_streamed.xlsx +0 -0
- data/examples/extractive.pdf +0 -0
- data/examples/extractive.rb +45 -0
- data/examples/no-use_autowidth.xlsx +0 -0
- data/examples/scraping_html.rb +91 -0
- data/examples/shared_strings_example.xlsx +0 -0
- data/examples/sheet_protection.rb +10 -0
- data/examples/sheet_view.rb +34 -0
- data/examples/two_cell_anchor_image.rb +11 -0
- data/lib/axlsx/content_type/content_type.rb +2 -0
- data/lib/axlsx/content_type/default.rb +30 -15
- data/lib/axlsx/content_type/override.rb +29 -14
- data/lib/axlsx/doc_props/app.rb +161 -104
- data/lib/axlsx/doc_props/core.rb +9 -5
- data/lib/axlsx/drawing/ax_data_source.rb +26 -0
- data/lib/axlsx/drawing/axis.rb +92 -37
- data/lib/axlsx/drawing/bar_3D_chart.rb +49 -45
- data/lib/axlsx/drawing/bar_series.rb +25 -7
- data/lib/axlsx/drawing/cat_axis.rb +50 -22
- data/lib/axlsx/drawing/chart.rb +69 -56
- data/lib/axlsx/drawing/d_lbls.rb +100 -0
- data/lib/axlsx/drawing/drawing.rb +28 -12
- data/lib/axlsx/drawing/graphic_frame.rb +2 -1
- data/lib/axlsx/drawing/line_3D_chart.rb +3 -10
- data/lib/axlsx/drawing/line_series.rb +20 -4
- data/lib/axlsx/drawing/num_data.rb +52 -0
- data/lib/axlsx/drawing/num_data_source.rb +61 -0
- data/lib/axlsx/drawing/num_val.rb +32 -0
- data/lib/axlsx/drawing/pic.rb +44 -4
- data/lib/axlsx/drawing/pie_3D_chart.rb +10 -7
- data/lib/axlsx/drawing/pie_series.rb +18 -4
- data/lib/axlsx/drawing/scatter_chart.rb +2 -8
- data/lib/axlsx/drawing/scatter_series.rb +28 -2
- data/lib/axlsx/drawing/ser_axis.rb +1 -1
- data/lib/axlsx/drawing/series.rb +1 -1
- data/lib/axlsx/drawing/str_data.rb +42 -0
- data/lib/axlsx/drawing/str_val.rb +33 -0
- data/lib/axlsx/drawing/title.rb +21 -9
- data/lib/axlsx/drawing/two_cell_anchor.rb +46 -9
- data/lib/axlsx/drawing/view_3D.rb +44 -31
- data/lib/axlsx/drawing/vml_drawing.rb +42 -0
- data/lib/axlsx/drawing/vml_shape.rb +125 -0
- data/lib/axlsx/package.rb +44 -16
- data/lib/axlsx/rels/relationship.rb +3 -3
- data/lib/axlsx/rels/relationships.rb +1 -11
- data/lib/axlsx/stylesheet/gradient_fill.rb +1 -1
- data/lib/axlsx/stylesheet/styles.rb +1 -1
- data/lib/axlsx/stylesheet/table_style.rb +3 -3
- data/lib/axlsx/util/constants.rb +28 -0
- data/lib/axlsx/util/simple_typed_list.rb +15 -21
- data/lib/axlsx/util/validators.rb +81 -8
- data/lib/axlsx/version.rb +2 -7
- data/lib/axlsx/workbook/defined_name.rb +174 -0
- data/lib/axlsx/workbook/defined_names.rb +21 -0
- data/lib/axlsx/workbook/workbook.rb +65 -13
- data/lib/axlsx/workbook/worksheet/auto_filter.rb +34 -0
- data/lib/axlsx/workbook/worksheet/cell.rb +35 -7
- data/lib/axlsx/workbook/worksheet/col.rb +17 -1
- data/lib/axlsx/workbook/worksheet/cols.rb +20 -0
- data/lib/axlsx/workbook/worksheet/comment.rb +101 -0
- data/lib/axlsx/workbook/worksheet/comments.rb +85 -0
- data/lib/axlsx/workbook/worksheet/conditional_formattings.rb +25 -0
- data/lib/axlsx/workbook/worksheet/data_bar.rb +1 -1
- data/lib/axlsx/workbook/worksheet/data_validation.rb +245 -0
- data/lib/axlsx/workbook/worksheet/data_validations.rb +28 -0
- data/lib/axlsx/workbook/worksheet/dimension.rb +65 -0
- data/lib/axlsx/workbook/worksheet/merged_cells.rb +35 -0
- data/lib/axlsx/workbook/worksheet/page_setup.rb +113 -0
- data/lib/axlsx/workbook/worksheet/pane.rb +144 -0
- data/lib/axlsx/workbook/worksheet/print_options.rb +63 -0
- data/lib/axlsx/workbook/worksheet/protected_range.rb +46 -0
- data/lib/axlsx/workbook/worksheet/protected_ranges.rb +34 -0
- data/lib/axlsx/workbook/worksheet/row.rb +67 -12
- data/lib/axlsx/workbook/worksheet/selection.rb +111 -0
- data/lib/axlsx/workbook/worksheet/sheet_data.rb +25 -0
- data/lib/axlsx/workbook/worksheet/sheet_pr.rb +24 -0
- data/lib/axlsx/workbook/worksheet/sheet_protection.rb +224 -0
- data/lib/axlsx/workbook/worksheet/sheet_view.rb +379 -0
- data/lib/axlsx/workbook/worksheet/table.rb +3 -3
- data/lib/axlsx/workbook/worksheet/tables.rb +31 -0
- data/lib/axlsx/workbook/worksheet/worksheet.rb +377 -255
- data/lib/axlsx/workbook/worksheet/worksheet_comments.rb +57 -0
- data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +64 -0
- data/lib/axlsx.rb +30 -15
- data/test/content_type/tc_content_type.rb +1 -6
- data/test/doc_props/tc_app.rb +31 -1
- data/test/doc_props/tc_core.rb +3 -1
- data/test/drawing/tc_axis.rb +38 -3
- data/test/drawing/tc_bar_3D_chart.rb +12 -12
- data/test/drawing/tc_bar_series.rb +17 -13
- data/test/drawing/tc_cat_axis.rb +3 -3
- data/test/drawing/tc_cat_axis_data.rb +23 -13
- data/test/drawing/tc_chart.rb +29 -11
- data/test/drawing/tc_d_lbls.rb +47 -0
- data/test/drawing/tc_data_source.rb +17 -0
- data/test/drawing/tc_drawing.rb +11 -5
- data/test/drawing/tc_hyperlink.rb +4 -5
- data/test/drawing/tc_line_series.rb +9 -11
- data/test/drawing/tc_named_axis_data.rb +27 -0
- data/test/drawing/tc_num_data.rb +31 -0
- data/test/drawing/tc_num_val.rb +29 -0
- data/test/drawing/tc_pic.rb +22 -2
- data/test/drawing/tc_pie_3D_chart.rb +4 -8
- data/test/drawing/tc_pie_series.rb +11 -13
- data/test/drawing/tc_scatter_chart.rb +6 -1
- data/test/drawing/tc_scatter_series.rb +6 -5
- data/test/drawing/tc_series.rb +1 -1
- data/test/drawing/tc_str_data.rb +18 -0
- data/test/drawing/tc_str_val.rb +21 -0
- data/test/drawing/tc_title.rb +16 -0
- data/test/drawing/tc_two_cell_anchor.rb +2 -3
- data/test/drawing/tc_view_3D.rb +18 -18
- data/test/drawing/tc_vml_drawing.rb +25 -0
- data/test/drawing/tc_vml_shape.rb +100 -0
- data/test/rels/tc_relationship.rb +1 -0
- data/test/stylesheet/tc_gradient_fill.rb +8 -0
- data/test/stylesheet/tc_pattern_fill.rb +7 -1
- data/test/stylesheet/tc_styles.rb +3 -4
- data/test/stylesheet/tc_table_style.rb +8 -0
- data/test/stylesheet/tc_table_style_element.rb +10 -1
- data/test/tc_helper.rb +1 -0
- data/test/tc_package.rb +93 -17
- data/test/util/tc_simple_typed_list.rb +13 -0
- data/test/util/tc_validators.rb +95 -9
- data/test/workbook/tc_defined_name.rb +41 -0
- data/test/workbook/tc_workbook.rb +5 -3
- data/test/workbook/worksheet/table/tc_table.rb +3 -11
- data/test/workbook/worksheet/tc_cell.rb +30 -6
- data/test/workbook/worksheet/tc_col.rb +9 -0
- data/test/workbook/worksheet/tc_comment.rb +57 -0
- data/test/workbook/worksheet/tc_comments.rb +57 -0
- data/test/workbook/worksheet/tc_conditional_formatting.rb +44 -0
- data/test/workbook/worksheet/tc_data_bar.rb +1 -1
- data/test/workbook/worksheet/tc_data_validation.rb +265 -0
- data/test/workbook/worksheet/tc_page_setup.rb +138 -0
- data/test/workbook/worksheet/tc_pane.rb +94 -0
- data/test/workbook/worksheet/tc_print_options.rb +72 -0
- data/test/workbook/worksheet/tc_protected_range.rb +17 -0
- data/test/workbook/worksheet/tc_row.rb +36 -12
- data/test/workbook/worksheet/tc_selection.rb +94 -0
- data/test/workbook/worksheet/tc_sheet_protection.rb +117 -0
- data/test/workbook/worksheet/tc_sheet_view.rb +214 -0
- data/test/workbook/worksheet/tc_worksheet.rb +138 -48
- metadata +164 -52
- data/examples/example.csv +0 -1000
- data/lib/axlsx/drawing/cat_axis_data.rb +0 -34
- data/lib/axlsx/drawing/hlink_click.rb~ +0 -0
- data/lib/axlsx/drawing/hyperlink.rb~ +0 -64
- data/lib/axlsx/drawing/named_axis_data.rb +0 -36
- data/lib/axlsx/drawing/picture_locking.rb~ +0 -36
- data/lib/axlsx/drawing/val_axis_data.rb +0 -27
- data/lib/axlsx/util/cbf.rb +0 -333
- data/lib/axlsx/util/cfb.rb~ +0 -201
- data/lib/axlsx/util/font_tables.rb~ +0 -0
- data/lib/axlsx/util/ms_off_crypto.rb +0 -189
- data/lib/axlsx/util/ms_off_crypto.rb~ +0 -3
- data/lib/axlsx/util/ms_offcrypto.rb~ +0 -0
- data/lib/axlsx/util/parser.rb~ +0 -6
- data/lib/axlsx/util/storage.rb~ +0 -0
- data/lib/axlsx/workbook/shared_strings_table.rb~ +0 -69
- data/lib/axlsx/workbook/worksheet/cfvo.rb~ +0 -0
- data/lib/axlsx/workbook/worksheet/col.rb~ +0 -0
- data/lib/axlsx/workbook/worksheet/color_scale.rb~ +0 -46
- data/lib/axlsx/workbook/worksheet/data_bar.rb~ +0 -0
- data/lib/axlsx/workbook/worksheet/icon_set.rb~ +0 -95
- data/lib/axlsx/workbook/worksheet/shared_strings_table.rb~ +0 -0
- data/lib/axlsx/workbook/worksheet/table.rb~ +0 -97
- data/lib/schema/dc.xsd~ +0 -118
- data/lib/schema/dcterms.xsd~ +0 -331
- data/lib/schema/opc-coreProperties.xsd~ +0 -50
- data/test/drawing/tc_val_axis_data.rb +0 -17
- data/test/workbook/worksheet/table/tc_table.rb~ +0 -72
- data/test/workbook/worksheet/tc_cfvo.rb~ +0 -20
- data/test/workbook/worksheet/tc_col.rb~ +0 -10
- data/test/workbook/worksheet/tc_color_scale.rb~ +0 -0
- data/test/workbook/worksheet/tc_data_bar.rb~ +0 -0
- 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 =
|
|
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.
|
|
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.
|
|
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
|
+
|