xsv 1.2.1 → 1.3.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/.github/workflows/ruby.yml +1 -1
- data/.standard.yml +1 -1
- data/CHANGELOG.md +7 -0
- data/README.md +48 -48
- data/benchmark.rb +2 -2
- data/lib/xsv/helpers.rb +6 -3
- data/lib/xsv/sax_parser.rb +18 -17
- data/lib/xsv/sheet.rb +2 -8
- data/lib/xsv/sheet_rows_handler.rb +1 -1
- data/lib/xsv/version.rb +1 -1
- data/lib/xsv/workbook.rb +21 -1
- data/xsv.gemspec +4 -5
- metadata +10 -24
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1ff63ab6263b0486a400d5d36eb53d0af7265532b67536c7024b414b2bcf3ad2
|
|
4
|
+
data.tar.gz: a885af30f1a874818bb80f984115d7bc47e178007bf9848407e279af3effcd3b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 37b9b49b66fcec0c393a56382b162d0fb3c77e2342798292d3a4c73c49939ce3d0827c783a7b9b5c139b52553e3a622f6e47f510e4839963609c571e7ab53067
|
|
7
|
+
data.tar.gz: ecd5e49c82d802e2a654c7d6321cdf81b5ea81482a83821ca6ddd19ae5036a6e2a516569356ded600b2181b0c4161c5c7e4e36a43570b4bef82f7c9d58038392
|
data/.github/workflows/ruby.yml
CHANGED
data/.standard.yml
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
ruby_version: 2.
|
|
1
|
+
ruby_version: 2.7.8
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Xsv Changelog
|
|
2
2
|
|
|
3
|
+
## 1.3.0 2023-12-16
|
|
4
|
+
|
|
5
|
+
- Ruby 2.6 is no longer supported. Xsv is compatible with Ruby 2.7 through 3.3, latest JRuby, and latest TruffleRuby
|
|
6
|
+
- Easier access worksheets using `Xsv::Workbook#[]` and `Enumerable` methods on `Xsv::Workbook`. The old `sheets` and `sheet_by_name` method have been retained for backward compatibility.
|
|
7
|
+
- Update of development dependencies including minitest and standardrb
|
|
8
|
+
- Various performance improvements, especially with YJIT on Ruby 3.3
|
|
9
|
+
|
|
3
10
|
## 1.2.1 2023-05-09
|
|
4
11
|
|
|
5
12
|
- Handle columns without `r` attribute (issue #48)
|
data/README.md
CHANGED
|
@@ -1,23 +1,20 @@
|
|
|
1
|
-
# Xsv .xlsx reader
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
# Xsv .xlsx reader for Ruby
|
|
4
2
|
|
|
5
3
|
[](https://github.com/martijn/xsv/actions/workflows/ruby.yml)
|
|
6
|
-
[](https://app.codecov.io/gh/martijn/xsv)
|
|
7
4
|
[](https://rubydoc.info/github/martijn/xsv)
|
|
8
5
|
[](https://badge.fury.io/rb/xsv)
|
|
9
6
|
|
|
10
|
-
Xsv is a
|
|
11
|
-
(commonly known as Excel or .xlsx files). It strives to be minimal in the
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
Xsv is a high performance, lightweight, pure Ruby parser for ISO/IEC 29500 Office Open XML spreadsheets
|
|
8
|
+
(commonly known as Excel or .xlsx files). It strives to be minimal in the sense that it provides nothing a
|
|
9
|
+
CSV reader wouldn't. This means it only deals with the minimal required formatting and cannot create or modify
|
|
10
|
+
documents.
|
|
11
|
+
Xsv can handle very large Excel files with minimal resources thanks to a custom streaming XML parser that
|
|
12
|
+
is optimized for the Excel file format.
|
|
14
13
|
|
|
15
14
|
Xsv is designed for worksheets with a single table of data, optionally
|
|
16
15
|
with a header row. It only casts values to basic Ruby types (integer, float,
|
|
17
16
|
date and time) and does not deal with most formatting or more advanced
|
|
18
|
-
functionality.
|
|
19
|
-
minimal RAM and CPU consumption and has been in production use since the earliest
|
|
20
|
-
versions.
|
|
17
|
+
functionality. Xsv has been production-ready since the initial release.
|
|
21
18
|
|
|
22
19
|
Xsv stands for 'Excel Separated Values', because Excel just gets in the way.
|
|
23
20
|
|
|
@@ -37,20 +34,24 @@ Or install it yourself as:
|
|
|
37
34
|
|
|
38
35
|
$ gem install xsv
|
|
39
36
|
|
|
40
|
-
Xsv targets ruby >= 2.
|
|
37
|
+
Xsv targets ruby >= 2.7 and has a just single dependency, `rubyzip`. It has been
|
|
41
38
|
tested successfully with MRI, JRuby, and TruffleRuby. It has no native extensions
|
|
42
39
|
and is designed to be thread-safe.
|
|
43
40
|
|
|
44
41
|
## Usage
|
|
45
42
|
|
|
46
43
|
### Array and hash mode
|
|
44
|
+
|
|
47
45
|
Xsv has two modes of operation. By default, it returns an array for
|
|
48
46
|
each row in the sheet:
|
|
49
47
|
|
|
50
48
|
```ruby
|
|
51
|
-
|
|
49
|
+
workbook = Xsv.open("sheet.xlsx") # => #<Xsv::Workbook sheets=1>
|
|
52
50
|
|
|
53
|
-
|
|
51
|
+
# Access worksheet by index, 0 is the first sheet
|
|
52
|
+
sheet = workbook[0]
|
|
53
|
+
# or, access worksheet by name
|
|
54
|
+
sheet = workbook["Sheet1"]
|
|
54
55
|
|
|
55
56
|
# Iterate over rows
|
|
56
57
|
sheet.each do |row|
|
|
@@ -68,29 +69,35 @@ option on open:
|
|
|
68
69
|
```ruby
|
|
69
70
|
# Parse headers for all sheets on open
|
|
70
71
|
|
|
71
|
-
|
|
72
|
+
workbook = Xsv.open("sheet.xlsx", parse_headers: true)
|
|
72
73
|
|
|
73
|
-
|
|
74
|
+
# Get the first row from the first sheet
|
|
75
|
+
workbook.first.first # => {"header1" => "value1", "header2" => "value2"}
|
|
74
76
|
|
|
75
77
|
# Manually parse headers for a single sheet
|
|
76
78
|
|
|
77
|
-
|
|
79
|
+
workbook = Xsv.open("sheet.xlsx")
|
|
78
80
|
|
|
79
|
-
sheet =
|
|
81
|
+
sheet = workbook.first
|
|
80
82
|
|
|
81
|
-
sheet
|
|
83
|
+
sheet.first # => ["header1", "header2"]
|
|
82
84
|
|
|
83
85
|
sheet.parse_headers!
|
|
84
86
|
|
|
85
|
-
sheet
|
|
87
|
+
sheet.first # => {"header1" => "value1", "header2" => "value2"}
|
|
86
88
|
```
|
|
87
89
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
a workbook with `parse_headers: true`.
|
|
90
|
+
Xsv will raise `Xsv::DuplicateHeaders` if it detects duplicate values in the header row when calling
|
|
91
|
+
`#parse_headers!` or when opening a workbook with `parse_headers: true` to ensure hash keys are unique.
|
|
91
92
|
|
|
92
93
|
`Xsv::Sheet` implements `Enumerable` so along with `#each`
|
|
93
|
-
you can call methods like `#first`, `#filter`/`#select`, and `#map` on it.
|
|
94
|
+
you can call methods like `#first`, `#filter`/`#select`, and `#map` on it. Likewise these methods can
|
|
95
|
+
be used on `Xsv::Workbook` to iterate over sheets, for example:
|
|
96
|
+
|
|
97
|
+
```ruby
|
|
98
|
+
# Get the name of all the sheets in a workbook
|
|
99
|
+
sheet_names = @workbook.map(&:name)
|
|
100
|
+
```
|
|
94
101
|
|
|
95
102
|
### Opening a string or buffer instead of filename
|
|
96
103
|
|
|
@@ -116,24 +123,6 @@ end
|
|
|
116
123
|
Prior to Xsv 1.1.0, `Xsv::Workbook.open` was used instead of `Xsv.open`. The parameters are identical and
|
|
117
124
|
the former is maintained for backwards compatibility.
|
|
118
125
|
|
|
119
|
-
### Accessing sheets by name
|
|
120
|
-
|
|
121
|
-
The sheets can be accessed by index or by name:
|
|
122
|
-
|
|
123
|
-
```ruby
|
|
124
|
-
x = Xsv.open("sheet.xlsx")
|
|
125
|
-
|
|
126
|
-
sheet = x.sheets[0] # gets sheet by index
|
|
127
|
-
|
|
128
|
-
sheet = x.sheets_by_name('Name').first # gets sheet by name
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
To get all the sheets names:
|
|
132
|
-
|
|
133
|
-
```ruby
|
|
134
|
-
sheet_names = x.sheets.map(&:name)
|
|
135
|
-
```
|
|
136
|
-
|
|
137
126
|
### Assumptions
|
|
138
127
|
|
|
139
128
|
Since Xsv treats worksheets like csv files it makes certain assumptions about your
|
|
@@ -147,26 +136,35 @@ If your data or headers do not start on the first row of the sheet you can
|
|
|
147
136
|
tell Xsv to skip a number of rows:
|
|
148
137
|
|
|
149
138
|
```ruby
|
|
150
|
-
workbook
|
|
139
|
+
sheet = workbook[0]
|
|
140
|
+
sheet.row_skip = 1
|
|
151
141
|
```
|
|
152
142
|
|
|
153
143
|
All operations will honour this offset, making the skipped rows unreachable.
|
|
154
144
|
|
|
155
145
|
## Development
|
|
156
146
|
|
|
157
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can
|
|
147
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can
|
|
148
|
+
also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
158
149
|
|
|
159
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the
|
|
150
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the
|
|
151
|
+
version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version,
|
|
152
|
+
push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
|
160
153
|
|
|
161
154
|
## Performance and Benchmarks
|
|
162
155
|
|
|
163
|
-
Xsv is faster and more memory efficient than other gems because of two things: it only _reads values_ from Excel files
|
|
156
|
+
Xsv is faster and more memory efficient than other gems because of two things: it only _reads values_ from Excel files
|
|
157
|
+
and it's based on a SAX-based parser instead of a DOM-based parser. If you want to read some background on this, check
|
|
158
|
+
out my blog post on
|
|
164
159
|
[Efficient XML parsing in Ruby](https://storck.io/posts/efficient-xml-parsing-in-ruby/).
|
|
165
160
|
|
|
166
|
-
Jamie Schembri did a shootout of Xsv against various other Excel reading gems comparing parsing speed, memory usage, and
|
|
161
|
+
Jamie Schembri did a shootout of Xsv against various other Excel reading gems comparing parsing speed, memory usage, and
|
|
162
|
+
allocations.
|
|
167
163
|
Check our his blog post: [Faster Excel parsing in Ruby](https://blog.schembri.me/post/faster-excel-parsing-in-ruby/).
|
|
168
164
|
|
|
169
|
-
Pre-1.0, Xsv used a native extension for XML parsing, which was faster than the native Ruby one (on MRI). But even
|
|
165
|
+
Pre-1.0, Xsv used a native extension for XML parsing, which was faster than the native Ruby one (on MRI). But even
|
|
166
|
+
the current native Ruby parser generally outperforms the competition. For maximum performance, it is recommended to
|
|
167
|
+
enable YJIT.
|
|
170
168
|
|
|
171
169
|
## Contributing
|
|
172
170
|
|
|
@@ -176,4 +174,6 @@ for inclusion in the source code repository.
|
|
|
176
174
|
|
|
177
175
|
## License
|
|
178
176
|
|
|
177
|
+
Copyright © Martijn Storck and Xsv contributors
|
|
178
|
+
|
|
179
179
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/benchmark.rb
CHANGED
|
@@ -14,7 +14,6 @@ def bench_perf(sheet)
|
|
|
14
14
|
result = Benchmark::Perf.cpu(repeat: 5) do
|
|
15
15
|
sheet.each do |row|
|
|
16
16
|
row.each do |cell|
|
|
17
|
-
cell
|
|
18
17
|
end
|
|
19
18
|
end
|
|
20
19
|
end
|
|
@@ -27,13 +26,14 @@ def bench_mem(sheet)
|
|
|
27
26
|
bm.report do
|
|
28
27
|
sheet.each do |row|
|
|
29
28
|
row.each do |cell|
|
|
30
|
-
cell
|
|
31
29
|
end
|
|
32
30
|
end
|
|
33
31
|
end
|
|
34
32
|
end
|
|
35
33
|
end
|
|
36
34
|
|
|
35
|
+
puts RUBY_DESCRIPTION
|
|
36
|
+
|
|
37
37
|
file = File.read("test/files/10k-sheet.xlsx")
|
|
38
38
|
|
|
39
39
|
workbook = Xsv.open(file)
|
data/lib/xsv/helpers.rb
CHANGED
|
@@ -45,11 +45,14 @@ module Xsv
|
|
|
45
45
|
EPOCH = Date.new(1899, 12, 30).freeze
|
|
46
46
|
|
|
47
47
|
# Return the index number for the given Excel column name (i.e. "A1" => 0)
|
|
48
|
+
# @param col [String] Column name in A1 notation
|
|
48
49
|
def column_index(col)
|
|
49
|
-
col.
|
|
50
|
-
|
|
50
|
+
chars = col.bytes
|
|
51
|
+
sum = 0
|
|
52
|
+
while (char = chars.delete_at(0))
|
|
53
|
+
break sum - 1 if char < A_CODEPOINT # reached the number
|
|
51
54
|
|
|
52
|
-
sum * 26 + (
|
|
55
|
+
sum = sum * 26 + (char - A_CODEPOINT + 1)
|
|
53
56
|
end
|
|
54
57
|
end
|
|
55
58
|
|
data/lib/xsv/sax_parser.rb
CHANGED
|
@@ -62,15 +62,27 @@ module Xsv
|
|
|
62
62
|
args = nil
|
|
63
63
|
end
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
is_close_tag = tag_name.delete_prefix!("/")
|
|
66
66
|
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
# Strip XML namespace from tag
|
|
68
|
+
if (offset = tag_name.index(":"))
|
|
69
|
+
tag_name.slice!(0, offset + 1)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
if is_close_tag
|
|
73
|
+
end_element(tag_name) if responds_to_end_element
|
|
69
74
|
elsif args.nil?
|
|
70
|
-
start_element(
|
|
75
|
+
start_element(tag_name, nil)
|
|
71
76
|
else
|
|
72
|
-
|
|
73
|
-
|
|
77
|
+
attribute_buffer = {}
|
|
78
|
+
attributes = args.scan(ATTR_REGEX)
|
|
79
|
+
while (attr = attributes.delete_at(0))
|
|
80
|
+
attribute_buffer[attr[1].to_sym] = attr[2]
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
start_element(tag_name, attribute_buffer)
|
|
84
|
+
|
|
85
|
+
end_element(tag_name) if responds_to_end_element && args.end_with?("/")
|
|
74
86
|
end
|
|
75
87
|
|
|
76
88
|
state = :look_start
|
|
@@ -82,16 +94,5 @@ module Xsv
|
|
|
82
94
|
end
|
|
83
95
|
end
|
|
84
96
|
end
|
|
85
|
-
|
|
86
|
-
private
|
|
87
|
-
|
|
88
|
-
# I am not proud of this, but there's simply no need to deal with xmlns for this application ¯\_(ツ)_/¯
|
|
89
|
-
def strip_namespace(tag)
|
|
90
|
-
if (offset = tag.index(":"))
|
|
91
|
-
tag[offset + 1..]
|
|
92
|
-
else
|
|
93
|
-
tag
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
97
|
end
|
|
97
98
|
end
|
data/lib/xsv/sheet.rb
CHANGED
|
@@ -30,13 +30,11 @@ module Xsv
|
|
|
30
30
|
#
|
|
31
31
|
# @param workbook [Workbook] The Workbook with shared data such as shared strings and styles
|
|
32
32
|
# @param io [IO] A handle to an open worksheet XML file
|
|
33
|
-
|
|
34
|
-
def initialize(workbook, io, size, ids)
|
|
33
|
+
def initialize(workbook, io, ids)
|
|
35
34
|
@workbook = workbook
|
|
36
35
|
@id = ids[:sheetId].to_i
|
|
37
36
|
@io = io
|
|
38
37
|
@name = ids[:name]
|
|
39
|
-
@size = size
|
|
40
38
|
@headers = []
|
|
41
39
|
@mode = :array
|
|
42
40
|
@row_skip = 0
|
|
@@ -58,11 +56,7 @@ module Xsv
|
|
|
58
56
|
# Iterate over rows, returning either hashes or arrays based on the current mode.
|
|
59
57
|
def each_row(&block)
|
|
60
58
|
@io.rewind
|
|
61
|
-
|
|
62
|
-
handler = SheetRowsHandler.new(@mode, empty_row, @workbook, @row_skip, @last_row, &block)
|
|
63
|
-
|
|
64
|
-
handler.parse(@io)
|
|
65
|
-
|
|
59
|
+
SheetRowsHandler.new(@mode, empty_row, @workbook, @row_skip, @last_row, &block).parse(@io)
|
|
66
60
|
true
|
|
67
61
|
end
|
|
68
62
|
|
data/lib/xsv/version.rb
CHANGED
data/lib/xsv/workbook.rb
CHANGED
|
@@ -6,6 +6,8 @@ module Xsv
|
|
|
6
6
|
# An OOXML Spreadsheet document is called a Workbook. A Workbook consists of
|
|
7
7
|
# multiple Sheets that are available in the array that's accessible through {#sheets}
|
|
8
8
|
class Workbook
|
|
9
|
+
include Enumerable
|
|
10
|
+
|
|
9
11
|
# Access the Sheet objects contained in the workbook
|
|
10
12
|
# @return [Array<Sheet>]
|
|
11
13
|
attr_reader :sheets
|
|
@@ -69,6 +71,24 @@ module Xsv
|
|
|
69
71
|
@num_fmts[@xfs[style][:numFmtId]]
|
|
70
72
|
end
|
|
71
73
|
|
|
74
|
+
def each(&block)
|
|
75
|
+
sheets.each(&block)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Get a sheet by index or name
|
|
79
|
+
# @param [String, Integer] index_or_name The name of the sheet or index in the workbook
|
|
80
|
+
# @return [<Xsv::Sheet>, nil] returns the sheet instance or nil if it was not found
|
|
81
|
+
def [](index_or_name)
|
|
82
|
+
case index_or_name
|
|
83
|
+
when Integer
|
|
84
|
+
sheets[index_or_name]
|
|
85
|
+
when String
|
|
86
|
+
sheets_by_name(index_or_name).first
|
|
87
|
+
else
|
|
88
|
+
raise ArgumentError, "Sheets can be accessed by Integer of String only"
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
72
92
|
private
|
|
73
93
|
|
|
74
94
|
def fetch_shared_strings
|
|
@@ -98,7 +118,7 @@ module Xsv
|
|
|
98
118
|
r[:Type].end_with?("worksheet")
|
|
99
119
|
end
|
|
100
120
|
sheet_ids = @sheet_ids.detect { |i| i[:id] == rel[:Id] }
|
|
101
|
-
Xsv::Sheet.new(self, entry.get_input_stream,
|
|
121
|
+
Xsv::Sheet.new(self, entry.get_input_stream, sheet_ids).tap do |sheet|
|
|
102
122
|
sheet.parse_headers! if mode == :hash
|
|
103
123
|
end
|
|
104
124
|
end
|
data/xsv.gemspec
CHANGED
|
@@ -36,13 +36,12 @@ Gem::Specification.new do |spec|
|
|
|
36
36
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
37
37
|
spec.require_paths = ["lib"]
|
|
38
38
|
|
|
39
|
-
spec.required_ruby_version = ">= 2.
|
|
39
|
+
spec.required_ruby_version = ">= 2.7"
|
|
40
40
|
|
|
41
41
|
spec.add_dependency "rubyzip", ">= 1.3", "< 3"
|
|
42
42
|
|
|
43
43
|
spec.add_development_dependency "bundler", "< 3"
|
|
44
|
-
spec.add_development_dependency "rake", "~> 13.0"
|
|
45
|
-
spec.add_development_dependency "minitest", "~> 5.
|
|
46
|
-
spec.add_development_dependency "standard", "~> 1.
|
|
47
|
-
spec.add_development_dependency "codecov", ">= 0.6.0"
|
|
44
|
+
spec.add_development_dependency "rake", "~> 13.1.0"
|
|
45
|
+
spec.add_development_dependency "minitest", "~> 5.20.0"
|
|
46
|
+
spec.add_development_dependency "standard", "~> 1.32.1"
|
|
48
47
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: xsv
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Martijn Storck
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2023-
|
|
11
|
+
date: 2023-12-16 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rubyzip
|
|
@@ -50,56 +50,42 @@ dependencies:
|
|
|
50
50
|
requirements:
|
|
51
51
|
- - "~>"
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
|
-
version:
|
|
53
|
+
version: 13.1.0
|
|
54
54
|
type: :development
|
|
55
55
|
prerelease: false
|
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
|
57
57
|
requirements:
|
|
58
58
|
- - "~>"
|
|
59
59
|
- !ruby/object:Gem::Version
|
|
60
|
-
version:
|
|
60
|
+
version: 13.1.0
|
|
61
61
|
- !ruby/object:Gem::Dependency
|
|
62
62
|
name: minitest
|
|
63
63
|
requirement: !ruby/object:Gem::Requirement
|
|
64
64
|
requirements:
|
|
65
65
|
- - "~>"
|
|
66
66
|
- !ruby/object:Gem::Version
|
|
67
|
-
version: 5.
|
|
67
|
+
version: 5.20.0
|
|
68
68
|
type: :development
|
|
69
69
|
prerelease: false
|
|
70
70
|
version_requirements: !ruby/object:Gem::Requirement
|
|
71
71
|
requirements:
|
|
72
72
|
- - "~>"
|
|
73
73
|
- !ruby/object:Gem::Version
|
|
74
|
-
version: 5.
|
|
74
|
+
version: 5.20.0
|
|
75
75
|
- !ruby/object:Gem::Dependency
|
|
76
76
|
name: standard
|
|
77
77
|
requirement: !ruby/object:Gem::Requirement
|
|
78
78
|
requirements:
|
|
79
79
|
- - "~>"
|
|
80
80
|
- !ruby/object:Gem::Version
|
|
81
|
-
version: 1.
|
|
81
|
+
version: 1.32.1
|
|
82
82
|
type: :development
|
|
83
83
|
prerelease: false
|
|
84
84
|
version_requirements: !ruby/object:Gem::Requirement
|
|
85
85
|
requirements:
|
|
86
86
|
- - "~>"
|
|
87
87
|
- !ruby/object:Gem::Version
|
|
88
|
-
version: 1.
|
|
89
|
-
- !ruby/object:Gem::Dependency
|
|
90
|
-
name: codecov
|
|
91
|
-
requirement: !ruby/object:Gem::Requirement
|
|
92
|
-
requirements:
|
|
93
|
-
- - ">="
|
|
94
|
-
- !ruby/object:Gem::Version
|
|
95
|
-
version: 0.6.0
|
|
96
|
-
type: :development
|
|
97
|
-
prerelease: false
|
|
98
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
99
|
-
requirements:
|
|
100
|
-
- - ">="
|
|
101
|
-
- !ruby/object:Gem::Version
|
|
102
|
-
version: 0.6.0
|
|
88
|
+
version: 1.32.1
|
|
103
89
|
description: |2
|
|
104
90
|
Xsv is a fast, lightweight parser for Office Open XML spreadsheet files
|
|
105
91
|
(commonly known as Excel or .xlsx files). It strives to be minimal in the
|
|
@@ -150,14 +136,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
150
136
|
requirements:
|
|
151
137
|
- - ">="
|
|
152
138
|
- !ruby/object:Gem::Version
|
|
153
|
-
version: '2.
|
|
139
|
+
version: '2.7'
|
|
154
140
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
155
141
|
requirements:
|
|
156
142
|
- - ">="
|
|
157
143
|
- !ruby/object:Gem::Version
|
|
158
144
|
version: '0'
|
|
159
145
|
requirements: []
|
|
160
|
-
rubygems_version: 3.
|
|
146
|
+
rubygems_version: 3.5.1
|
|
161
147
|
signing_key:
|
|
162
148
|
specification_version: 4
|
|
163
149
|
summary: A fast and lightweight xlsx parser that provides nothing a CSV parser wouldn't
|