caxlsx 2.0.2 → 3.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (210) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +125 -30
  3. data/README.md +65 -151
  4. data/Rakefile +9 -11
  5. data/examples/{image1.jpeg → assets/image1.jpeg} +0 -0
  6. data/examples/generate.rb +15 -0
  7. data/lib/axlsx.rb +35 -17
  8. data/lib/axlsx/content_type/abstract_content_type.rb +1 -1
  9. data/lib/axlsx/content_type/content_type.rb +1 -1
  10. data/lib/axlsx/doc_props/app.rb +1 -1
  11. data/lib/axlsx/doc_props/core.rb +5 -5
  12. data/lib/axlsx/drawing/area_chart.rb +99 -0
  13. data/lib/axlsx/drawing/area_series.rb +110 -0
  14. data/lib/axlsx/drawing/axes.rb +1 -1
  15. data/lib/axlsx/drawing/axis.rb +12 -9
  16. data/lib/axlsx/drawing/bar_3D_chart.rb +13 -13
  17. data/lib/axlsx/drawing/bar_chart.rb +143 -0
  18. data/lib/axlsx/drawing/bar_series.rb +12 -14
  19. data/lib/axlsx/drawing/bubble_chart.rb +59 -0
  20. data/lib/axlsx/drawing/bubble_series.rb +63 -0
  21. data/lib/axlsx/drawing/cat_axis.rb +5 -5
  22. data/lib/axlsx/drawing/chart.rb +52 -8
  23. data/lib/axlsx/drawing/d_lbls.rb +4 -4
  24. data/lib/axlsx/drawing/drawing.rb +6 -1
  25. data/lib/axlsx/drawing/graphic_frame.rb +3 -3
  26. data/lib/axlsx/drawing/hyperlink.rb +1 -3
  27. data/lib/axlsx/drawing/line_3D_chart.rb +2 -2
  28. data/lib/axlsx/drawing/line_chart.rb +10 -10
  29. data/lib/axlsx/drawing/line_series.rb +32 -3
  30. data/lib/axlsx/drawing/marker.rb +1 -1
  31. data/lib/axlsx/drawing/num_data.rb +4 -4
  32. data/lib/axlsx/drawing/num_data_source.rb +6 -6
  33. data/lib/axlsx/drawing/num_val.rb +3 -1
  34. data/lib/axlsx/drawing/one_cell_anchor.rb +3 -2
  35. data/lib/axlsx/drawing/pic.rb +25 -19
  36. data/lib/axlsx/drawing/picture_locking.rb +1 -3
  37. data/lib/axlsx/drawing/pie_3D_chart.rb +5 -6
  38. data/lib/axlsx/drawing/pie_series.rb +6 -6
  39. data/lib/axlsx/drawing/scaling.rb +6 -6
  40. data/lib/axlsx/drawing/scatter_chart.rb +10 -10
  41. data/lib/axlsx/drawing/scatter_series.rb +40 -7
  42. data/lib/axlsx/drawing/ser_axis.rb +2 -2
  43. data/lib/axlsx/drawing/series.rb +3 -3
  44. data/lib/axlsx/drawing/series_title.rb +4 -2
  45. data/lib/axlsx/drawing/str_data.rb +3 -3
  46. data/lib/axlsx/drawing/str_val.rb +3 -1
  47. data/lib/axlsx/drawing/title.rb +23 -4
  48. data/lib/axlsx/drawing/two_cell_anchor.rb +6 -1
  49. data/lib/axlsx/drawing/val_axis.rb +1 -1
  50. data/lib/axlsx/drawing/view_3D.rb +2 -2
  51. data/lib/axlsx/drawing/vml_drawing.rb +1 -1
  52. data/lib/axlsx/package.rb +58 -47
  53. data/lib/axlsx/rels/relationship.rb +27 -26
  54. data/lib/axlsx/rels/relationships.rb +7 -4
  55. data/lib/axlsx/stylesheet/border_pr.rb +2 -2
  56. data/lib/axlsx/stylesheet/cell_alignment.rb +1 -3
  57. data/lib/axlsx/stylesheet/cell_protection.rb +1 -3
  58. data/lib/axlsx/stylesheet/cell_style.rb +1 -3
  59. data/lib/axlsx/stylesheet/color.rb +1 -3
  60. data/lib/axlsx/stylesheet/font.rb +11 -3
  61. data/lib/axlsx/stylesheet/gradient_stop.rb +1 -1
  62. data/lib/axlsx/stylesheet/num_fmt.rb +10 -3
  63. data/lib/axlsx/stylesheet/pattern_fill.rb +1 -1
  64. data/lib/axlsx/stylesheet/styles.rb +7 -7
  65. data/lib/axlsx/stylesheet/table_style_element.rb +1 -3
  66. data/lib/axlsx/util/accessors.rb +6 -6
  67. data/lib/axlsx/util/constants.rb +108 -99
  68. data/lib/axlsx/util/mime_type_utils.rb +11 -0
  69. data/lib/axlsx/util/options_parser.rb +2 -1
  70. data/lib/axlsx/util/serialized_attributes.rb +16 -6
  71. data/lib/axlsx/util/simple_typed_list.rb +28 -52
  72. data/lib/axlsx/util/storage.rb +4 -4
  73. data/lib/axlsx/util/validators.rb +31 -19
  74. data/lib/axlsx/util/zip_command.rb +73 -0
  75. data/lib/axlsx/version.rb +1 -1
  76. data/lib/axlsx/workbook/defined_name.rb +11 -12
  77. data/lib/axlsx/workbook/defined_names.rb +2 -2
  78. data/lib/axlsx/workbook/shared_strings_table.rb +5 -5
  79. data/lib/axlsx/workbook/workbook.rb +36 -20
  80. data/lib/axlsx/workbook/workbook_view.rb +80 -0
  81. data/lib/axlsx/workbook/workbook_views.rb +22 -0
  82. data/lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb +2 -2
  83. data/lib/axlsx/workbook/worksheet/auto_filter/filters.rb +1 -3
  84. data/lib/axlsx/workbook/worksheet/break.rb +1 -3
  85. data/lib/axlsx/workbook/worksheet/cell.rb +164 -75
  86. data/lib/axlsx/workbook/worksheet/cell_serializer.rb +63 -43
  87. data/lib/axlsx/workbook/worksheet/cfvo.rb +1 -3
  88. data/lib/axlsx/workbook/worksheet/cfvos.rb +4 -1
  89. data/lib/axlsx/workbook/worksheet/col.rb +14 -13
  90. data/lib/axlsx/workbook/worksheet/col_breaks.rb +2 -2
  91. data/lib/axlsx/workbook/worksheet/cols.rb +5 -2
  92. data/lib/axlsx/workbook/worksheet/comment.rb +5 -6
  93. data/lib/axlsx/workbook/worksheet/comments.rb +9 -12
  94. data/lib/axlsx/workbook/worksheet/conditional_formatting.rb +1 -1
  95. data/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb +1 -1
  96. data/lib/axlsx/workbook/worksheet/data_bar.rb +4 -6
  97. data/lib/axlsx/workbook/worksheet/data_validation.rb +8 -6
  98. data/lib/axlsx/workbook/worksheet/dimension.rb +2 -2
  99. data/lib/axlsx/workbook/worksheet/header_footer.rb +6 -8
  100. data/lib/axlsx/workbook/worksheet/icon_set.rb +3 -5
  101. data/lib/axlsx/workbook/worksheet/merged_cells.rb +4 -2
  102. data/lib/axlsx/workbook/worksheet/outline_pr.rb +33 -0
  103. data/lib/axlsx/workbook/worksheet/page_margins.rb +1 -3
  104. data/lib/axlsx/workbook/worksheet/page_set_up_pr.rb +1 -1
  105. data/lib/axlsx/workbook/worksheet/page_setup.rb +21 -23
  106. data/lib/axlsx/workbook/worksheet/pane.rb +1 -3
  107. data/lib/axlsx/workbook/worksheet/pivot_table.rb +44 -28
  108. data/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb +4 -4
  109. data/lib/axlsx/workbook/worksheet/print_options.rb +1 -3
  110. data/lib/axlsx/workbook/worksheet/protected_range.rb +1 -3
  111. data/lib/axlsx/workbook/worksheet/protected_ranges.rb +5 -2
  112. data/lib/axlsx/workbook/worksheet/rich_text.rb +55 -0
  113. data/lib/axlsx/workbook/worksheet/rich_text_run.rb +250 -0
  114. data/lib/axlsx/workbook/worksheet/row.rb +42 -52
  115. data/lib/axlsx/workbook/worksheet/row_breaks.rb +2 -2
  116. data/lib/axlsx/workbook/worksheet/selection.rb +1 -3
  117. data/lib/axlsx/workbook/worksheet/sheet_data.rb +3 -1
  118. data/lib/axlsx/workbook/worksheet/sheet_pr.rb +21 -3
  119. data/lib/axlsx/workbook/worksheet/sheet_protection.rb +1 -3
  120. data/lib/axlsx/workbook/worksheet/table.rb +6 -6
  121. data/lib/axlsx/workbook/worksheet/table_style_info.rb +1 -3
  122. data/lib/axlsx/workbook/worksheet/tables.rb +4 -1
  123. data/lib/axlsx/workbook/worksheet/worksheet.rb +76 -81
  124. data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +10 -10
  125. data/lib/axlsx/workbook/worksheet/worksheet_hyperlinks.rb +3 -3
  126. data/lib/caxlsx.rb +2 -0
  127. data/test/drawing/tc_area_chart.rb +39 -0
  128. data/test/drawing/tc_area_series.rb +71 -0
  129. data/test/drawing/tc_axis.rb +27 -0
  130. data/test/drawing/tc_bar_chart.rb +71 -0
  131. data/test/drawing/tc_bubble_chart.rb +44 -0
  132. data/test/drawing/tc_bubble_series.rb +21 -0
  133. data/test/drawing/tc_chart.rb +23 -10
  134. data/test/drawing/tc_data_source.rb +6 -0
  135. data/test/drawing/tc_drawing.rb +4 -4
  136. data/test/drawing/tc_hyperlink.rb +1 -1
  137. data/test/drawing/tc_line_chart.rb +5 -5
  138. data/test/drawing/tc_line_series.rb +47 -6
  139. data/test/drawing/tc_one_cell_anchor.rb +1 -1
  140. data/test/drawing/tc_pic.rb +11 -15
  141. data/test/drawing/tc_pie_series.rb +2 -1
  142. data/test/drawing/tc_scatter_series.rb +36 -1
  143. data/test/drawing/tc_series_title.rb +21 -0
  144. data/test/drawing/tc_str_val.rb +9 -0
  145. data/test/drawing/tc_title.rb +21 -0
  146. data/test/fixtures/image1.gif +0 -0
  147. data/test/fixtures/image1.jpeg +0 -0
  148. data/test/fixtures/image1.jpg +0 -0
  149. data/test/fixtures/image1.png +0 -0
  150. data/test/fixtures/image1_fake.jpg +0 -0
  151. data/test/rels/tc_relationship.rb +8 -0
  152. data/test/stylesheet/tc_font.rb +14 -2
  153. data/test/stylesheet/tc_styles.rb +29 -3
  154. data/test/tc_axlsx.rb +37 -0
  155. data/test/tc_helper.rb +2 -0
  156. data/test/tc_package.rb +50 -13
  157. data/test/util/tc_mime_type_utils.rb +13 -0
  158. data/test/util/tc_simple_typed_list.rb +2 -3
  159. data/test/util/tc_validators.rb +35 -11
  160. data/test/workbook/tc_defined_name.rb +12 -4
  161. data/test/workbook/tc_shared_strings_table.rb +16 -1
  162. data/test/workbook/tc_workbook.rb +38 -3
  163. data/test/workbook/tc_workbook_view.rb +50 -0
  164. data/test/workbook/worksheet/auto_filter/tc_filters.rb +1 -1
  165. data/test/workbook/worksheet/tc_break.rb +1 -1
  166. data/test/workbook/worksheet/tc_cell.rb +143 -9
  167. data/test/workbook/worksheet/tc_col.rb +18 -3
  168. data/test/workbook/worksheet/tc_conditional_formatting.rb +2 -2
  169. data/test/workbook/worksheet/tc_data_bar.rb +1 -1
  170. data/test/workbook/worksheet/tc_data_validation.rb +11 -11
  171. data/test/workbook/worksheet/tc_header_footer.rb +2 -2
  172. data/test/workbook/worksheet/tc_icon_set.rb +1 -1
  173. data/test/workbook/worksheet/tc_outline_pr.rb +19 -0
  174. data/test/workbook/worksheet/tc_page_setup.rb +3 -3
  175. data/test/workbook/worksheet/tc_pivot_table.rb +21 -6
  176. data/test/workbook/worksheet/tc_print_options.rb +1 -1
  177. data/test/workbook/worksheet/tc_rich_text.rb +44 -0
  178. data/test/workbook/worksheet/tc_rich_text_run.rb +173 -0
  179. data/test/workbook/worksheet/tc_row.rb +24 -2
  180. data/test/workbook/worksheet/tc_sheet_calc_pr.rb +1 -1
  181. data/test/workbook/worksheet/tc_sheet_format_pr.rb +4 -4
  182. data/test/workbook/worksheet/tc_sheet_pr.rb +26 -4
  183. data/test/workbook/worksheet/tc_sheet_protection.rb +5 -5
  184. data/test/workbook/worksheet/tc_sheet_view.rb +4 -4
  185. data/test/workbook/worksheet/tc_table.rb +2 -3
  186. data/test/workbook/worksheet/tc_worksheet.rb +123 -60
  187. metadata +180 -128
  188. data/examples/2010_comments.rb +0 -17
  189. data/examples/anchor_swapping.rb +0 -28
  190. data/examples/auto_filter.rb +0 -16
  191. data/examples/basic_charts.rb +0 -58
  192. data/examples/chart_colors.rb +0 -88
  193. data/examples/colored_links.rb +0 -59
  194. data/examples/conditional_formatting/example_conditional_formatting.rb +0 -74
  195. data/examples/conditional_formatting/getting_barred.rb +0 -37
  196. data/examples/conditional_formatting/hitting_the_high_notes.rb +0 -37
  197. data/examples/conditional_formatting/scaled_colors.rb +0 -39
  198. data/examples/conditional_formatting/stop_and_go.rb +0 -37
  199. data/examples/data_validation.rb +0 -50
  200. data/examples/example.rb +0 -777
  201. data/examples/extractive.rb +0 -45
  202. data/examples/ios_preview.rb +0 -14
  203. data/examples/page_setup.rb +0 -11
  204. data/examples/pivot_table.rb +0 -39
  205. data/examples/sheet_protection.rb +0 -10
  206. data/examples/skydrive/real_example.rb +0 -63
  207. data/examples/styles.rb +0 -66
  208. data/examples/underline.rb +0 -13
  209. data/examples/wrap_text.rb +0 -21
  210. 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
- self.send("#{key}=", value) if self.respond_to?("#{key}=") && value != nil
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
- def xml_attributes
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
- def xml_element_attributes
32
- @xml_element_attributes
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
- @list = []
20
- @locked_at = nil
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
- attr_reader :locked_at
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 "SimpleTypedList.+", @allowed_types, item
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 "SimpleTypedList.<<", @allowed_types, v
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 @list.include? v
106
- raise ArgumentError, "Item is protected and cannot be deleted" if protected? @list.index(v)
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 "SimpleTypedList.<<", @allowed_types, v
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 "SimpleTypedList.<<", @allowed_types, v
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 @locked_at.is_a? Fixnum
147
- index < @locked_at
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="' << @list.size.to_s << '">'
196
- @list.each { |item| item.to_xml_string(str) }
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
@@ -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 "Storage.color", COLORS.values, v
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 "Storage.type", TYPES.values, v
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
- if v.class == Class
60
- types.each { |t| return if v.ancestors.include?(t) }
61
- else
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
- # Requires that the value is a Fixnum or Integer and is greater or equal to 0
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 Fixnum or Integer value greater or equal to 0
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, [Fixnum, Integer], v, lambda { |arg| arg.respond_to?(:>=) && arg >= 0 })
90
+ DataTypeValidator.validate(:unsigned_int, Integer, v, UINT_VALIDATOR)
89
91
  end
90
92
 
91
- # Requires that the value is a Fixnum Integer or Float and is greater or equal to 0
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 Fixnun, Integer, Float value greater or equal to 0
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("Invalid column width", [Fixnum, Integer, Float], v, lambda { |arg| arg.respond_to?(:>=) && arg.to_i >= 0 })
98
+ DataTypeValidator.validate(:unsigned_numeric, Numeric, v, UINT_VALIDATOR)
97
99
  end
98
100
 
99
- # Requires that the value is a Fixnum or Integer
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 :unsigned_int, [Fixnum, Integer], v
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 Fixnum, String, Integer, Symbol, TrueClass or FalseClass and
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, [Fixnum, String, Integer, Symbol, TrueClass, FalseClass], v, lambda { |arg| [0, 1, "true", "false", :true, :false, true, false, "0", "1"].include?(arg) })
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", [Fixnum, Integer], v, lambda { |arg| arg >= 10 && arg <= 400 }
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", [Fixnum, Integer], v, lambda { |arg| arg == 0 || (arg >= 10 && arg <= 400) }
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