caxlsx 2.0.2 → 3.0.4
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.
- 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
|