caxlsx 4.0.0 → 4.4.1

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.
Files changed (133) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +48 -12
  3. data/README.md +18 -9
  4. data/Rakefile +2 -9
  5. data/examples/generate.rb +3 -1
  6. data/lib/axlsx/content_type/abstract_content_type.rb +6 -3
  7. data/lib/axlsx/content_type/content_type.rb +4 -4
  8. data/lib/axlsx/content_type/default.rb +4 -1
  9. data/lib/axlsx/content_type/override.rb +4 -1
  10. data/lib/axlsx/doc_props/app.rb +91 -24
  11. data/lib/axlsx/drawing/area_chart.rb +3 -3
  12. data/lib/axlsx/drawing/area_series.rb +10 -4
  13. data/lib/axlsx/drawing/ax_data_source.rb +1 -1
  14. data/lib/axlsx/drawing/axes.rb +1 -1
  15. data/lib/axlsx/drawing/axis.rb +25 -7
  16. data/lib/axlsx/drawing/bar_3D_chart.rb +14 -4
  17. data/lib/axlsx/drawing/bar_chart.rb +14 -4
  18. data/lib/axlsx/drawing/bar_series.rb +14 -5
  19. data/lib/axlsx/drawing/bubble_chart.rb +2 -2
  20. data/lib/axlsx/drawing/bubble_series.rb +2 -2
  21. data/lib/axlsx/drawing/cat_axis.rb +23 -8
  22. data/lib/axlsx/drawing/chart.rb +33 -8
  23. data/lib/axlsx/drawing/d_lbls.rb +9 -8
  24. data/lib/axlsx/drawing/drawing.rb +50 -49
  25. data/lib/axlsx/drawing/hyperlink.rb +13 -4
  26. data/lib/axlsx/drawing/line_3D_chart.rb +3 -3
  27. data/lib/axlsx/drawing/line_chart.rb +3 -3
  28. data/lib/axlsx/drawing/line_series.rb +10 -4
  29. data/lib/axlsx/drawing/marker.rb +19 -4
  30. data/lib/axlsx/drawing/num_val.rb +1 -1
  31. data/lib/axlsx/drawing/one_cell_anchor.rb +8 -2
  32. data/lib/axlsx/drawing/pic.rb +17 -8
  33. data/lib/axlsx/drawing/pie_3D_chart.rb +3 -3
  34. data/lib/axlsx/drawing/pie_chart.rb +36 -0
  35. data/lib/axlsx/drawing/pie_series.rb +18 -6
  36. data/lib/axlsx/drawing/scaling.rb +18 -4
  37. data/lib/axlsx/drawing/scatter_chart.rb +2 -2
  38. data/lib/axlsx/drawing/scatter_series.rb +2 -2
  39. data/lib/axlsx/drawing/ser_axis.rb +11 -5
  40. data/lib/axlsx/drawing/series.rb +8 -2
  41. data/lib/axlsx/drawing/two_cell_anchor.rb +1 -1
  42. data/lib/axlsx/drawing/val_axis.rb +2 -2
  43. data/lib/axlsx/drawing/view_3D.rb +8 -2
  44. data/lib/axlsx/drawing/vml_shape.rb +1 -1
  45. data/lib/axlsx/package.rb +54 -21
  46. data/lib/axlsx/rels/relationship.rb +15 -5
  47. data/lib/axlsx/rels/relationships.rb +3 -3
  48. data/lib/axlsx/stylesheet/border.rb +12 -3
  49. data/lib/axlsx/stylesheet/border_pr.rb +16 -4
  50. data/lib/axlsx/stylesheet/cell_alignment.rb +39 -10
  51. data/lib/axlsx/stylesheet/cell_protection.rb +9 -2
  52. data/lib/axlsx/stylesheet/cell_style.rb +30 -7
  53. data/lib/axlsx/stylesheet/color.rb +10 -4
  54. data/lib/axlsx/stylesheet/dxf.rb +29 -6
  55. data/lib/axlsx/stylesheet/fill.rb +4 -1
  56. data/lib/axlsx/stylesheet/font.rb +59 -13
  57. data/lib/axlsx/stylesheet/gradient_fill.rb +9 -3
  58. data/lib/axlsx/stylesheet/gradient_stop.rb +9 -2
  59. data/lib/axlsx/stylesheet/num_fmt.rb +8 -2
  60. data/lib/axlsx/stylesheet/pattern_fill.rb +15 -3
  61. data/lib/axlsx/stylesheet/styles.rb +84 -43
  62. data/lib/axlsx/stylesheet/table_style.rb +15 -4
  63. data/lib/axlsx/stylesheet/table_style_element.rb +12 -3
  64. data/lib/axlsx/stylesheet/table_styles.rb +10 -3
  65. data/lib/axlsx/stylesheet/theme.rb +163 -0
  66. data/lib/axlsx/stylesheet/xf.rb +70 -16
  67. data/lib/axlsx/util/accessors.rb +9 -7
  68. data/lib/axlsx/util/buffered_zip_output_stream.rb +6 -2
  69. data/lib/axlsx/util/constants.rb +14 -2
  70. data/lib/axlsx/util/mime_type_utils.rb +72 -13
  71. data/lib/axlsx/util/serialized_attributes.rb +2 -2
  72. data/lib/axlsx/util/simple_typed_list.rb +26 -14
  73. data/lib/axlsx/util/storage.rb +4 -4
  74. data/lib/axlsx/util/uri_utils.rb +70 -0
  75. data/lib/axlsx/util/validators.rb +6 -6
  76. data/lib/axlsx/version.rb +1 -1
  77. data/lib/axlsx/workbook/defined_name.rb +2 -1
  78. data/lib/axlsx/workbook/defined_names.rb +1 -1
  79. data/lib/axlsx/workbook/shared_strings_table.rb +3 -3
  80. data/lib/axlsx/workbook/workbook.rb +87 -67
  81. data/lib/axlsx/workbook/workbook_view.rb +1 -1
  82. data/lib/axlsx/workbook/workbook_views.rb +1 -1
  83. data/lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb +4 -4
  84. data/lib/axlsx/workbook/worksheet/auto_filter/filter_column.rb +5 -3
  85. data/lib/axlsx/workbook/worksheet/auto_filter/filters.rb +4 -4
  86. data/lib/axlsx/workbook/worksheet/auto_filter/sort_condition.rb +1 -1
  87. data/lib/axlsx/workbook/worksheet/auto_filter/sort_state.rb +2 -2
  88. data/lib/axlsx/workbook/worksheet/border_creator.rb +4 -4
  89. data/lib/axlsx/workbook/worksheet/cell.rb +40 -20
  90. data/lib/axlsx/workbook/worksheet/cell_serializer.rb +1 -1
  91. data/lib/axlsx/workbook/worksheet/cfvo.rb +8 -2
  92. data/lib/axlsx/workbook/worksheet/col.rb +23 -9
  93. data/lib/axlsx/workbook/worksheet/col_breaks.rb +1 -1
  94. data/lib/axlsx/workbook/worksheet/cols.rb +1 -1
  95. data/lib/axlsx/workbook/worksheet/comment.rb +2 -2
  96. data/lib/axlsx/workbook/worksheet/comments.rb +1 -1
  97. data/lib/axlsx/workbook/worksheet/conditional_formatting.rb +9 -3
  98. data/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb +70 -15
  99. data/lib/axlsx/workbook/worksheet/conditional_formattings.rb +3 -3
  100. data/lib/axlsx/workbook/worksheet/data_validation.rb +53 -14
  101. data/lib/axlsx/workbook/worksheet/data_validations.rb +3 -3
  102. data/lib/axlsx/workbook/worksheet/date_time_converter.rb +2 -2
  103. data/lib/axlsx/workbook/worksheet/dimension.rb +1 -1
  104. data/lib/axlsx/workbook/worksheet/header_footer.rb +1 -1
  105. data/lib/axlsx/workbook/worksheet/icon_set.rb +17 -5
  106. data/lib/axlsx/workbook/worksheet/merged_cells.rb +1 -1
  107. data/lib/axlsx/workbook/worksheet/outline_pr.rb +1 -1
  108. data/lib/axlsx/workbook/worksheet/page_margins.rb +30 -7
  109. data/lib/axlsx/workbook/worksheet/page_set_up_pr.rb +1 -2
  110. data/lib/axlsx/workbook/worksheet/page_setup.rb +32 -9
  111. data/lib/axlsx/workbook/worksheet/pane.rb +9 -2
  112. data/lib/axlsx/workbook/worksheet/pivot_table.rb +30 -6
  113. data/lib/axlsx/workbook/worksheet/pivot_tables.rb +1 -1
  114. data/lib/axlsx/workbook/worksheet/print_options.rb +1 -0
  115. data/lib/axlsx/workbook/worksheet/protected_ranges.rb +1 -1
  116. data/lib/axlsx/workbook/worksheet/rich_text_run.rb +31 -11
  117. data/lib/axlsx/workbook/worksheet/row.rb +5 -2
  118. data/lib/axlsx/workbook/worksheet/row_breaks.rb +1 -1
  119. data/lib/axlsx/workbook/worksheet/selection.rb +8 -2
  120. data/lib/axlsx/workbook/worksheet/sheet_calc_pr.rb +1 -0
  121. data/lib/axlsx/workbook/worksheet/sheet_pr.rb +1 -1
  122. data/lib/axlsx/workbook/worksheet/sheet_protection.rb +1 -1
  123. data/lib/axlsx/workbook/worksheet/sheet_view.rb +30 -9
  124. data/lib/axlsx/workbook/worksheet/table_style_info.rb +3 -2
  125. data/lib/axlsx/workbook/worksheet/tables.rb +1 -1
  126. data/lib/axlsx/workbook/worksheet/worksheet.rb +28 -14
  127. data/lib/axlsx/workbook/worksheet/worksheet_comments.rb +4 -4
  128. data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +1 -1
  129. data/lib/axlsx/workbook/worksheet/worksheet_hyperlink.rb +3 -2
  130. data/lib/axlsx/workbook/worksheet/worksheet_hyperlinks.rb +2 -2
  131. data/lib/axlsx.rb +46 -30
  132. data/lib/caxlsx.rb +1 -1
  133. metadata +13 -52
@@ -9,6 +9,10 @@ module Axlsx
9
9
  # The 4_096 was chosen somewhat arbitrary, however, it was difficult to see any obvious improvement with larger
10
10
  # buffer sizes.
11
11
  BUFFER_SIZE = 4_096
12
+ # The suppress_extra_fields method was introduced in rubyzip 3.2
13
+ # Between rubyzip 3.0 and 3.2, it automatically writes zip64 support to the xlsx files
14
+ # See: https://github.com/caxlsx/caxlsx/issues/481
15
+ SUPPRESS_ZIP64 = Zip::OutputStream.method(:open).parameters.any? { |_, key| key == :suppress_extra_fields } ? { suppress_extra_fields: :zip64 } : {}
12
16
 
13
17
  def initialize(zos)
14
18
  @zos = zos
@@ -19,7 +23,7 @@ module Axlsx
19
23
  #
20
24
  # The directory and its contents are removed at the end of the block.
21
25
  def self.open(file_name, encrypter = nil)
22
- Zip::OutputStream.open(file_name, encrypter) do |zos|
26
+ Zip::OutputStream.open(file_name, encrypter: encrypter, **SUPPRESS_ZIP64) do |zos|
23
27
  bzos = new(zos)
24
28
  yield(bzos)
25
29
  ensure
@@ -28,7 +32,7 @@ module Axlsx
28
32
  end
29
33
 
30
34
  def self.write_buffer(io = ::StringIO.new, encrypter = nil)
31
- Zip::OutputStream.write_buffer(io, encrypter) do |zos|
35
+ Zip::OutputStream.write_buffer(io, encrypter: encrypter, **SUPPRESS_ZIP64) do |zos|
32
36
  bzos = new(zos)
33
37
  yield(bzos)
34
38
  ensure
@@ -79,6 +79,9 @@ module Axlsx
79
79
  # shared strings namespace
80
80
  SHARED_STRINGS_R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings"
81
81
 
82
+ # theme rels namespace
83
+ THEME_R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme"
84
+
82
85
  # drawing rels namespace
83
86
  DRAWING_R = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing"
84
87
 
@@ -133,6 +136,9 @@ module Axlsx
133
136
  # shared strings content type
134
137
  SHARED_STRINGS_CT = "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml"
135
138
 
139
+ # theme content type
140
+ THEME_CT = "application/vnd.openxmlformats-officedocument.theme+xml"
141
+
136
142
  # core content type
137
143
  CORE_CT = "application/vnd.openxmlformats-package.core-properties+xml"
138
144
 
@@ -187,6 +193,9 @@ module Axlsx
187
193
  # shared_strings part
188
194
  SHARED_STRINGS_PN = "sharedStrings.xml"
189
195
 
196
+ # theme part
197
+ THEME_PN = "theme/theme1.xml"
198
+
190
199
  # app part
191
200
  APP_PN = "docProps/app.xml"
192
201
 
@@ -259,7 +268,10 @@ module Axlsx
259
268
  # drawing validation schema
260
269
  DRAWING_XSD = "#{SCHEMA_BASE}dml-spreadsheetDrawing.xsd"
261
270
 
262
- # number format id for pecentage formatting using the default formatting id.
271
+ # theme validation schema
272
+ THEME_XSD = "#{SCHEMA_BASE}dml-main.xsd"
273
+
274
+ # number format id for percentage formatting using the default formatting id.
263
275
  NUM_FMT_PERCENT = 9
264
276
 
265
277
  # number format id for date format like 2011/11/13
@@ -404,7 +416,7 @@ module Axlsx
404
416
  CONTROL_CHARS = pattern.freeze
405
417
 
406
418
  # ISO 8601 date recognition
407
- 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
419
+ 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/.freeze
408
420
 
409
421
  # FLOAT recognition
410
422
  SAFE_FLOAT_REGEX = /\A[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]{1,2})?\Z/.freeze
@@ -1,22 +1,81 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'open-uri'
4
-
5
3
  module Axlsx
6
4
  # This module defines some utils related with mime type detection
7
5
  module MimeTypeUtils
8
- # Detect a file mime type
9
- # @param [String] v File path
10
- # @return [String] File mime type
11
- def self.get_mime_type(v)
12
- Marcel::MimeType.for(Pathname.new(v))
13
- end
6
+ # Extension to MIME type mapping for Windows fallback
7
+ EXTENSION_FALLBACKS = {
8
+ '.jpg' => 'image/jpeg',
9
+ '.jpeg' => 'image/jpeg',
10
+ '.png' => 'image/png',
11
+ '.gif' => 'image/gif'
12
+ }.freeze
13
+
14
+ class << self
15
+ # Detect a file mime type
16
+ # @param [String] v File path
17
+ # @return [String] File mime type
18
+ def get_mime_type(v)
19
+ mime_type = Marcel::MimeType.for(Pathname.new(v))
20
+
21
+ # Windows fallback: Marcel sometimes returns application/octet-stream for valid image files
22
+ if mime_type == 'application/octet-stream' && windows_platform?
23
+ extension = File.extname(v).downcase
24
+ # Verify it's actually an image by checking the file header
25
+ if EXTENSION_FALLBACKS.key?(extension) && File.exist?(v) && valid_image_file?(v, extension)
26
+ mime_type = EXTENSION_FALLBACKS[extension]
27
+ end
28
+ end
29
+
30
+ mime_type
31
+ end
32
+
33
+ # Detect a file mime type from URI
34
+ # @param [String] v URI
35
+ # @return [String] File mime type
36
+ def get_mime_type_from_uri(v)
37
+ uri = URI.parse(v)
38
+
39
+ unless uri.is_a?(URI::HTTP) || uri.is_a?(URI::HTTPS)
40
+ raise URI::InvalidURIError, "Only HTTP/HTTPS URIs are supported"
41
+ end
42
+
43
+ response = UriUtils.fetch_headers(uri)
44
+ mime_type = response&.[]('content-type')&.split(';')&.first&.strip
45
+
46
+ if mime_type.nil? || mime_type.empty?
47
+ raise ArgumentError, "Unable to determine MIME type from response"
48
+ end
49
+
50
+ mime_type
51
+ end
52
+
53
+ private
54
+
55
+ def windows_platform?
56
+ RUBY_PLATFORM =~ /mswin|mingw|cygwin/
57
+ end
58
+
59
+ def valid_image_file?(file_path, extension)
60
+ return false unless File.exist?(file_path)
14
61
 
15
- # Detect a file mime type from URI
16
- # @param [String] v URI
17
- # @return [String] File mime type
18
- def self.get_mime_type_from_uri(v)
19
- Marcel::MimeType.for(URI.parse(v).open)
62
+ # Check magic bytes for common image formats
63
+ begin
64
+ header = File.binread(file_path, 10)
65
+ case extension
66
+ when '.jpg', '.jpeg'
67
+ header[0..2].bytes == [0xFF, 0xD8, 0xFF] # JPEG magic bytes
68
+ when '.png'
69
+ header[0..7].bytes == [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A] # PNG magic bytes
70
+ when '.gif'
71
+ header[0..2] == 'GIF' # GIF magic bytes
72
+ else
73
+ false
74
+ end
75
+ rescue StandardError
76
+ false
77
+ end
78
+ end
20
79
  end
21
80
  end
22
81
  end
@@ -91,8 +91,8 @@ module Axlsx
91
91
 
92
92
  # serialized instance values at text nodes on a camelized element of the
93
93
  # attribute name. You may pass in a block for evaluation against non nil
94
- # values. We use an array for element attributes becuase misordering will
95
- # break the xml and 1.8.7 does not support ordered hashes.
94
+ # values. We use an array for element attributes because misordering will
95
+ # break the xml.
96
96
  # @param [String] str The string instance to which serialized data is appended
97
97
  # @param [Array] additional_attributes An array of additional attribute names.
98
98
  # @return [String] The serialized output.
@@ -21,7 +21,7 @@ module Axlsx
21
21
  alias :== :equal?
22
22
  alias :eql? :equal?
23
23
 
24
- # Creats a new typed list
24
+ # Creates a new typed list
25
25
  # @param [Array, Class] type An array of Class objects or a single Class object
26
26
  # @param [String] serialize_as The tag name to use in serialization
27
27
  # @raise [ArgumentError] if all members of type are not Class objects
@@ -57,7 +57,7 @@ module Axlsx
57
57
  # Transposes the list (without blowing up like ruby does)
58
58
  # any non populated cell in the matrix will be a nil value
59
59
  def transpose
60
- return clone if size.zero?
60
+ return clone if size == 0
61
61
 
62
62
  row_count = size
63
63
  max_column_count = map { |row| row.cells.size }.max
@@ -90,21 +90,24 @@ module Axlsx
90
90
  self
91
91
  end
92
92
 
93
- # join operator
94
- # @param [Array] other the array to join
93
+ # Appends the elements of +others+ to self.
94
+ # @param [Array<Array>] others one or more arrays to join
95
95
  # @raise [ArgumentError] if any of the values being joined are not
96
96
  # one of the allowed types
97
97
  # @return [SimpleTypedList]
98
- def +(other)
99
- other.each do |item|
100
- self << item
98
+ def concat(*others)
99
+ others.each do |other|
100
+ other.each do |item|
101
+ self << item
102
+ end
101
103
  end
102
- super
104
+ self
103
105
  end
104
106
 
105
- # Concat operator
107
+ # Pushes the given object on to the end of this array and returns the index
108
+ # of the item added.
106
109
  # @param [Any] v the data to be added
107
- # @raise [ArgumentError] if the value being added is not one fo the allowed types
110
+ # @raise [ArgumentError] if the value being added is not one of the allowed types
108
111
  # @return [Integer] returns the index of the item added.
109
112
  def <<(v)
110
113
  DataTypeValidator.validate :SimpleTypedList_push, @allowed_types, v
@@ -112,7 +115,17 @@ module Axlsx
112
115
  size - 1
113
116
  end
114
117
 
115
- alias :push :<<
118
+ # Pushes the given object(s) on to the end of this array. This expression
119
+ # returns the array itself, so several appends may be chained together.
120
+ # @param [Any] values the data to be added
121
+ # @raise [ArgumentError] if any of the values being joined are not
122
+ # @return [SimpleTypedList]
123
+ def push(*values)
124
+ values.each do |value|
125
+ self << value
126
+ end
127
+ self
128
+ end
116
129
 
117
130
  # delete the item from the list
118
131
  # @param [Any] v The item to be deleted.
@@ -147,7 +160,7 @@ module Axlsx
147
160
  super
148
161
  end
149
162
 
150
- # inserts an item at the index specfied
163
+ # inserts an item at the index specified
151
164
  # @param [Integer] index
152
165
  # @param [Any] v
153
166
  # @raise [ArgumentError] if the index is protected by locking
@@ -170,8 +183,7 @@ module Axlsx
170
183
  end
171
184
 
172
185
  def to_xml_string(str = +'')
173
- classname = @allowed_types[0].name.split('::').last
174
- el_name = serialize_as.to_s || (classname[0, 1].downcase + classname[1..])
186
+ el_name = serialize_as.to_s
175
187
  str << '<' << el_name << ' count="' << size.to_s << '">'
176
188
  each { |item| item.to_xml_string(str) }
177
189
  str << '</' << el_name << '>'
@@ -85,16 +85,16 @@ module Axlsx
85
85
  # @return [Integer] sector
86
86
  attr_accessor :sector
87
87
 
88
- # The 0 based index in the directoies chain for this the left sibling of this storage.
88
+ # The 0 based index in the directories chain for this the left sibling of this storage.
89
89
 
90
90
  # @return [Integer] left
91
91
  attr_accessor :left
92
92
 
93
- # The 0 based index in the directoies chain for this the right sibling of this storage.
93
+ # The 0 based index in the directories chain for this the right sibling of this storage.
94
94
  # @return [Integer] right
95
95
  attr_accessor :right
96
96
 
97
- # The 0 based index in the directoies chain for the child of this storage.
97
+ # The 0 based index in the directories chain for the child of this storage.
98
98
  # @return [Integer] child
99
99
  attr_accessor :child
100
100
 
@@ -133,7 +133,7 @@ module Axlsx
133
133
  @left = @right = @child = -1
134
134
  @sector = @size = @created = @modified = 0
135
135
  options.each do |o|
136
- send("#{o[0]}=", o[1]) if respond_to? "#{o[0]}="
136
+ send(:"#{o[0]}=", o[1]) if respond_to? :"#{o[0]}="
137
137
  end
138
138
  @color ||= COLORS[:black]
139
139
  @type ||= (data.nil? ? TYPES[:storage] : TYPES[:stream])
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http'
4
+ require 'uri'
5
+
6
+ module Axlsx
7
+ # This module defines some utils related to mime type detection
8
+ module UriUtils
9
+ class << self
10
+ # Performs an HTTP GeT request fetching only headers
11
+ def fetch_headers(uri, redirect_limit = 5)
12
+ redirect_count = 0
13
+ use_get = false
14
+
15
+ while redirect_count < redirect_limit
16
+ case (response = fetch_headers_request(uri, use_get: use_get))
17
+ when Net::HTTPSuccess
18
+ return response
19
+ when Net::HTTPMethodNotAllowed, Net::HTTPNotImplemented
20
+ fail_response(response) if use_get
21
+ use_get = true
22
+ next # Retry current URL with GET
23
+ when Net::HTTPRedirection
24
+ uri = follow_redirect(uri, response)
25
+ redirect_count += 1
26
+ else
27
+ fail_response(response)
28
+ end
29
+ end
30
+
31
+ raise ArgumentError, "Too many redirects (exceeded #{redirect_limit})"
32
+ end
33
+
34
+ private
35
+
36
+ def fetch_headers_request(uri, use_get: false)
37
+ Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
38
+ path = build_path(uri)
39
+ if use_get
40
+ http.request_get(path) { |response| break(response) } # Exit early with just headers
41
+ else
42
+ http.head(path)
43
+ end
44
+ end
45
+ end
46
+
47
+ def build_path(uri)
48
+ "#{uri.path.empty? ? '/' : uri.path}#{"?#{uri.query}" if uri.query}"
49
+ end
50
+
51
+ def follow_redirect(original_uri, response)
52
+ location = response['location']
53
+
54
+ if location.nil? || location.empty?
55
+ raise ArgumentError, "Redirect response missing Location header"
56
+ end
57
+
58
+ if location.start_with?('http://', 'https://')
59
+ URI.parse(location)
60
+ else
61
+ URI.join(original_uri, location)
62
+ end
63
+ end
64
+
65
+ def fail_response(response)
66
+ raise ArgumentError, "Failed to fetch resource: #{response.code} #{response.message}"
67
+ end
68
+ end
69
+ end
70
+ end
@@ -9,7 +9,7 @@ module Axlsx
9
9
  # @param [Any] v The value to be validated
10
10
  # @raise [ArgumentError] Raised if the value provided is not in the list of choices.
11
11
  # @return [Boolean] true if validation succeeds.
12
- def self.validate(name, choices, v)
12
+ def self.validate(name, choices, v) # rubocop:disable Naming/PredicateMethod
13
13
  raise ArgumentError, format(ERR_RESTRICTION, v.to_s, name, choices.inspect) unless choices.include?(v)
14
14
 
15
15
  true
@@ -81,7 +81,7 @@ module Axlsx
81
81
  raise ArgumentError, format(ERR_ANGLE, v.inspect) unless v.to_i >= -5400000 && v.to_i <= 5400000
82
82
  end
83
83
 
84
- # Validates an unsigned intger
84
+ # Validates an unsigned integer
85
85
  UINT_VALIDATOR = ->(arg) { arg.respond_to?(:>=) && arg >= 0 }
86
86
 
87
87
  # Requires that the value is a Integer and is greater or equal to 0
@@ -268,19 +268,19 @@ module Axlsx
268
268
  RestrictionValidator.validate :vertical_alignment, VALID_VERTICAL_ALIGNMENT_VALUES, v
269
269
  end
270
270
 
271
- VALID_CONTENT_TYPE_VALUES = [TABLE_CT, WORKBOOK_CT, APP_CT, RELS_CT, STYLES_CT, XML_CT, WORKSHEET_CT, SHARED_STRINGS_CT, CORE_CT, CHART_CT, JPEG_CT, GIF_CT, PNG_CT, DRAWING_CT, COMMENT_CT, VML_DRAWING_CT, PIVOT_TABLE_CT, PIVOT_TABLE_CACHE_DEFINITION_CT].freeze
271
+ VALID_CONTENT_TYPE_VALUES = [TABLE_CT, WORKBOOK_CT, APP_CT, RELS_CT, STYLES_CT, THEME_CT, XML_CT, WORKSHEET_CT, SHARED_STRINGS_CT, CORE_CT, CHART_CT, JPEG_CT, GIF_CT, PNG_CT, DRAWING_CT, COMMENT_CT, VML_DRAWING_CT, PIVOT_TABLE_CT, PIVOT_TABLE_CACHE_DEFINITION_CT].freeze
272
272
 
273
273
  # Requires that the value is a valid content_type
274
- # TABLE_CT, WORKBOOK_CT, APP_CT, RELS_CT, STYLES_CT, XML_CT, WORKSHEET_CT, SHARED_STRINGS_CT, CORE_CT, CHART_CT, DRAWING_CT, COMMENT_CT are allowed
274
+ # TABLE_CT, WORKBOOK_CT, APP_CT, RELS_CT, STYLES_CT, THEME_CT, XML_CT, WORKSHEET_CT, SHARED_STRINGS_CT, CORE_CT, CHART_CT, DRAWING_CT, COMMENT_CT are allowed
275
275
  # @param [Any] v The value validated
276
276
  def self.validate_content_type(v)
277
277
  RestrictionValidator.validate :content_type, VALID_CONTENT_TYPE_VALUES, v
278
278
  end
279
279
 
280
- VALID_RELATIONSHIP_TYPE_VALUES = [XML_NS_R, TABLE_R, WORKBOOK_R, WORKSHEET_R, APP_R, RELS_R, CORE_R, STYLES_R, CHART_R, DRAWING_R, IMAGE_R, HYPERLINK_R, SHARED_STRINGS_R, COMMENT_R, VML_DRAWING_R, COMMENT_R_NULL, PIVOT_TABLE_R, PIVOT_TABLE_CACHE_DEFINITION_R].freeze
280
+ VALID_RELATIONSHIP_TYPE_VALUES = [XML_NS_R, TABLE_R, WORKBOOK_R, WORKSHEET_R, APP_R, RELS_R, CORE_R, STYLES_R, THEME_R, CHART_R, DRAWING_R, IMAGE_R, HYPERLINK_R, SHARED_STRINGS_R, COMMENT_R, VML_DRAWING_R, COMMENT_R_NULL, PIVOT_TABLE_R, PIVOT_TABLE_CACHE_DEFINITION_R].freeze
281
281
 
282
282
  # Requires that the value is a valid relationship_type
283
- # XML_NS_R, TABLE_R, WORKBOOK_R, WORKSHEET_R, APP_R, RELS_R, CORE_R, STYLES_R, CHART_R, DRAWING_R, IMAGE_R, HYPERLINK_R, SHARED_STRINGS_R are allowed
283
+ # XML_NS_R, TABLE_R, WORKBOOK_R, WORKSHEET_R, APP_R, RELS_R, CORE_R, STYLES_R, THEME_R, CHART_R, DRAWING_R, IMAGE_R, HYPERLINK_R, SHARED_STRINGS_R are allowed
284
284
  # @param [Any] v The value validated
285
285
  def self.validate_relationship_type(v)
286
286
  RestrictionValidator.validate :relationship_type, VALID_RELATIONSHIP_TYPE_VALUES, v
data/lib/axlsx/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Axlsx
4
4
  # The current version
5
- VERSION = "4.0.0"
5
+ VERSION = "4.4.1"
6
6
  end
@@ -22,7 +22,7 @@
22
22
  # <xsd:attribute name="shortcutKey" type="s:ST_Xstring" use="optional"/>
23
23
  # <xsd:attribute name="publishToServer" type="xsd:boolean" use="optional" default="false"/>
24
24
  # <xsd:attribute name="workbookParameter" type="xsd:boolean" use="optional" default="false"/>
25
- # </xsd:extenstion>
25
+ # </xsd:extension>
26
26
  # </xsd:simpleContent>
27
27
 
28
28
  module Axlsx
@@ -54,6 +54,7 @@ module Axlsx
54
54
  include Axlsx::SerializedAttributes
55
55
  include Axlsx::OptionsParser
56
56
  include Axlsx::Accessors
57
+
57
58
  # creates a new DefinedName.
58
59
  # @param [String] formula - the formula the defined name references
59
60
  # @param [Hash] options - A hash of key/value pairs that will be mapped to this instances attributes.
@@ -5,7 +5,7 @@ module Axlsx
5
5
  class DefinedNames < SimpleTypedList
6
6
  # creates the DefinedNames object
7
7
  def initialize
8
- super DefinedName
8
+ super(DefinedName)
9
9
  end
10
10
 
11
11
  # Serialize to xml
@@ -7,7 +7,7 @@ module Axlsx
7
7
  # As a developer, you should never need to directly work against this class. Simply set 'use_shared_strings'
8
8
  # on the package or workbook to generate a package that uses the shared strings table instead of inline strings.
9
9
  # @note Serialization performance is affected by using this serialization method so if you do not need interoperability
10
- # it is recomended that you use the default inline string method of serialization.
10
+ # it is recommended that you use the default inline string method of serialization.
11
11
  class SharedStringsTable
12
12
  # The total number of strings in the workbook including duplicates
13
13
  # Empty cells are treated as blank strings
@@ -29,7 +29,7 @@ module Axlsx
29
29
  # @see Workbook#xml_space
30
30
  attr_reader :xml_space
31
31
 
32
- # Creates a new Shared Strings Table agains an array of cells
32
+ # Creates a new Shared Strings Table against an array of cells
33
33
  # @param [Array] cells This is an array of all of the cells in the workbook
34
34
  # @param [Symbol] xml_space The xml:space behavior for the shared string table.
35
35
  def initialize(cells, xml_space = :preserve)
@@ -54,7 +54,7 @@ module Axlsx
54
54
 
55
55
  private
56
56
 
57
- # Interate over all of the cells in the array.
57
+ # Iterate over all of the cells in the array.
58
58
  # if our unique cells array does not contain a sharable cell,
59
59
  # add the cell to our unique cells array and set the ssti attribute on the index of this cell in the shared strings table
60
60
  # if a sharable cell already exists in our unique_cells array, set the ssti attribute of the cell and move on.