caxlsx 3.0.0 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +126 -31
  3. data/README.md +78 -170
  4. data/examples/{image1.jpeg → assets/image1.jpeg} +0 -0
  5. data/examples/generate.rb +15 -0
  6. data/lib/axlsx.rb +2 -3
  7. data/lib/axlsx/drawing/bar_chart.rb +3 -3
  8. data/lib/axlsx/drawing/bar_series.rb +3 -5
  9. data/lib/axlsx/drawing/d_lbls.rb +1 -1
  10. data/lib/axlsx/drawing/pie_series.rb +1 -1
  11. data/lib/axlsx/drawing/series_title.rb +3 -1
  12. data/lib/axlsx/drawing/title.rb +3 -2
  13. data/lib/axlsx/package.rb +53 -19
  14. data/lib/axlsx/rels/relationship.rb +26 -25
  15. data/lib/axlsx/stylesheet/font.rb +10 -2
  16. data/lib/axlsx/util/constants.rb +2 -1
  17. data/lib/axlsx/util/mime_type_utils.rb +1 -1
  18. data/lib/axlsx/util/validators.rb +2 -2
  19. data/lib/axlsx/util/zip_command.rb +73 -0
  20. data/lib/axlsx/version.rb +1 -1
  21. data/lib/axlsx/workbook/workbook.rb +0 -9
  22. data/lib/axlsx/workbook/worksheet/cell.rb +32 -5
  23. data/lib/axlsx/workbook/worksheet/col.rb +8 -4
  24. data/lib/axlsx/workbook/worksheet/data_validation.rb +4 -4
  25. data/lib/axlsx/workbook/worksheet/pivot_table.rb +7 -2
  26. data/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb +1 -1
  27. data/lib/axlsx/workbook/worksheet/rich_text_run.rb +1 -1
  28. data/lib/axlsx/workbook/worksheet/row.rb +6 -3
  29. data/lib/axlsx/workbook/worksheet/table.rb +1 -1
  30. data/lib/axlsx/workbook/worksheet/worksheet.rb +17 -4
  31. data/lib/caxlsx.rb +2 -0
  32. data/test/drawing/tc_drawing.rb +2 -2
  33. data/test/drawing/tc_hyperlink.rb +1 -1
  34. data/test/drawing/tc_one_cell_anchor.rb +1 -1
  35. data/test/drawing/tc_pic.rb +4 -4
  36. data/test/drawing/tc_pie_series.rb +2 -1
  37. data/test/drawing/tc_series_title.rb +21 -0
  38. data/test/drawing/tc_title.rb +16 -0
  39. data/test/fixtures/image1.gif +0 -0
  40. data/test/fixtures/image1.jpeg +0 -0
  41. data/test/fixtures/image1.jpg +0 -0
  42. data/test/fixtures/image1.png +0 -0
  43. data/test/fixtures/image1_fake.jpg +0 -0
  44. data/test/rels/tc_relationship.rb +8 -0
  45. data/test/stylesheet/tc_font.rb +14 -2
  46. data/test/stylesheet/tc_styles.rb +27 -1
  47. data/test/tc_axlsx.rb +6 -0
  48. data/test/tc_helper.rb +0 -2
  49. data/test/tc_package.rb +82 -13
  50. data/test/util/tc_mime_type_utils.rb +1 -1
  51. data/test/util/tc_validators.rb +1 -1
  52. data/test/workbook/worksheet/tc_cell.rb +68 -2
  53. data/test/workbook/worksheet/tc_col.rb +16 -1
  54. data/test/workbook/worksheet/tc_pivot_table.rb +8 -0
  55. data/test/workbook/worksheet/tc_pivot_table_cache_definition.rb +8 -0
  56. data/test/workbook/worksheet/tc_rich_text_run.rb +3 -2
  57. data/test/workbook/worksheet/tc_row.rb +38 -0
  58. data/test/workbook/worksheet/tc_table.rb +10 -0
  59. data/test/workbook/worksheet/tc_worksheet.rb +24 -15
  60. metadata +130 -151
  61. data/examples/2010_comments.rb +0 -17
  62. data/examples/anchor_swapping.rb +0 -28
  63. data/examples/auto_filter.rb +0 -25
  64. data/examples/basic_charts.rb +0 -58
  65. data/examples/chart_colors.rb +0 -88
  66. data/examples/colored_links.rb +0 -59
  67. data/examples/conditional_formatting/example_conditional_formatting.rb +0 -89
  68. data/examples/conditional_formatting/getting_barred.rb +0 -37
  69. data/examples/conditional_formatting/hitting_the_high_notes.rb +0 -37
  70. data/examples/conditional_formatting/scaled_colors.rb +0 -39
  71. data/examples/conditional_formatting/stop_and_go.rb +0 -37
  72. data/examples/data_validation.rb +0 -67
  73. data/examples/example.rb +0 -885
  74. data/examples/extractive.rb +0 -45
  75. data/examples/ios_preview.rb +0 -14
  76. data/examples/merge_cells.rb +0 -17
  77. data/examples/no_grid_with_borders.rb +0 -18
  78. data/examples/page_setup.rb +0 -11
  79. data/examples/pivot_table.rb +0 -39
  80. data/examples/pivot_test.rb +0 -63
  81. data/examples/sheet_protection.rb +0 -10
  82. data/examples/skydrive/real_example.rb +0 -63
  83. data/examples/split.rb +0 -16
  84. data/examples/styles.rb +0 -66
  85. data/examples/underline.rb +0 -13
  86. data/examples/wrap_text.rb +0 -21
  87. data/lib/axlsx/util/parser.rb +0 -44
File without changes
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ files = if !ARGV.empty?
4
+ ARGV.select { |file| File.exist?(file) }
5
+ else
6
+ Dir['*_example.md']
7
+ end
8
+
9
+ files.each do |file|
10
+ puts "Executing #{file.split('.')[0].tr('_', ' ')}"
11
+ code = File.read(file).match(/```ruby(?<code>.+)```/m)[:code]
12
+ unless code.nil?
13
+ eval(['$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"', code].join("\n"))
14
+ end
15
+ end
data/lib/axlsx.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # encoding: UTF-8
2
2
  require 'htmlentities'
3
3
  require 'axlsx/version.rb'
4
- require 'mimemagic'
4
+ require 'marcel'
5
5
 
6
6
  require 'axlsx/util/simple_typed_list.rb'
7
7
  require 'axlsx/util/constants.rb'
@@ -9,9 +9,8 @@ require 'axlsx/util/validators.rb'
9
9
  require 'axlsx/util/accessors.rb'
10
10
  require 'axlsx/util/serialized_attributes'
11
11
  require 'axlsx/util/options_parser'
12
- # to be included with parsable intitites.
13
- #require 'axlsx/util/parser.rb'
14
12
  require 'axlsx/util/mime_type_utils'
13
+ require 'axlsx/util/zip_command'
15
14
 
16
15
  require 'axlsx/stylesheet/styles.rb'
17
16
 
@@ -1,7 +1,7 @@
1
1
  # encoding: UTF-8
2
2
  module Axlsx
3
3
 
4
- # The BarChart is a three dimentional barchart (who would have guessed?) that you can add to your worksheet.
4
+ # The BarChart is a two dimentional barchart that you can add to your worksheet.
5
5
  # @see Worksheet#add_chart
6
6
  # @see Chart#add_series
7
7
  # @see Package#serialize
@@ -49,7 +49,7 @@ module Axlsx
49
49
  @grouping ||= :clustered
50
50
  end
51
51
 
52
- # The shabe of the bars or columns
52
+ # The shape of the bars or columns
53
53
  # must be one of [:cone, :coneToMax, :box, :cylinder, :pyramid, :pyramidToMax]
54
54
  # @return [Symbol]
55
55
  def shape
@@ -106,7 +106,7 @@ module Axlsx
106
106
  end
107
107
  alias :gapDepth= :gap_depth=
108
108
 
109
- # The shabe of the bars or columns
109
+ # The shape of the bars or columns
110
110
  # must be one of [:cone, :coneToMax, :box, :cylinder, :pyramid, :pyramidToMax]
111
111
  def shape=(v)
112
112
  RestrictionValidator.validate "BarChart.shape", [:cone, :coneToMax, :box, :cylinder, :pyramid, :pyramidToMax], v
@@ -15,9 +15,8 @@ module Axlsx
15
15
  # @return [Array, SimpleTypedList]
16
16
  attr_reader :labels
17
17
 
18
- # The shabe of the bars or columns
19
- # must be one of [:percentStacked, :clustered, :standard, :stacked]
20
- # @return [Symbol]
18
+ # The shape of the bars or columns
19
+ # @return [Symbol] must be one of [:cone, :coneToMax, :box, :cylinder, :pyramid, :pyramidToMax]
21
20
  attr_reader :shape
22
21
 
23
22
  # An array of rgb colors to apply to your bar chart.
@@ -41,8 +40,7 @@ module Axlsx
41
40
  # @see colors
42
41
  def colors=(v) DataTypeValidator.validate "BarSeries.colors", [Array], v; @colors = v end
43
42
 
44
- # The shabe of the bars or columns
45
- # must be one of [:cone, :coneToMax, :box, :cylinder, :pyramid, :pyramidToMax]
43
+ # @see shape
46
44
  def shape=(v)
47
45
  RestrictionValidator.validate "BarSeries.shape", [:cone, :coneToMax, :box, :cylinder, :pyramid, :pyramidToMax], v
48
46
  @shape = v
@@ -55,7 +55,7 @@ module Axlsx
55
55
 
56
56
  # @see DLbls#d_lbl_pos
57
57
  # Assigns the label postion for this data labels on this chart.
58
- # Allowed positions are :bestFilt, :b, :ctr, :inBase, :inEnd, :l,
58
+ # Allowed positions are :bestFit, :b, :ctr, :inBase, :inEnd, :l,
59
59
  # :outEnd, :r and :t
60
60
  # The default is :bestFit
61
61
  # @param [Symbol] label_position the postion you want to use.
@@ -47,7 +47,7 @@ module Axlsx
47
47
  # @return [String]
48
48
  def to_xml_string(str = '')
49
49
  super(str) do
50
- str << '<c:explosion val="' + @explosion + '"/>' unless @explosion.nil?
50
+ str << '<c:explosion val="' + @explosion.to_s + '"/>' unless @explosion.nil?
51
51
  colors.each_with_index do |c, index|
52
52
  str << '<c:dPt>'
53
53
  str << ('<c:idx val="' << index.to_s << '"/>')
@@ -7,13 +7,15 @@ module Axlsx
7
7
  # @param [String] str
8
8
  # @return [String]
9
9
  def to_xml_string(str = '')
10
+ clean_value = Axlsx::trust_input ? @text.to_s : ::CGI.escapeHTML(Axlsx::sanitize(@text.to_s))
11
+
10
12
  str << '<c:tx>'
11
13
  str << '<c:strRef>'
12
14
  str << ('<c:f>' << Axlsx::cell_range([@cell]) << '</c:f>')
13
15
  str << '<c:strCache>'
14
16
  str << '<c:ptCount val="1"/>'
15
17
  str << '<c:pt idx="0">'
16
- str << ('<c:v>' << @text << '</c:v>')
18
+ str << ('<c:v>' << clean_value << '</c:v>')
17
19
  str << '</c:pt>'
18
20
  str << '</c:strCache>'
19
21
  str << '</c:strRef>'
@@ -62,6 +62,7 @@ module Axlsx
62
62
  def to_xml_string(str = '')
63
63
  str << '<c:title>'
64
64
  unless @text.empty?
65
+ clean_value = Axlsx::trust_input ? @text.to_s : ::CGI.escapeHTML(Axlsx::sanitize(@text.to_s))
65
66
  str << '<c:tx>'
66
67
  if @cell.is_a?(Cell)
67
68
  str << '<c:strRef>'
@@ -69,7 +70,7 @@ module Axlsx
69
70
  str << '<c:strCache>'
70
71
  str << '<c:ptCount val="1"/>'
71
72
  str << '<c:pt idx="0">'
72
- str << ('<c:v>' << @text << '</c:v>')
73
+ str << ('<c:v>' << clean_value << '</c:v>')
73
74
  str << '</c:pt>'
74
75
  str << '</c:strCache>'
75
76
  str << '</c:strRef>'
@@ -80,7 +81,7 @@ module Axlsx
80
81
  str << '<a:p>'
81
82
  str << '<a:r>'
82
83
  str << ('<a:rPr sz="' << @text_size.to_s << '"/>')
83
- str << ('<a:t>' << @text.to_s << '</a:t>')
84
+ str << ('<a:t>' << clean_value << '</a:t>')
84
85
  str << '</a:r>'
85
86
  str << '</a:p>'
86
87
  str << '</c:rich>'
data/lib/axlsx/package.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
  module Axlsx
3
3
  # Package is responsible for managing all the bits and peices that Open Office XML requires to make a valid
4
- # xlsx document including valdation and serialization.
4
+ # xlsx document including validation and serialization.
5
5
  class Package
6
6
  include Axlsx::OptionsParser
7
7
 
@@ -68,23 +68,20 @@ module Axlsx
68
68
  @workbook
69
69
  end
70
70
 
71
- #def self.parse(input, confirm_valid = false)
72
- # p = Package.new
73
- # z = Zip::File.open(input)
74
- # p.workbook = Workbook.parse z.get_entry(WORKBOOK_PN)
75
- # p
76
- #end
77
-
78
71
  # @see workbook
79
72
  def workbook=(workbook) DataTypeValidator.validate :Package_workbook, Workbook, workbook; @workbook = workbook; end
80
73
 
81
74
  # Serialize your workbook to disk as an xlsx document.
82
75
  #
83
76
  # @param [String] output The name of the file you want to serialize your package to
84
- # @param [Boolean] confirm_valid Validate the package prior to serialization.
77
+ # @param [Hash] options
78
+ # @option options [Boolean] :confirm_valid Validate the package prior to serialization.
79
+ # @option options [String] :zip_command When `nil`, `#serialize` with RubyZip to
80
+ # zip the XLSX file contents. When a String, the provided zip command (e.g.,
81
+ # "zip") is used to zip the file contents (may be faster for large files)
85
82
  # @return [Boolean] False if confirm_valid and validation errors exist. True if the package was serialized
86
83
  # @note A tremendous amount of effort has gone into ensuring that you cannot create invalid xlsx documents.
87
- # confirm_valid should be used in the rare case that you cannot open the serialized file.
84
+ # options[:confirm_valid] should be used in the rare case that you cannot open the serialized file.
88
85
  # @see Package#validate
89
86
  # @example
90
87
  # # This is how easy it is to create a valid xlsx file. Of course you might want to add a sheet or two, and maybe some data, styles and charts.
@@ -95,16 +92,29 @@ module Axlsx
95
92
  # # ......add cool stuff to your workbook......
96
93
  # p.serialize("example.xlsx")
97
94
  #
95
+ # # Serialize to a file, using a system zip binary
96
+ # p.serialize("example.xlsx", zip_command: "zip", confirm_valid: false)
97
+ # p.serialize("example.xlsx", zip_command: "/path/to/zip")
98
+ # p.serialize("example.xlsx", zip_command: "zip -1")
99
+ #
98
100
  # # Serialize to a stream
99
101
  # s = p.to_stream()
100
102
  # File.open('example_streamed.xlsx', 'w') { |f| f.write(s.read) }
101
- def serialize(output, confirm_valid=false)
103
+ def serialize(output, options = {}, secondary_options = nil)
104
+ confirm_valid, zip_command = parse_serialize_options(options, secondary_options)
102
105
  return false unless !confirm_valid || self.validate.empty?
103
- Relationship.clear_cached_instances
104
- Zip::OutputStream.open(output) do |zip|
106
+ zip_provider = if zip_command
107
+ ZipCommand.new(zip_command)
108
+ else
109
+ Zip::OutputStream
110
+ end
111
+ Relationship.initialize_ids_cache
112
+ zip_provider.open(output) do |zip|
105
113
  write_parts(zip)
106
114
  end
107
115
  true
116
+ ensure
117
+ Relationship.clear_ids_cache
108
118
  end
109
119
 
110
120
 
@@ -113,11 +123,13 @@ module Axlsx
113
123
  # @return [StringIO|Boolean] False if confirm_valid and validation errors exist. rewound string IO if not.
114
124
  def to_stream(confirm_valid=false)
115
125
  return false unless !confirm_valid || self.validate.empty?
116
- Relationship.clear_cached_instances
126
+ Relationship.initialize_ids_cache
117
127
  zip = write_parts(Zip::OutputStream.new(StringIO.new, true))
118
128
  stream = zip.close_buffer
119
129
  stream.rewind
120
130
  stream
131
+ ensure
132
+ Relationship.clear_ids_cache
121
133
  end
122
134
 
123
135
  # Encrypt the package into a CFB using the password provided
@@ -135,7 +147,7 @@ module Axlsx
135
147
  # dcterms and xml namespaces. Those remote schema are included in this gem, and the original files have been altered to
136
148
  # refer to the local versions.
137
149
  #
138
- # If by chance you are able to creat a package that does not validate it indicates that the internal
150
+ # If by chance you are able to create a package that does not validate it indicates that the internal
139
151
  # validation is not robust enough and needs to be improved. Please report your errors to the gem author.
140
152
  # @see http://www.ecma-international.org/publications/standards/Ecma-376.htm
141
153
  # @example
@@ -156,8 +168,8 @@ module Axlsx
156
168
  private
157
169
 
158
170
  # Writes the package parts to a zip archive.
159
- # @param [Zip::OutputStream] zip
160
- # @return [Zip::OutputStream]
171
+ # @param [Zip::OutputStream, ZipCommand] zip
172
+ # @return [Zip::OutputStream, ZipCommand]
161
173
  def write_parts(zip)
162
174
  p = parts
163
175
  p.each do |part|
@@ -167,7 +179,7 @@ module Axlsx
167
179
  end
168
180
  unless part[:path].nil?
169
181
  zip.put_next_entry(zip_entry_for_part(part))
170
- zip.write IO.read(part[:path])
182
+ zip.write IO.read(part[:path], mode: "rb")
171
183
  end
172
184
  end
173
185
  zip
@@ -349,6 +361,28 @@ module Axlsx
349
361
  rels.lock
350
362
  rels
351
363
  end
364
+
365
+ # Parse the arguments of `#serialize`
366
+ # @return [Boolean, (String or nil)] Returns an array where the first value is
367
+ # `confirm_valid` and the second is the `zip_command`.
368
+ # @private
369
+ def parse_serialize_options(options, secondary_options)
370
+ if secondary_options
371
+ warn "[DEPRECATION] Axlsx::Package#serialize with 3 arguments is deprecated. " +
372
+ "Use keyword args instead e.g., package.serialize(output, confirm_valid: false, zip_command: 'zip')"
373
+ end
374
+ if options.is_a?(Hash)
375
+ options.merge!(secondary_options || {})
376
+ invalid_keys = options.keys - [:confirm_valid, :zip_command]
377
+ if invalid_keys.any?
378
+ raise ArgumentError.new("Invalid keyword arguments: #{invalid_keys}")
379
+ end
380
+ [options.fetch(:confirm_valid, false), options.fetch(:zip_command, nil)]
381
+ else
382
+ warn "[DEPRECATION] Axlsx::Package#serialize with confirm_valid as a boolean is deprecated. " +
383
+ "Use keyword args instead e.g., package.serialize(output, confirm_valid: false)"
384
+ parse_serialize_options((secondary_options || {}).merge(confirm_valid: options), nil)
385
+ end
386
+ end
352
387
  end
353
388
  end
354
-
@@ -5,32 +5,40 @@ module Axlsx
5
5
  class Relationship
6
6
 
7
7
  class << self
8
- # Keeps track of all instances of this class.
8
+ # Keeps track of relationship ids in use.
9
9
  # @return [Array]
10
- def instances
11
- @instances ||= []
10
+ def ids_cache
11
+ Thread.current[:axlsx_relationship_ids_cache] ||= {}
12
12
  end
13
-
14
- # Clear cached instances.
13
+
14
+ # Initialize cached ids.
15
15
  #
16
16
  # This should be called before serializing a package (see {Package#serialize} and
17
17
  # {Package#to_stream}) to make sure that serialization is idempotent (i.e.
18
18
  # Relationship instances are generated with the same IDs everytime the package
19
19
  # is serialized).
20
+ def initialize_ids_cache
21
+ Thread.current[:axlsx_relationship_ids_cache] = {}
22
+ end
23
+
24
+ # Clear cached ids.
20
25
  #
21
- # Also, calling this avoids memory leaks (cached instances lingering around
26
+ # This should be called after serializing a package (see {Package#serialize} and
27
+ # {Package#to_stream}) to free the memory allocated for cache.
28
+ #
29
+ # Also, calling this avoids memory leaks (cached ids lingering around
22
30
  # forever).
23
- def clear_cached_instances
24
- @instances = []
31
+ def clear_ids_cache
32
+ Thread.current[:axlsx_relationship_ids_cache] = nil
25
33
  end
26
34
 
27
35
  # Generate and return a unique id (eg. `rId123`) Used for setting {#Id}.
28
36
  #
29
- # The generated id depends on the number of cached instances, so using
30
- # {clear_cached_instances} will automatically reset the generated ids, too.
37
+ # The generated id depends on the number of previously cached ids, so using
38
+ # {clear_ids_cache} will automatically reset the generated ids, too.
31
39
  # @return [String]
32
40
  def next_free_id
33
- "rId#{@instances.size + 1}"
41
+ "rId#{ids_cache.size + 1}"
34
42
  end
35
43
  end
36
44
 
@@ -80,12 +88,7 @@ module Axlsx
80
88
  self.Target=target
81
89
  self.Type=type
82
90
  self.TargetMode = options[:target_mode] if options[:target_mode]
83
- @Id = if (existing = self.class.instances.find{ |i| should_use_same_id_as?(i) })
84
- existing.Id
85
- else
86
- self.class.next_free_id
87
- end
88
- self.class.instances << self
91
+ @Id = (self.class.ids_cache[ids_cache_key] ||= self.class.next_free_id)
89
92
  end
90
93
 
91
94
  # @see Target
@@ -106,7 +109,7 @@ module Axlsx
106
109
  str << '/>'
107
110
  end
108
111
 
109
- # Whether this relationship should use the same id as `other`.
112
+ # A key that determines whether this relationship should use already generated id.
110
113
  #
111
114
  # Instances designating the same relationship need to use the same id. We can not simply
112
115
  # compare the {#Target} attribute, though: `foo/bar.xml`, `../foo/bar.xml`,
@@ -116,13 +119,11 @@ module Axlsx
116
119
  # then {#Target} will be an absolute URL and thus can safely be compared).
117
120
  #
118
121
  # @todo Implement comparison of {#Target} based on normalized path names.
119
- # @param other [Relationship]
120
- def should_use_same_id_as?(other)
121
- result = self.source_obj == other.source_obj && self.Type == other.Type && self.TargetMode == other.TargetMode
122
- if self.TargetMode == :External
123
- result &&= self.Target == other.Target
124
- end
125
- result
122
+ # @return [Array]
123
+ def ids_cache_key
124
+ key = [source_obj, self.Type, self.TargetMode]
125
+ key << self.Target if self.TargetMode == :External
126
+ key
126
127
  end
127
128
 
128
129
  end
@@ -76,7 +76,10 @@ module Axlsx
76
76
  attr_reader :i
77
77
 
78
78
  # Indicates if the font should be rendered underlined
79
- # @return [Boolean]
79
+ # It must be one of :none, :single, :double, :singleAccounting, :doubleAccounting, true, false
80
+ # @return [String]
81
+ # @note
82
+ # true or false is for backwards compatibility and is reassigned to :single or :none respectively
80
83
  attr_reader :u
81
84
 
82
85
  # Indicates if the font should be rendered with a strikthrough
@@ -118,7 +121,12 @@ module Axlsx
118
121
  # @see i
119
122
  def i=(v) Axlsx::validate_boolean v; @i = v end
120
123
  # @see u
121
- def u=(v) Axlsx::validate_boolean v; @u = v end
124
+ def u=(v)
125
+ v = :single if (v == true || v == 1 || v == :true || v == 'true')
126
+ v = :none if (v == false || v == 0 || v == :false || v == 'false')
127
+ Axlsx::validate_cell_u v
128
+ @u = v
129
+ end
122
130
  # @see strike
123
131
  def strike=(v) Axlsx::validate_boolean v; @strike = v end
124
132
  # @see outline
@@ -393,7 +393,8 @@ module Axlsx
393
393
  ISO_8601_REGEX = /\A(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[0-1]|0[1-9]|[1-2][0-9])T(2[0-3]|[0-1][0-9]):([0-5][0-9]):([0-5][0-9])(\.[0-9]+)?(Z|[+-](?:2[0-3]|[0-1][0-9]):[0-5][0-9])?\Z/.freeze
394
394
 
395
395
  # FLOAT recognition
396
- FLOAT_REGEX = /\A[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?\Z/.freeze
396
+ SAFE_FLOAT_REGEX = /\A[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]{1,2})?\Z/.freeze
397
+ MAYBE_FLOAT_REGEX = /\A[-+]?[0-9]*\.?[0-9]+[eE](?<exp>[-+]?[0-9]{3})\Z/.freeze
397
398
 
398
399
  # Numeric recognition
399
400
  NUMERIC_REGEX = /\A[+-]?\d+?\Z/.freeze
@@ -5,7 +5,7 @@ module Axlsx
5
5
  # @param [String] v File path
6
6
  # @return [String] File mime type
7
7
  def self.get_mime_type(v)
8
- MimeMagic.by_magic(File.open(v)).to_s
8
+ Marcel::MimeType.for(Pathname.new(v))
9
9
  end
10
10
  end
11
11
  end
@@ -92,7 +92,7 @@ module Axlsx
92
92
 
93
93
  # Requires that the value is a Integer or Float and is greater or equal to 0
94
94
  # @param [Any] v The value validated
95
- # @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
96
96
  # @return [Boolean] true if the data is valid
97
97
  def self.validate_unsigned_numeric(v)
98
98
  DataTypeValidator.validate(:unsigned_numeric, Numeric, v, UINT_VALIDATOR)
@@ -269,7 +269,7 @@ module Axlsx
269
269
  # valid types must be one of custom, data, decimal, list, none, textLength, time, whole
270
270
  # @param [Any] v The value validated
271
271
  def self.validate_data_validation_type(v)
272
- 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
273
273
  end
274
274
 
275
275
  # Requires that the value is a valid sheet view type.