caxlsx 2.0.2 → 3.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +125 -30
- data/README.md +65 -151
- data/Rakefile +9 -11
- data/examples/{image1.jpeg → assets/image1.jpeg} +0 -0
- data/examples/generate.rb +15 -0
- data/lib/axlsx.rb +35 -17
- data/lib/axlsx/content_type/abstract_content_type.rb +1 -1
- data/lib/axlsx/content_type/content_type.rb +1 -1
- data/lib/axlsx/doc_props/app.rb +1 -1
- data/lib/axlsx/doc_props/core.rb +5 -5
- data/lib/axlsx/drawing/area_chart.rb +99 -0
- data/lib/axlsx/drawing/area_series.rb +110 -0
- data/lib/axlsx/drawing/axes.rb +1 -1
- data/lib/axlsx/drawing/axis.rb +12 -9
- data/lib/axlsx/drawing/bar_3D_chart.rb +13 -13
- data/lib/axlsx/drawing/bar_chart.rb +143 -0
- data/lib/axlsx/drawing/bar_series.rb +12 -14
- data/lib/axlsx/drawing/bubble_chart.rb +59 -0
- data/lib/axlsx/drawing/bubble_series.rb +63 -0
- data/lib/axlsx/drawing/cat_axis.rb +5 -5
- data/lib/axlsx/drawing/chart.rb +52 -8
- data/lib/axlsx/drawing/d_lbls.rb +4 -4
- data/lib/axlsx/drawing/drawing.rb +6 -1
- data/lib/axlsx/drawing/graphic_frame.rb +3 -3
- data/lib/axlsx/drawing/hyperlink.rb +1 -3
- data/lib/axlsx/drawing/line_3D_chart.rb +2 -2
- data/lib/axlsx/drawing/line_chart.rb +10 -10
- data/lib/axlsx/drawing/line_series.rb +32 -3
- data/lib/axlsx/drawing/marker.rb +1 -1
- data/lib/axlsx/drawing/num_data.rb +4 -4
- data/lib/axlsx/drawing/num_data_source.rb +6 -6
- data/lib/axlsx/drawing/num_val.rb +3 -1
- data/lib/axlsx/drawing/one_cell_anchor.rb +3 -2
- data/lib/axlsx/drawing/pic.rb +25 -19
- data/lib/axlsx/drawing/picture_locking.rb +1 -3
- data/lib/axlsx/drawing/pie_3D_chart.rb +5 -6
- data/lib/axlsx/drawing/pie_series.rb +6 -6
- data/lib/axlsx/drawing/scaling.rb +6 -6
- data/lib/axlsx/drawing/scatter_chart.rb +10 -10
- data/lib/axlsx/drawing/scatter_series.rb +40 -7
- data/lib/axlsx/drawing/ser_axis.rb +2 -2
- data/lib/axlsx/drawing/series.rb +3 -3
- data/lib/axlsx/drawing/series_title.rb +4 -2
- data/lib/axlsx/drawing/str_data.rb +3 -3
- data/lib/axlsx/drawing/str_val.rb +3 -1
- data/lib/axlsx/drawing/title.rb +23 -4
- data/lib/axlsx/drawing/two_cell_anchor.rb +6 -1
- data/lib/axlsx/drawing/val_axis.rb +1 -1
- data/lib/axlsx/drawing/view_3D.rb +2 -2
- data/lib/axlsx/drawing/vml_drawing.rb +1 -1
- data/lib/axlsx/package.rb +58 -47
- data/lib/axlsx/rels/relationship.rb +27 -26
- data/lib/axlsx/rels/relationships.rb +7 -4
- data/lib/axlsx/stylesheet/border_pr.rb +2 -2
- data/lib/axlsx/stylesheet/cell_alignment.rb +1 -3
- data/lib/axlsx/stylesheet/cell_protection.rb +1 -3
- data/lib/axlsx/stylesheet/cell_style.rb +1 -3
- data/lib/axlsx/stylesheet/color.rb +1 -3
- data/lib/axlsx/stylesheet/font.rb +11 -3
- data/lib/axlsx/stylesheet/gradient_stop.rb +1 -1
- data/lib/axlsx/stylesheet/num_fmt.rb +10 -3
- data/lib/axlsx/stylesheet/pattern_fill.rb +1 -1
- data/lib/axlsx/stylesheet/styles.rb +7 -7
- data/lib/axlsx/stylesheet/table_style_element.rb +1 -3
- data/lib/axlsx/util/accessors.rb +6 -6
- data/lib/axlsx/util/constants.rb +108 -99
- data/lib/axlsx/util/mime_type_utils.rb +11 -0
- data/lib/axlsx/util/options_parser.rb +2 -1
- data/lib/axlsx/util/serialized_attributes.rb +16 -6
- data/lib/axlsx/util/simple_typed_list.rb +28 -52
- data/lib/axlsx/util/storage.rb +4 -4
- data/lib/axlsx/util/validators.rb +31 -19
- data/lib/axlsx/util/zip_command.rb +73 -0
- data/lib/axlsx/version.rb +1 -1
- data/lib/axlsx/workbook/defined_name.rb +11 -12
- data/lib/axlsx/workbook/defined_names.rb +2 -2
- data/lib/axlsx/workbook/shared_strings_table.rb +5 -5
- data/lib/axlsx/workbook/workbook.rb +36 -20
- data/lib/axlsx/workbook/workbook_view.rb +80 -0
- data/lib/axlsx/workbook/workbook_views.rb +22 -0
- data/lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb +2 -2
- data/lib/axlsx/workbook/worksheet/auto_filter/filters.rb +1 -3
- data/lib/axlsx/workbook/worksheet/break.rb +1 -3
- data/lib/axlsx/workbook/worksheet/cell.rb +164 -75
- data/lib/axlsx/workbook/worksheet/cell_serializer.rb +63 -43
- data/lib/axlsx/workbook/worksheet/cfvo.rb +1 -3
- data/lib/axlsx/workbook/worksheet/cfvos.rb +4 -1
- data/lib/axlsx/workbook/worksheet/col.rb +14 -13
- data/lib/axlsx/workbook/worksheet/col_breaks.rb +2 -2
- data/lib/axlsx/workbook/worksheet/cols.rb +5 -2
- data/lib/axlsx/workbook/worksheet/comment.rb +5 -6
- data/lib/axlsx/workbook/worksheet/comments.rb +9 -12
- data/lib/axlsx/workbook/worksheet/conditional_formatting.rb +1 -1
- data/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb +1 -1
- data/lib/axlsx/workbook/worksheet/data_bar.rb +4 -6
- data/lib/axlsx/workbook/worksheet/data_validation.rb +8 -6
- data/lib/axlsx/workbook/worksheet/dimension.rb +2 -2
- data/lib/axlsx/workbook/worksheet/header_footer.rb +6 -8
- data/lib/axlsx/workbook/worksheet/icon_set.rb +3 -5
- data/lib/axlsx/workbook/worksheet/merged_cells.rb +4 -2
- data/lib/axlsx/workbook/worksheet/outline_pr.rb +33 -0
- data/lib/axlsx/workbook/worksheet/page_margins.rb +1 -3
- data/lib/axlsx/workbook/worksheet/page_set_up_pr.rb +1 -1
- data/lib/axlsx/workbook/worksheet/page_setup.rb +21 -23
- data/lib/axlsx/workbook/worksheet/pane.rb +1 -3
- data/lib/axlsx/workbook/worksheet/pivot_table.rb +44 -28
- data/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb +4 -4
- data/lib/axlsx/workbook/worksheet/print_options.rb +1 -3
- data/lib/axlsx/workbook/worksheet/protected_range.rb +1 -3
- data/lib/axlsx/workbook/worksheet/protected_ranges.rb +5 -2
- data/lib/axlsx/workbook/worksheet/rich_text.rb +55 -0
- data/lib/axlsx/workbook/worksheet/rich_text_run.rb +250 -0
- data/lib/axlsx/workbook/worksheet/row.rb +42 -52
- data/lib/axlsx/workbook/worksheet/row_breaks.rb +2 -2
- data/lib/axlsx/workbook/worksheet/selection.rb +1 -3
- data/lib/axlsx/workbook/worksheet/sheet_data.rb +3 -1
- data/lib/axlsx/workbook/worksheet/sheet_pr.rb +21 -3
- data/lib/axlsx/workbook/worksheet/sheet_protection.rb +1 -3
- data/lib/axlsx/workbook/worksheet/table.rb +6 -6
- data/lib/axlsx/workbook/worksheet/table_style_info.rb +1 -3
- data/lib/axlsx/workbook/worksheet/tables.rb +4 -1
- data/lib/axlsx/workbook/worksheet/worksheet.rb +76 -81
- data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +10 -10
- data/lib/axlsx/workbook/worksheet/worksheet_hyperlinks.rb +3 -3
- data/lib/caxlsx.rb +2 -0
- data/test/drawing/tc_area_chart.rb +39 -0
- data/test/drawing/tc_area_series.rb +71 -0
- data/test/drawing/tc_axis.rb +27 -0
- data/test/drawing/tc_bar_chart.rb +71 -0
- data/test/drawing/tc_bubble_chart.rb +44 -0
- data/test/drawing/tc_bubble_series.rb +21 -0
- data/test/drawing/tc_chart.rb +23 -10
- data/test/drawing/tc_data_source.rb +6 -0
- data/test/drawing/tc_drawing.rb +4 -4
- data/test/drawing/tc_hyperlink.rb +1 -1
- data/test/drawing/tc_line_chart.rb +5 -5
- data/test/drawing/tc_line_series.rb +47 -6
- data/test/drawing/tc_one_cell_anchor.rb +1 -1
- data/test/drawing/tc_pic.rb +11 -15
- data/test/drawing/tc_pie_series.rb +2 -1
- data/test/drawing/tc_scatter_series.rb +36 -1
- data/test/drawing/tc_series_title.rb +21 -0
- data/test/drawing/tc_str_val.rb +9 -0
- data/test/drawing/tc_title.rb +21 -0
- data/test/fixtures/image1.gif +0 -0
- data/test/fixtures/image1.jpeg +0 -0
- data/test/fixtures/image1.jpg +0 -0
- data/test/fixtures/image1.png +0 -0
- data/test/fixtures/image1_fake.jpg +0 -0
- data/test/rels/tc_relationship.rb +8 -0
- data/test/stylesheet/tc_font.rb +14 -2
- data/test/stylesheet/tc_styles.rb +29 -3
- data/test/tc_axlsx.rb +37 -0
- data/test/tc_helper.rb +2 -0
- data/test/tc_package.rb +50 -13
- data/test/util/tc_mime_type_utils.rb +13 -0
- data/test/util/tc_simple_typed_list.rb +2 -3
- data/test/util/tc_validators.rb +35 -11
- data/test/workbook/tc_defined_name.rb +12 -4
- data/test/workbook/tc_shared_strings_table.rb +16 -1
- data/test/workbook/tc_workbook.rb +38 -3
- data/test/workbook/tc_workbook_view.rb +50 -0
- data/test/workbook/worksheet/auto_filter/tc_filters.rb +1 -1
- data/test/workbook/worksheet/tc_break.rb +1 -1
- data/test/workbook/worksheet/tc_cell.rb +143 -9
- data/test/workbook/worksheet/tc_col.rb +18 -3
- data/test/workbook/worksheet/tc_conditional_formatting.rb +2 -2
- data/test/workbook/worksheet/tc_data_bar.rb +1 -1
- data/test/workbook/worksheet/tc_data_validation.rb +11 -11
- data/test/workbook/worksheet/tc_header_footer.rb +2 -2
- data/test/workbook/worksheet/tc_icon_set.rb +1 -1
- data/test/workbook/worksheet/tc_outline_pr.rb +19 -0
- data/test/workbook/worksheet/tc_page_setup.rb +3 -3
- data/test/workbook/worksheet/tc_pivot_table.rb +21 -6
- data/test/workbook/worksheet/tc_print_options.rb +1 -1
- data/test/workbook/worksheet/tc_rich_text.rb +44 -0
- data/test/workbook/worksheet/tc_rich_text_run.rb +173 -0
- data/test/workbook/worksheet/tc_row.rb +24 -2
- data/test/workbook/worksheet/tc_sheet_calc_pr.rb +1 -1
- data/test/workbook/worksheet/tc_sheet_format_pr.rb +4 -4
- data/test/workbook/worksheet/tc_sheet_pr.rb +26 -4
- data/test/workbook/worksheet/tc_sheet_protection.rb +5 -5
- data/test/workbook/worksheet/tc_sheet_view.rb +4 -4
- data/test/workbook/worksheet/tc_table.rb +2 -3
- data/test/workbook/worksheet/tc_worksheet.rb +123 -60
- metadata +180 -128
- data/examples/2010_comments.rb +0 -17
- data/examples/anchor_swapping.rb +0 -28
- data/examples/auto_filter.rb +0 -16
- data/examples/basic_charts.rb +0 -58
- data/examples/chart_colors.rb +0 -88
- data/examples/colored_links.rb +0 -59
- data/examples/conditional_formatting/example_conditional_formatting.rb +0 -74
- data/examples/conditional_formatting/getting_barred.rb +0 -37
- data/examples/conditional_formatting/hitting_the_high_notes.rb +0 -37
- data/examples/conditional_formatting/scaled_colors.rb +0 -39
- data/examples/conditional_formatting/stop_and_go.rb +0 -37
- data/examples/data_validation.rb +0 -50
- data/examples/example.rb +0 -777
- data/examples/extractive.rb +0 -45
- data/examples/ios_preview.rb +0 -14
- data/examples/page_setup.rb +0 -11
- data/examples/pivot_table.rb +0 -39
- data/examples/sheet_protection.rb +0 -10
- data/examples/skydrive/real_example.rb +0 -63
- data/examples/styles.rb +0 -66
- data/examples/underline.rb +0 -13
- data/examples/wrap_text.rb +0 -21
- data/lib/axlsx/util/parser.rb +0 -44
@@ -0,0 +1,11 @@
|
|
1
|
+
module Axlsx
|
2
|
+
# This module defines some utils related with mime type detection
|
3
|
+
module MimeTypeUtils
|
4
|
+
# Detect a file mime type
|
5
|
+
# @param [String] v File path
|
6
|
+
# @return [String] File mime type
|
7
|
+
def self.get_mime_type(v)
|
8
|
+
MimeMagic.by_magic(File.open(v)).to_s
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -8,7 +8,8 @@ module Axlsx
|
|
8
8
|
# @param [Hash] options Options to parse.
|
9
9
|
def parse_options(options={})
|
10
10
|
options.each do |key, value|
|
11
|
-
|
11
|
+
key = :"#{key}="
|
12
|
+
self.send(key, value) if !value.nil? && self.respond_to?(key)
|
12
13
|
end
|
13
14
|
end
|
14
15
|
end
|
@@ -18,9 +18,7 @@ module Axlsx
|
|
18
18
|
end
|
19
19
|
|
20
20
|
# a reader for those attributes
|
21
|
-
|
22
|
-
@xml_attributes
|
23
|
-
end
|
21
|
+
attr_reader :xml_attributes
|
24
22
|
|
25
23
|
# This helper registers the attributes that will be formatted as elements.
|
26
24
|
def serializable_element_attributes(*symbols)
|
@@ -28,8 +26,20 @@ module Axlsx
|
|
28
26
|
end
|
29
27
|
|
30
28
|
# attr reader for element attributes
|
31
|
-
|
32
|
-
|
29
|
+
attr_reader :xml_element_attributes
|
30
|
+
end
|
31
|
+
|
32
|
+
# creates a XML tag with serialized attributes
|
33
|
+
# @see SerializedAttributes#serialized_attributes
|
34
|
+
def serialized_tag(tagname, str, additional_attributes = {}, &block)
|
35
|
+
str << "<#{tagname} "
|
36
|
+
serialized_attributes(str, additional_attributes)
|
37
|
+
if block_given?
|
38
|
+
str << '>'
|
39
|
+
yield
|
40
|
+
str << "</#{tagname}>"
|
41
|
+
else
|
42
|
+
str << '/>'
|
33
43
|
end
|
34
44
|
end
|
35
45
|
|
@@ -42,7 +52,7 @@ module Axlsx
|
|
42
52
|
def serialized_attributes(str = '', additional_attributes = {})
|
43
53
|
attributes = declared_attributes.merge! additional_attributes
|
44
54
|
attributes.each do |key, value|
|
45
|
-
str << "#{Axlsx.camel(key, false)}=\"#{Axlsx.camel(value, false)}\" "
|
55
|
+
str << "#{Axlsx.camel(key, false)}=\"#{Axlsx.camel(Axlsx.booleanize(value), false)}\" "
|
46
56
|
end
|
47
57
|
str
|
48
58
|
end
|
@@ -8,7 +8,7 @@ module Axlsx
|
|
8
8
|
# @param [Array, Class] type An array of Class objects or a single Class object
|
9
9
|
# @param [String] serialize_as The tag name to use in serialization
|
10
10
|
# @raise [ArgumentError] if all members of type are not Class objects
|
11
|
-
def initialize type, serialize_as=nil
|
11
|
+
def initialize type, serialize_as=nil, start_size = 0
|
12
12
|
if type.is_a? Array
|
13
13
|
type.each { |item| raise ArgumentError, "All members of type must be Class objects" unless item.is_a? Class }
|
14
14
|
@allowed_types = type
|
@@ -16,9 +16,8 @@ module Axlsx
|
|
16
16
|
raise ArgumentError, "Type must be a Class object or array of Class objects" unless type.is_a? Class
|
17
17
|
@allowed_types = [type]
|
18
18
|
end
|
19
|
-
@
|
20
|
-
@
|
21
|
-
@serialize_as = serialize_as
|
19
|
+
@serialize_as = serialize_as unless serialize_as.nil?
|
20
|
+
@list = Array.new(start_size)
|
22
21
|
end
|
23
22
|
|
24
23
|
# The class constants of allowed types
|
@@ -27,7 +26,9 @@ module Axlsx
|
|
27
26
|
|
28
27
|
# The index below which items cannot be removed
|
29
28
|
# @return [Integer]
|
30
|
-
|
29
|
+
def locked_at
|
30
|
+
defined?(@locked_at) ? @locked_at : nil
|
31
|
+
end
|
31
32
|
|
32
33
|
# The tag name to use when serializing this object
|
33
34
|
# by default the parent node for all items in the list is the classname of the first allowed type with the first letter in lowercase.
|
@@ -54,6 +55,7 @@ module Axlsx
|
|
54
55
|
end
|
55
56
|
result
|
56
57
|
end
|
58
|
+
|
57
59
|
# Lock this list at the current size
|
58
60
|
# @return [self]
|
59
61
|
def lock
|
@@ -61,18 +63,18 @@ module Axlsx
|
|
61
63
|
self
|
62
64
|
end
|
63
65
|
|
64
|
-
def to_ary
|
65
|
-
@list
|
66
|
-
end
|
67
|
-
|
68
|
-
alias :to_a :to_ary
|
69
|
-
|
70
66
|
# Unlock the list
|
71
67
|
# @return [self]
|
72
68
|
def unlock
|
73
69
|
@locked_at = nil
|
74
70
|
self
|
75
71
|
end
|
72
|
+
|
73
|
+
def to_ary
|
74
|
+
@list
|
75
|
+
end
|
76
|
+
|
77
|
+
alias :to_a :to_ary
|
76
78
|
|
77
79
|
# join operator
|
78
80
|
# @param [Array] v the array to join
|
@@ -81,7 +83,7 @@ module Axlsx
|
|
81
83
|
# @return [SimpleTypedList]
|
82
84
|
def +(v)
|
83
85
|
v.each do |item|
|
84
|
-
DataTypeValidator.validate
|
86
|
+
DataTypeValidator.validate :SimpleTypedList_plus, @allowed_types, item
|
85
87
|
@list << item
|
86
88
|
end
|
87
89
|
end
|
@@ -91,19 +93,21 @@ module Axlsx
|
|
91
93
|
# @raise [ArgumentError] if the value being added is not one fo the allowed types
|
92
94
|
# @return [Integer] returns the index of the item added.
|
93
95
|
def <<(v)
|
94
|
-
DataTypeValidator.validate
|
96
|
+
DataTypeValidator.validate :SimpleTypedList_push, @allowed_types, v
|
95
97
|
@list << v
|
96
98
|
@list.size - 1
|
97
|
-
end
|
99
|
+
end
|
100
|
+
|
98
101
|
alias :push :<<
|
102
|
+
|
99
103
|
|
100
104
|
# delete the item from the list
|
101
105
|
# @param [Any] v The item to be deleted.
|
102
106
|
# @raise [ArgumentError] if the item's index is protected by locking
|
103
107
|
# @return [Any] The item deleted
|
104
108
|
def delete(v)
|
105
|
-
return unless
|
106
|
-
raise ArgumentError, "Item is protected and cannot be deleted" if protected?
|
109
|
+
return unless include? v
|
110
|
+
raise ArgumentError, "Item is protected and cannot be deleted" if protected? index(v)
|
107
111
|
@list.delete v
|
108
112
|
end
|
109
113
|
|
@@ -122,7 +126,7 @@ module Axlsx
|
|
122
126
|
# @raise [ArgumentError] if the index is protected by locking
|
123
127
|
# @raise [ArgumentError] if the item is not one of the allowed types
|
124
128
|
def []=(index, v)
|
125
|
-
DataTypeValidator.validate
|
129
|
+
DataTypeValidator.validate :SimpleTypedList_insert, @allowed_types, v
|
126
130
|
raise ArgumentError, "Item is protected and cannot be changed" if protected? index
|
127
131
|
@list[index] = v
|
128
132
|
v
|
@@ -134,7 +138,7 @@ module Axlsx
|
|
134
138
|
# @raise [ArgumentError] if the index is protected by locking
|
135
139
|
# @raise [ArgumentError] if the index is not one of the allowed types
|
136
140
|
def insert(index, v)
|
137
|
-
DataTypeValidator.validate
|
141
|
+
DataTypeValidator.validate :SimpleTypedList_insert, @allowed_types, v
|
138
142
|
raise ArgumentError, "Item is protected and cannot be changed" if protected? index
|
139
143
|
@list.insert(index, v)
|
140
144
|
v
|
@@ -143,38 +147,10 @@ module Axlsx
|
|
143
147
|
# determines if the index is protected
|
144
148
|
# @param [Integer] index
|
145
149
|
def protected? index
|
146
|
-
return false unless
|
147
|
-
index <
|
150
|
+
return false unless locked_at.is_a? Integer
|
151
|
+
index < locked_at
|
148
152
|
end
|
149
153
|
|
150
|
-
# override the equality method so that this object can be compared to a simple array.
|
151
|
-
# if this object's list is equal to the specifiec array, we return true.
|
152
|
-
def ==(v)
|
153
|
-
v == @list
|
154
|
-
end
|
155
|
-
# method_mission override to pass allowed methods to the list.
|
156
|
-
# @note
|
157
|
-
# the following methods are not allowed
|
158
|
-
# :replace
|
159
|
-
# :insert
|
160
|
-
# :collect!
|
161
|
-
# :map!
|
162
|
-
# :pop
|
163
|
-
# :delete_if
|
164
|
-
# :reverse!
|
165
|
-
# :shift
|
166
|
-
# :shuffle!
|
167
|
-
# :slice!
|
168
|
-
# :sort!
|
169
|
-
# :uniq!
|
170
|
-
# :unshift
|
171
|
-
# :zip
|
172
|
-
# :flatten!
|
173
|
-
# :fill
|
174
|
-
# :drop
|
175
|
-
# :drop_while
|
176
|
-
# :delete_if
|
177
|
-
# :clear
|
178
154
|
DESTRUCTIVE = ['replace', 'insert', 'collect!', 'map!', 'pop', 'delete_if',
|
179
155
|
'reverse!', 'shift', 'shuffle!', 'slice!', 'sort!', 'uniq!',
|
180
156
|
'unshift', 'zip', 'flatten!', 'fill', 'drop', 'drop_while',
|
@@ -188,13 +164,13 @@ module Axlsx
|
|
188
164
|
end
|
189
165
|
}
|
190
166
|
end
|
191
|
-
|
167
|
+
|
192
168
|
def to_xml_string(str = '')
|
193
169
|
classname = @allowed_types[0].name.split('::').last
|
194
170
|
el_name = serialize_as.to_s || (classname[0,1].downcase + classname[1..-1])
|
195
|
-
str << '<' << el_name << ' count="' <<
|
196
|
-
|
197
|
-
str << '</' << el_name << '>'
|
171
|
+
str << ('<' << el_name << ' count="' << size.to_s << '">')
|
172
|
+
each { |item| item.to_xml_string(str) }
|
173
|
+
str << ('</' << el_name << '>')
|
198
174
|
end
|
199
175
|
|
200
176
|
end
|
data/lib/axlsx/util/storage.rb
CHANGED
@@ -6,14 +6,14 @@ module Axlsx
|
|
6
6
|
|
7
7
|
# Packing for the Storage when pushing an array of items into a byte stream
|
8
8
|
# Name, name length, type, color, left sibling, right sibling, child, classid, state, created, modified, sector, size
|
9
|
-
PACKING = "s32 s1 c2 l3 x16 x4 q2 l q"
|
9
|
+
PACKING = "s32 s1 c2 l3 x16 x4 q2 l q".freeze
|
10
10
|
|
11
11
|
# storage types
|
12
12
|
TYPES = {
|
13
13
|
:root=>5,
|
14
14
|
:stream=>2,
|
15
15
|
:storage=>1
|
16
|
-
}
|
16
|
+
}.freeze
|
17
17
|
|
18
18
|
# Creates a byte string for this storage
|
19
19
|
# @return [String]
|
@@ -45,7 +45,7 @@ module Axlsx
|
|
45
45
|
# Sets the color for this storage
|
46
46
|
# @param [Integer] v Must be one of the COLORS constant hash values
|
47
47
|
def color=(v)
|
48
|
-
RestrictionValidator.validate
|
48
|
+
RestrictionValidator.validate :storage_color, COLORS.values, v
|
49
49
|
@color = v
|
50
50
|
end
|
51
51
|
|
@@ -116,7 +116,7 @@ module Axlsx
|
|
116
116
|
# Sets the type for this storage.
|
117
117
|
# @param [Integer] v the type to specify must be one of the TYPES constant hash values.
|
118
118
|
def type=(v)
|
119
|
-
RestrictionValidator.validate
|
119
|
+
RestrictionValidator.validate :storage_type, TYPES.values, v
|
120
120
|
@type = v
|
121
121
|
end
|
122
122
|
|
@@ -52,14 +52,12 @@ module Axlsx
|
|
52
52
|
# @return [Boolean] true if validation succeeds.
|
53
53
|
# @see validate_boolean
|
54
54
|
def self.validate(name, types, v, other=false)
|
55
|
-
types = [types] unless types.is_a? Array
|
56
55
|
if other.is_a?(Proc)
|
57
56
|
raise ArgumentError, (ERR_TYPE % [v.inspect, name, types.inspect]) unless other.call(v)
|
58
57
|
end
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
types.each { |t| return if v.is_a?(t) }
|
58
|
+
v_class = v.is_a?(Class) ? v : v.class
|
59
|
+
Array(types).each do |t|
|
60
|
+
return if v_class <= t
|
63
61
|
end
|
64
62
|
raise ArgumentError, (ERR_TYPE % [v.inspect, name, types.inspect])
|
65
63
|
end
|
@@ -80,34 +78,38 @@ module Axlsx
|
|
80
78
|
def self.validate_angle(v)
|
81
79
|
raise ArgumentError, (ERR_ANGLE % v.inspect) unless (v.to_i >= -5400000 && v.to_i <= 5400000)
|
82
80
|
end
|
83
|
-
|
81
|
+
|
82
|
+
# Validates an unsigned intger
|
83
|
+
UINT_VALIDATOR = lambda { |arg| arg.respond_to?(:>=) && arg >= 0 }
|
84
|
+
|
85
|
+
# Requires that the value is a Integer and is greater or equal to 0
|
84
86
|
# @param [Any] v The value validated
|
85
|
-
# @raise [ArgumentError] raised if the value is not a
|
87
|
+
# @raise [ArgumentError] raised if the value is not a Integer value greater or equal to 0
|
86
88
|
# @return [Boolean] true if the data is valid
|
87
89
|
def self.validate_unsigned_int(v)
|
88
|
-
DataTypeValidator.validate(:unsigned_int,
|
90
|
+
DataTypeValidator.validate(:unsigned_int, Integer, v, UINT_VALIDATOR)
|
89
91
|
end
|
90
92
|
|
91
|
-
# Requires that the value is a
|
93
|
+
# Requires that the value is a Integer or Float and is greater or equal to 0
|
92
94
|
# @param [Any] v The value validated
|
93
|
-
# @raise [ArgumentError] raised if the value is not a
|
95
|
+
# @raise [ArgumentError] raised if the value is not a Integer, Float value greater or equal to 0
|
94
96
|
# @return [Boolean] true if the data is valid
|
95
97
|
def self.validate_unsigned_numeric(v)
|
96
|
-
DataTypeValidator.validate(
|
98
|
+
DataTypeValidator.validate(:unsigned_numeric, Numeric, v, UINT_VALIDATOR)
|
97
99
|
end
|
98
100
|
|
99
|
-
# Requires that the value is a
|
101
|
+
# Requires that the value is a Integer
|
100
102
|
# @param [Any] v The value validated
|
101
103
|
def self.validate_int(v)
|
102
|
-
DataTypeValidator.validate :
|
104
|
+
DataTypeValidator.validate :signed_int, Integer, v
|
103
105
|
end
|
104
106
|
|
105
107
|
# Requires that the value is a form that can be evaluated as a boolean in an xml document.
|
106
|
-
# The value must be an instance of
|
108
|
+
# The value must be an instance of String, Integer, Symbol, TrueClass or FalseClass and
|
107
109
|
# it must be one of 0, 1, "true", "false", :true, :false, true, false, "0", or "1"
|
108
110
|
# @param [Any] v The value validated
|
109
111
|
def self.validate_boolean(v)
|
110
|
-
DataTypeValidator.validate(:boolean, [
|
112
|
+
DataTypeValidator.validate(:boolean, [String, Integer, Symbol, TrueClass, FalseClass], v, lambda { |arg| [0, 1, "true", "false", :true, :false, true, false, "0", "1"].include?(arg) })
|
111
113
|
end
|
112
114
|
|
113
115
|
# Requires that the value is a String
|
@@ -130,12 +132,12 @@ module Axlsx
|
|
130
132
|
|
131
133
|
# Requires that the value is an integer ranging from 10 to 400.
|
132
134
|
def self.validate_scale_10_400(v)
|
133
|
-
DataTypeValidator.validate "page_scale",
|
135
|
+
DataTypeValidator.validate "page_scale", Integer, v, lambda { |arg| arg >= 10 && arg <= 400 }
|
134
136
|
end
|
135
137
|
|
136
138
|
# Requires that the value is an integer ranging from 10 to 400 or 0.
|
137
139
|
def self.validate_scale_0_10_400(v)
|
138
|
-
DataTypeValidator.validate "page_scale",
|
140
|
+
DataTypeValidator.validate "page_scale", Integer, v, lambda { |arg| arg == 0 || (arg >= 10 && arg <= 400) }
|
139
141
|
end
|
140
142
|
|
141
143
|
# Requires that the value is one of :default, :landscape, or :portrait.
|
@@ -147,7 +149,7 @@ module Axlsx
|
|
147
149
|
RestrictionValidator.validate "cell run style u", [:none, :single, :double, :singleAccounting, :doubleAccounting], v
|
148
150
|
end
|
149
151
|
|
150
|
-
# validates cell style family which must be between 1 and 5
|
152
|
+
# validates cell style family which must be between 1 and 5
|
151
153
|
def self.validate_family(v)
|
152
154
|
RestrictionValidator.validate "cell run style family", 1..5, v
|
153
155
|
end
|
@@ -267,7 +269,7 @@ module Axlsx
|
|
267
269
|
# valid types must be one of custom, data, decimal, list, none, textLength, time, whole
|
268
270
|
# @param [Any] v The value validated
|
269
271
|
def self.validate_data_validation_type(v)
|
270
|
-
RestrictionValidator.validate :data_validation_type, [:custom, :data, :decimal, :list, :none, :textLength, :time, :whole], v
|
272
|
+
RestrictionValidator.validate :data_validation_type, [:custom, :data, :decimal, :list, :none, :textLength, :date, :time, :whole], v
|
271
273
|
end
|
272
274
|
|
273
275
|
# Requires that the value is a valid sheet view type.
|
@@ -297,4 +299,14 @@ module Axlsx
|
|
297
299
|
def self.validate_display_blanks_as(v)
|
298
300
|
RestrictionValidator.validate :display_blanks_as, [:gap, :span, :zero], v
|
299
301
|
end
|
302
|
+
|
303
|
+
# Requires that the value is one of :visible, :hidden, :very_hidden
|
304
|
+
def self.validate_view_visibility(v)
|
305
|
+
RestrictionValidator.validate :visibility, [:visible, :hidden, :very_hidden], v
|
306
|
+
end
|
307
|
+
|
308
|
+
# Requires that the value is one of :default, :circle, :dash, :diamond, :dot, :picture, :plus, :square, :star, :triangle, :x
|
309
|
+
def self.validate_marker_symbol(v)
|
310
|
+
RestrictionValidator.validate :marker_symbol, [:default, :circle, :dash, :diamond, :dot, :picture, :plus, :square, :star, :triangle, :x], v
|
311
|
+
end
|
300
312
|
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'open3'
|
3
|
+
require 'shellwords'
|
4
|
+
|
5
|
+
module Axlsx
|
6
|
+
|
7
|
+
# The ZipCommand class supports zipping the Excel file contents using
|
8
|
+
# a binary zip program instead of RubyZip's `Zip::OutputStream`.
|
9
|
+
#
|
10
|
+
# The methods provided here mimic `Zip::OutputStream` so that `ZipCommand` can
|
11
|
+
# be used as a drop-in replacement. Note that method signatures are not
|
12
|
+
# identical to `Zip::OutputStream`, they are only sufficiently close so that
|
13
|
+
# `ZipCommand` and `Zip::OutputStream` can be interchangeably used within
|
14
|
+
# `caxlsx`.
|
15
|
+
class ZipCommand
|
16
|
+
# Raised when the zip command exits with a non-zero status.
|
17
|
+
class ZipError < StandardError; end
|
18
|
+
|
19
|
+
def initialize(zip_command)
|
20
|
+
@current_file = nil
|
21
|
+
@files = []
|
22
|
+
@zip_command = zip_command
|
23
|
+
end
|
24
|
+
|
25
|
+
# Create a temporary directory for writing files to.
|
26
|
+
#
|
27
|
+
# The directory and its contents are removed at the end of the block.
|
28
|
+
def open(output, &block)
|
29
|
+
Dir.mktmpdir do |dir|
|
30
|
+
@dir = dir
|
31
|
+
block.call(self)
|
32
|
+
write_file
|
33
|
+
zip_parts(output)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Closes the current entry and opens a new for writing.
|
38
|
+
def put_next_entry(entry)
|
39
|
+
write_file
|
40
|
+
@current_file = "#{@dir}/#{entry.name}"
|
41
|
+
@files << entry.name
|
42
|
+
FileUtils.mkdir_p(File.dirname(@current_file))
|
43
|
+
end
|
44
|
+
|
45
|
+
# Write to a buffer that will be written to the current entry
|
46
|
+
def write(content)
|
47
|
+
@buffer << content
|
48
|
+
end
|
49
|
+
alias << write
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def write_file
|
54
|
+
if @current_file
|
55
|
+
@buffer.rewind
|
56
|
+
File.open(@current_file, "wb") { |f| f.write @buffer.read }
|
57
|
+
end
|
58
|
+
@current_file = nil
|
59
|
+
@buffer = StringIO.new
|
60
|
+
end
|
61
|
+
|
62
|
+
def zip_parts(output)
|
63
|
+
output = Shellwords.shellescape(File.absolute_path(output))
|
64
|
+
inputs = Shellwords.shelljoin(@files)
|
65
|
+
escaped_dir = Shellwords.shellescape(@dir)
|
66
|
+
command = "cd #{escaped_dir} && #{@zip_command} #{output} #{inputs}"
|
67
|
+
stdout_and_stderr, status = Open3.capture2e(command)
|
68
|
+
if !status.success?
|
69
|
+
raise(ZipError.new(stdout_and_stderr))
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|