caxlsx 3.0.4 → 3.1.0
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 +6 -1
- data/README.md +2 -0
- data/lib/axlsx.rb +1 -1
- data/lib/axlsx/package.rb +32 -7
- data/lib/axlsx/util/mime_type_utils.rb +1 -1
- data/lib/axlsx/version.rb +1 -1
- data/lib/axlsx/workbook/worksheet/pivot_table.rb +7 -2
- data/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb +1 -1
- data/lib/axlsx/workbook/worksheet/row.rb +5 -3
- data/lib/axlsx/workbook/worksheet/table.rb +1 -1
- data/lib/axlsx/workbook/worksheet/worksheet.rb +4 -0
- data/test/tc_helper.rb +0 -2
- data/test/tc_package.rb +54 -4
- data/test/workbook/worksheet/tc_pivot_table.rb +8 -0
- data/test/workbook/worksheet/tc_pivot_table_cache_definition.rb +8 -0
- data/test/workbook/worksheet/tc_row.rb +21 -0
- data/test/workbook/worksheet/tc_table.rb +10 -0
- metadata +8 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dfea731879b2415d4ed0ac46abfbad17483d7e9f2c27802aef87a93823589af7
|
4
|
+
data.tar.gz: 709606e3d36fe21ac41a8f9381d4017c31103d6ce0a8686eb195a935c3626538
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cd1fd47bfe33dafa4909960d326f81433b4fa3e18d1a6f6f99e7a13617eecc98f212e2a938788d53466a47b52a0a2325a8dfcb3a6c3b52def5325b75ead9d402
|
7
|
+
data.tar.gz: bd9deebebd7cfc2222e64a8485ec9951ece3a69bb695fad5f4a790166324dab45134e835d02dc503e6c37e70b27d586db8bccf0c847448944f50ef37205e53d6
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
CHANGELOG
|
2
2
|
---------
|
3
3
|
|
4
|
-
- **
|
4
|
+
- **March.27.21**: 3.1.0
|
5
|
+
- [PR #95](https://github.com/caxlsx/caxlsx/pull/95) - Replace mimemagic with marcel
|
6
|
+
- [PR #87](https://github.com/caxlsx/caxlsx/pull/87) - Implement :offset option for worksheet#add_row
|
7
|
+
- [PR #79](https://github.com/caxlsx/caxlsx/pull/79) - Add support for format in pivot tables
|
8
|
+
- [PR #77](https://github.com/caxlsx/caxlsx/pull/77) - Fix special characters in table header
|
9
|
+
- [PR #57](https://github.com/caxlsx/caxlsx/pull/57) - Deprecate using #serialize with boolean argument: Calls like `Package#serialize("name.xlsx", false)` should be replaced with `Package#serialize("name.xlsx", confirm_valid: false)`.
|
5
10
|
|
6
11
|
- **January.5.21**: 3.0.4
|
7
12
|
- [PR #72](https://github.com/caxlsx/caxlsx/pull/72) - Relax Ruby dependency to allow for Ruby 3. This required Travis to be upgraded from Ubuntu Trusty to Ubuntu Bionic. rbx-3 was dropped.
|
data/README.md
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
[](https://travis-ci.com/caxlsx/caxlsx)
|
3
3
|
[](http://badge.fury.io/rb/caxlsx)
|
5
|
+

|
6
|
+

|
5
7
|
|
6
8
|
## Notice: Community Axlsx Organization
|
7
9
|
|
data/lib/axlsx.rb
CHANGED
data/lib/axlsx/package.rb
CHANGED
@@ -74,13 +74,14 @@ module Axlsx
|
|
74
74
|
# Serialize your workbook to disk as an xlsx document.
|
75
75
|
#
|
76
76
|
# @param [String] output The name of the file you want to serialize your package to
|
77
|
-
# @param [
|
78
|
-
# @
|
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
|
79
80
|
# zip the XLSX file contents. When a String, the provided zip command (e.g.,
|
80
81
|
# "zip") is used to zip the file contents (may be faster for large files)
|
81
82
|
# @return [Boolean] False if confirm_valid and validation errors exist. True if the package was serialized
|
82
83
|
# @note A tremendous amount of effort has gone into ensuring that you cannot create invalid xlsx documents.
|
83
|
-
# 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.
|
84
85
|
# @see Package#validate
|
85
86
|
# @example
|
86
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.
|
@@ -92,14 +93,15 @@ module Axlsx
|
|
92
93
|
# p.serialize("example.xlsx")
|
93
94
|
#
|
94
95
|
# # Serialize to a file, using a system zip binary
|
95
|
-
# p.serialize("example.xlsx",
|
96
|
-
# p.serialize("example.xlsx",
|
97
|
-
# p.serialize("example.xlsx",
|
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")
|
98
99
|
#
|
99
100
|
# # Serialize to a stream
|
100
101
|
# s = p.to_stream()
|
101
102
|
# File.open('example_streamed.xlsx', 'w') { |f| f.write(s.read) }
|
102
|
-
def serialize(output,
|
103
|
+
def serialize(output, options = {}, secondary_options = nil)
|
104
|
+
confirm_valid, zip_command = parse_serialize_options(options, secondary_options)
|
103
105
|
return false unless !confirm_valid || self.validate.empty?
|
104
106
|
zip_provider = if zip_command
|
105
107
|
ZipCommand.new(zip_command)
|
@@ -359,5 +361,28 @@ module Axlsx
|
|
359
361
|
rels.lock
|
360
362
|
rels
|
361
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
|
362
387
|
end
|
363
388
|
end
|
data/lib/axlsx/version.rb
CHANGED
@@ -111,8 +111,12 @@ module Axlsx
|
|
111
111
|
if data_field.is_a? String
|
112
112
|
data_field = {:ref => data_field}
|
113
113
|
end
|
114
|
-
data_field.
|
115
|
-
|
114
|
+
data_field.each do |key, value|
|
115
|
+
if key == :num_fmt
|
116
|
+
DataTypeValidator.validate "#{self.class}.data[]", [Integer], value
|
117
|
+
else
|
118
|
+
DataTypeValidator.validate "#{self.class}.data[]", [String], value
|
119
|
+
end
|
116
120
|
end
|
117
121
|
@data << data_field
|
118
122
|
end
|
@@ -212,6 +216,7 @@ module Axlsx
|
|
212
216
|
data.each do |datum_value|
|
213
217
|
# The correct name prefix in ["Sum","Average", etc...]
|
214
218
|
str << "<dataField name='#{(datum_value[:subtotal]||'')} of #{datum_value[:ref]}' fld='#{header_index_of(datum_value[:ref])}' baseField='0' baseItem='0'"
|
219
|
+
str << " numFmtId='#{datum_value[:num_fmt]}'" if datum_value[:num_fmt]
|
215
220
|
str << " subtotal='#{datum_value[:subtotal]}' " if datum_value[:subtotal]
|
216
221
|
str << "/>"
|
217
222
|
end
|
@@ -53,7 +53,7 @@ module Axlsx
|
|
53
53
|
str << '</cacheSource>'
|
54
54
|
str << ( '<cacheFields count="' << pivot_table.header_cells_count.to_s << '">')
|
55
55
|
pivot_table.header_cells.each do |cell|
|
56
|
-
str << ( '<cacheField name="' << cell.
|
56
|
+
str << ( '<cacheField name="' << cell.clean_value << '" numFmtId="0">')
|
57
57
|
str << '<sharedItems count="0">'
|
58
58
|
str << '</sharedItems>'
|
59
59
|
str << '</cacheField>'
|
@@ -25,11 +25,12 @@ module Axlsx
|
|
25
25
|
# @option options [Array, Symbol] types
|
26
26
|
# @option options [Array, Integer] style
|
27
27
|
# @option options [Float] height the row's height (in points)
|
28
|
+
# @option options [Integer] offset - add empty columns before values
|
28
29
|
# @see Row#array_to_cells
|
29
30
|
# @see Cell
|
30
31
|
def initialize(worksheet, values=[], options={})
|
31
32
|
self.worksheet = worksheet
|
32
|
-
super(Cell, nil, values.size)
|
33
|
+
super(Cell, nil, values.size + options[:offset].to_i)
|
33
34
|
self.height = options.delete(:height)
|
34
35
|
worksheet.rows << self
|
35
36
|
array_to_cells(values, options)
|
@@ -147,14 +148,15 @@ module Axlsx
|
|
147
148
|
# @option options [Array, Integer] style
|
148
149
|
def array_to_cells(values, options={})
|
149
150
|
DataTypeValidator.validate :array_to_cells, Array, values
|
150
|
-
types, style, formula_values, escape_formulas = options.delete(:types), options.delete(:style), options.delete(:formula_values), options.delete(:escape_formulas)
|
151
|
+
types, style, formula_values, escape_formulas, offset = options.delete(:types), options.delete(:style), options.delete(:formula_values), options.delete(:escape_formulas), options.delete(:offset)
|
152
|
+
offset.to_i.times { |index| self[index] = Cell.new(self) } if offset
|
151
153
|
values.each_with_index do |value, index|
|
152
154
|
options[:style] = style.is_a?(Array) ? style[index] : style if style
|
153
155
|
options[:type] = types.is_a?(Array) ? types[index] : types if types
|
154
156
|
options[:escape_formulas] = escape_formulas.is_a?(Array) ? escape_formulas[index] : escape_formulas if escape_formulas
|
155
157
|
options[:formula_value] = formula_values[index] if formula_values.is_a?(Array)
|
156
158
|
|
157
|
-
self[index] = Cell.new(self, value, options)
|
159
|
+
self[index + offset.to_i] = Cell.new(self, value, options)
|
158
160
|
end
|
159
161
|
end
|
160
162
|
end
|
@@ -80,7 +80,7 @@ module Axlsx
|
|
80
80
|
str << ('<autoFilter ref="' << @ref << '"/>')
|
81
81
|
str << ('<tableColumns count="' << header_cells.length.to_s << '">')
|
82
82
|
header_cells.each_with_index do |cell,index|
|
83
|
-
str << ('<tableColumn id ="' << (index+1).to_s << '" name="' << cell.
|
83
|
+
str << ('<tableColumn id ="' << (index+1).to_s << '" name="' << cell.clean_value << '"/>')
|
84
84
|
end
|
85
85
|
str << '</tableColumns>'
|
86
86
|
table_style_info.to_xml_string(str)
|
@@ -393,6 +393,9 @@ module Axlsx
|
|
393
393
|
# @example - specify whether a certain cells in a row should escape formulas or not
|
394
394
|
# ws.add_row ['=IF(2+2=4,4,5)', '=IF(13+13=4,4,5)'], :escape_formulas=>[true, false]
|
395
395
|
#
|
396
|
+
# @example - add a column offset when adding a row (inserts 'n' blank, unstyled columns before data)
|
397
|
+
# ws.add_row ['I wish', 'for a fish', 'on my fish wish dish'], offset: 3
|
398
|
+
#
|
396
399
|
# @see Worksheet#column_widths
|
397
400
|
# @return [Row]
|
398
401
|
# @option options [Array] values
|
@@ -400,6 +403,7 @@ module Axlsx
|
|
400
403
|
# @option options [Array, Integer] style
|
401
404
|
# @option options [Array] widths each member of the widths array will affect how auto_fit behavies.
|
402
405
|
# @option options [Float] height the row's height (in points)
|
406
|
+
# @option options [Integer] offset - add empty columns before values
|
403
407
|
# @option options [Array, Boolean] escape_formulas - Whether to treat a value starting with an equal
|
404
408
|
# sign as formula (default) or as simple string.
|
405
409
|
# Allowing user generated data to be interpreted as formulas can be dangerous
|
data/test/tc_helper.rb
CHANGED
data/test/tc_package.rb
CHANGED
@@ -129,25 +129,28 @@ class TestPackage < Test::Unit::TestCase
|
|
129
129
|
def test_serialization
|
130
130
|
@package.serialize(@fname)
|
131
131
|
assert_zip_file_matches_package(@fname, @package)
|
132
|
+
assert_created_with_rubyzip(@fname, @package)
|
132
133
|
File.delete(@fname)
|
133
134
|
end
|
134
135
|
|
135
136
|
def test_serialization_with_zip_command
|
136
|
-
@package.serialize(@fname,
|
137
|
+
@package.serialize(@fname, zip_command: "zip")
|
137
138
|
assert_zip_file_matches_package(@fname, @package)
|
139
|
+
assert_created_with_zip_command(@fname, @package)
|
138
140
|
File.delete(@fname)
|
139
141
|
end
|
140
142
|
|
141
143
|
def test_serialization_with_zip_command_and_absolute_path
|
142
144
|
fname = "#{Dir.tmpdir}/#{@fname}"
|
143
|
-
@package.serialize(fname,
|
145
|
+
@package.serialize(fname, zip_command: "zip")
|
144
146
|
assert_zip_file_matches_package(fname, @package)
|
147
|
+
assert_created_with_zip_command(fname, @package)
|
145
148
|
File.delete(fname)
|
146
149
|
end
|
147
150
|
|
148
151
|
def test_serialization_with_invalid_zip_command
|
149
152
|
assert_raises Axlsx::ZipCommand::ZipError do
|
150
|
-
@package.serialize(@fname,
|
153
|
+
@package.serialize(@fname, zip_command: "invalid_zip")
|
151
154
|
end
|
152
155
|
end
|
153
156
|
|
@@ -156,6 +159,53 @@ class TestPackage < Test::Unit::TestCase
|
|
156
159
|
package.send(:parts).each{ |part| zf.get_entry(part[:entry]) }
|
157
160
|
end
|
158
161
|
|
162
|
+
def assert_created_with_rubyzip(fname, package)
|
163
|
+
assert_equal 2098, get_mtime(fname, package).year, "XLSX files created with RubyZip have 2098 as the file mtime"
|
164
|
+
end
|
165
|
+
|
166
|
+
def assert_created_with_zip_command(fname, package)
|
167
|
+
assert_equal Time.now.utc.year, get_mtime(fname, package).year, "XLSX files created with a zip command have the current year as the file mtime"
|
168
|
+
end
|
169
|
+
|
170
|
+
def get_mtime(fname, package)
|
171
|
+
zf = Zip::File.open(fname)
|
172
|
+
part = package.send(:parts).first
|
173
|
+
entry = zf.get_entry(part[:entry])
|
174
|
+
entry.mtime.utc
|
175
|
+
end
|
176
|
+
|
177
|
+
def test_serialization_with_deprecated_argument
|
178
|
+
warnings = capture_warnings do
|
179
|
+
@package.serialize(@fname, false)
|
180
|
+
end
|
181
|
+
assert_equal 1, warnings.size
|
182
|
+
assert_includes warnings.first, "confirm_valid as a boolean is deprecated"
|
183
|
+
File.delete(@fname)
|
184
|
+
end
|
185
|
+
|
186
|
+
def test_serialization_with_deprecated_three_arguments
|
187
|
+
warnings = capture_warnings do
|
188
|
+
@package.serialize(@fname, true, zip_command: "zip")
|
189
|
+
end
|
190
|
+
assert_zip_file_matches_package(@fname, @package)
|
191
|
+
assert_created_with_zip_command(@fname, @package)
|
192
|
+
assert_equal 2, warnings.size
|
193
|
+
assert_includes warnings.first, "with 3 arguments is deprecated"
|
194
|
+
File.delete(@fname)
|
195
|
+
end
|
196
|
+
|
197
|
+
def capture_warnings(&block)
|
198
|
+
original_warn = Kernel.instance_method(:warn)
|
199
|
+
warnings = []
|
200
|
+
Kernel.send(:define_method, :warn) { |string| warnings << string }
|
201
|
+
block.call
|
202
|
+
original_verbose = $VERBOSE
|
203
|
+
$VERBOSE = nil
|
204
|
+
Kernel.send(:define_method, :warn, original_warn)
|
205
|
+
$VERBOSE = original_verbose
|
206
|
+
warnings
|
207
|
+
end
|
208
|
+
|
159
209
|
# See comment for Package#zip_entry_for_part
|
160
210
|
def test_serialization_creates_identical_files_at_any_time_if_created_at_is_set
|
161
211
|
@package.core.created = Time.now
|
@@ -178,7 +228,7 @@ class TestPackage < Test::Unit::TestCase
|
|
178
228
|
end
|
179
229
|
|
180
230
|
def test_serialization_creates_files_with_excel_mime_type
|
181
|
-
assert_equal(
|
231
|
+
assert_equal(Marcel::MimeType.for(@package.to_stream),
|
182
232
|
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
|
183
233
|
end
|
184
234
|
|
@@ -132,4 +132,12 @@ class TestPivotTable < Test::Unit::TestCase
|
|
132
132
|
end
|
133
133
|
shared_test_pivot_table_xml_validity(pivot_table)
|
134
134
|
end
|
135
|
+
|
136
|
+
def test_add_pivot_table_with_format_options_on_data_field
|
137
|
+
pivot_table = @ws.add_pivot_table('G5:G6', 'A1:E5') do |pt|
|
138
|
+
pt.data = [{:ref=>"Sales", :subtotal => 'sum', num_fmt: 4}]
|
139
|
+
end
|
140
|
+
doc = Nokogiri::XML(pivot_table.to_xml_string)
|
141
|
+
assert_equal('4', doc.at_css('dataFields dataField')['numFmtId'], 'adding format options to pivot_table')
|
142
|
+
end
|
135
143
|
end
|
@@ -51,4 +51,12 @@ class TestPivotTableCacheDefinition < Test::Unit::TestCase
|
|
51
51
|
assert(errors.empty?, "error free validation")
|
52
52
|
end
|
53
53
|
|
54
|
+
def test_to_xml_string_for_special_characters
|
55
|
+
cell = @ws.rows.first.cells.first
|
56
|
+
cell.value = "&><'\""
|
57
|
+
|
58
|
+
doc = Nokogiri::XML(@cache_definition.to_xml_string)
|
59
|
+
errors = doc.errors
|
60
|
+
assert(errors.empty?, "invalid xml: #{errors.map(&:to_s).join(', ')}")
|
61
|
+
end
|
54
62
|
end
|
@@ -136,4 +136,25 @@ class TestRow < Test::Unit::TestCase
|
|
136
136
|
assert_equal(r_s_xml.xpath(".//row[@r=1][@ht=20][@customHeight=1]").size, 1)
|
137
137
|
end
|
138
138
|
|
139
|
+
def test_offsets
|
140
|
+
offset = 3
|
141
|
+
values = [1,2,3,4,5]
|
142
|
+
r = @ws.add_row(values, offset: offset, style: 1)
|
143
|
+
r.cells.each_with_index do |c, index|
|
144
|
+
assert_equal(c.style, index < offset ? 0 : 1)
|
145
|
+
assert_equal(c.value, index < offset ? nil : values[index - offset])
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def test_offsets_with_styles
|
150
|
+
offset = 3
|
151
|
+
values = [1,2,3,4,5]
|
152
|
+
styles = (1..5).map{ @ws.workbook.styles.add_style }
|
153
|
+
r = @ws.add_row(values, offset: offset, style: styles)
|
154
|
+
r.cells.each_with_index do |c, index|
|
155
|
+
assert_equal(c.style, index < offset ? 0 : styles[index-offset])
|
156
|
+
assert_equal(c.value, index < offset ? nil : values[index - offset])
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
139
160
|
end
|
@@ -64,4 +64,14 @@ class TestTable < Test::Unit::TestCase
|
|
64
64
|
end
|
65
65
|
assert(errors.empty?, "error free validation")
|
66
66
|
end
|
67
|
+
|
68
|
+
def test_to_xml_string_for_special_characters
|
69
|
+
cell = @ws.rows.first.cells.first
|
70
|
+
cell.value = "&><'\""
|
71
|
+
|
72
|
+
table = @ws.add_table("A1:D5")
|
73
|
+
doc = Nokogiri::XML(table.to_xml_string)
|
74
|
+
errors = doc.errors
|
75
|
+
assert(errors.empty?, "invalid xml: #{errors.map(&:to_s).join(', ')}")
|
76
|
+
end
|
67
77
|
end
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: caxlsx
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0
|
4
|
+
version: 3.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Randy Morgan
|
8
8
|
- Jurriaan Pruis
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2021-
|
12
|
+
date: 2021-03-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: nokogiri
|
@@ -72,19 +72,19 @@ dependencies:
|
|
72
72
|
- !ruby/object:Gem::Version
|
73
73
|
version: 4.3.4
|
74
74
|
- !ruby/object:Gem::Dependency
|
75
|
-
name:
|
75
|
+
name: marcel
|
76
76
|
requirement: !ruby/object:Gem::Requirement
|
77
77
|
requirements:
|
78
78
|
- - "~>"
|
79
79
|
- !ruby/object:Gem::Version
|
80
|
-
version: '0
|
80
|
+
version: '1.0'
|
81
81
|
type: :runtime
|
82
82
|
prerelease: false
|
83
83
|
version_requirements: !ruby/object:Gem::Requirement
|
84
84
|
requirements:
|
85
85
|
- - "~>"
|
86
86
|
- !ruby/object:Gem::Version
|
87
|
-
version: '0
|
87
|
+
version: '1.0'
|
88
88
|
- !ruby/object:Gem::Dependency
|
89
89
|
name: yard
|
90
90
|
requirement: !ruby/object:Gem::Requirement
|
@@ -452,7 +452,7 @@ homepage: https://github.com/caxlsx/caxlsx
|
|
452
452
|
licenses:
|
453
453
|
- MIT
|
454
454
|
metadata: {}
|
455
|
-
post_install_message:
|
455
|
+
post_install_message:
|
456
456
|
rdoc_options: []
|
457
457
|
require_paths:
|
458
458
|
- lib
|
@@ -468,7 +468,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
468
468
|
version: '0'
|
469
469
|
requirements: []
|
470
470
|
rubygems_version: 3.0.3
|
471
|
-
signing_key:
|
471
|
+
signing_key:
|
472
472
|
specification_version: 4
|
473
473
|
summary: Excel OOXML (xlsx) with charts, styles, images and autowidth columns.
|
474
474
|
test_files:
|