bayonet 0.2.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 +7 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.ruby-version +1 -0
- data/.travis.yml +9 -0
- data/Gemfile +11 -0
- data/LICENSE.txt +21 -0
- data/README.md +58 -0
- data/Rakefile +2 -0
- data/bayonet.gemspec +26 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/lib/bayonet.rb +8 -0
- data/lib/bayonet/cell.rb +37 -0
- data/lib/bayonet/node_creation.rb +79 -0
- data/lib/bayonet/sheet.rb +66 -0
- data/lib/bayonet/version.rb +3 -0
- data/lib/bayonet/workbook.rb +79 -0
- metadata +120 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2bec54b0bad049f5802aca27083b33bc782290dc
|
4
|
+
data.tar.gz: 5ee3c94ac1f7ddd9b70675af7109b6952efed880
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fcd56d9e58e861a38fb7976997f6487637c8f3e46a9d1c3426fd3cba5abfc8c74c284115cac3b8d5c06629fc328b7acb260749a1c31dfcdbf9e43e9c0d36ec37
|
7
|
+
data.tar.gz: 193a3fe91b11c9baa8adad8fd5990b548eb290002e3b72dddc30c7dfb39ec55ed788d77c918c621cd4a05f05876f4bc0bf97d1f776e51402c54ed708e83619cc
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.2.2
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Thomas Ritter
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# Bayonet gem
|
2
|
+
|
3
|
+
[](https://travis-ci.org/nethad/bayonet)
|
4
|
+
[](https://codeclimate.com/github/nethad/bayonet)
|
5
|
+
[](https://codeclimate.com/github/nethad/bayonet/coverage)
|
6
|
+
|
7
|
+
Bayonet is a Microsoft Excel write-only gem that reads and produces XLSX files.
|
8
|
+
It's strength lies in the fact that it's able to open bigger Excel files (even with macros!) -- and write cells without touching the rest of the Excel file. I've written the gem because *roo* was unbearably slow and was using ~1GB of RAM to read a 5MB XLSX file.
|
9
|
+
|
10
|
+
|
11
|
+
**WARNING:** Use this gem at your own risk. It's writing directly to sheet XML files and uses a few tricks that Microsoft Excel 2010 seems to be fine with, but I cannot guarantee that future (or past) versions will play along. That being said, I've used it successfully in one of my projects. If you find any bugs, let me know.
|
12
|
+
|
13
|
+
### Usage example
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
workbook = Bayonet::Workbook.new(a_file_path)
|
17
|
+
|
18
|
+
workbook.on_sheet('The First Sheet') do |sheet|
|
19
|
+
sheet.set_typed_cell('A', 1, "I'm a string") # set a cell auto-typed to a string
|
20
|
+
sheet.set_typed_cell('B', 1, 42) # set a cell auto-typed to a number
|
21
|
+
sheet.set_cell('C', 1, "Some value") # set a cell without setting its type
|
22
|
+
sheet.write_string('D', 1, "Some value") # set a cell and forcing it to be a string
|
23
|
+
sheet.write_number('E', 1, 23) # set a cell and forcing it to be a number
|
24
|
+
end
|
25
|
+
|
26
|
+
workbook.write_and_close(output_file_path)
|
27
|
+
```
|
28
|
+
|
29
|
+
See the *Tips* section for more information.
|
30
|
+
|
31
|
+
### When to use Bayonet?
|
32
|
+
|
33
|
+
* If you want to modify an existing, possibly huge XLSX file.
|
34
|
+
* If other gems fail at the task or are too slow.
|
35
|
+
|
36
|
+
### When should I use other gems?
|
37
|
+
|
38
|
+
* If you want to create an XLSX file from scratch.
|
39
|
+
* If you plan to open legacy (binary) XLS files.
|
40
|
+
* If your XLSX file is small and other gems are working fine.
|
41
|
+
|
42
|
+
Other gems I can recommend are:
|
43
|
+
|
44
|
+
* [roo](https://rubygems.org/gems/roo) (read/write, lots of features and supported formats)
|
45
|
+
* [axlsx](https://rubygems.org/gems/axlsx) (write-only)
|
46
|
+
* [creek](https://rubygems.org/gems/creek) (read-only, very fast)
|
47
|
+
|
48
|
+
|
49
|
+
### Tips
|
50
|
+
|
51
|
+
#### When should I use `set_typed_cell` vs. `set_cell`?
|
52
|
+
|
53
|
+
Normally you should use `set_typed_cell`, which sets the cell type correctly and falls back to `string`. If you're using a prepared XLSX sheet you might not want to override the current cell type. You should use `set_cell` for those instances. If you want to force a cell type, you can use `write_string` or `write_number` instead, but this should rarely be necessary.
|
54
|
+
|
55
|
+
#### Why can't I read cells?
|
56
|
+
|
57
|
+
It's simply not been implemented yet. I've been writing to template files with pre-defined cells to fill, so reading cells was not necessary. It shouldn't be hard to implemented, though there might be some edge cases I haven't considered yet, that's why I left it out for now. Pull requests are welcome, otherwise I'd suggest to use other gems for that.
|
58
|
+
|
data/Rakefile
ADDED
data/bayonet.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'bayonet/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "bayonet"
|
8
|
+
spec.version = Bayonet::VERSION
|
9
|
+
spec.authors = ["Thomas Ritter"]
|
10
|
+
spec.email = ["ritter.thomas@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Bayonet is a Microsoft Excel write-only gem that reads and produces XLSX files.}
|
13
|
+
spec.description = %q{Bayonet is a Microsoft Excel write-only gem that reads and produces XLSX files. It's strength lies in the fact that it's able to open bigger Excel files (even with macros!) -- and write cells without touching the rest of the Excel file.}
|
14
|
+
spec.homepage = "https://github.com/nethad/bayonet"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.bindir = "exe"
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
23
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
24
|
+
spec.add_development_dependency "rubyzip", "~> 1.1"
|
25
|
+
spec.add_development_dependency "nokogiri", "~> 1.6"
|
26
|
+
end
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "bayonet"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
data/lib/bayonet.rb
ADDED
data/lib/bayonet/cell.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
module Bayonet
|
2
|
+
class Cell
|
3
|
+
|
4
|
+
ROW_MATCHER = /\A[A-Z]+\z/ # is only A-Z characters, upper case.
|
5
|
+
|
6
|
+
def initialize(row, column)
|
7
|
+
@row = row
|
8
|
+
@column = column
|
9
|
+
end
|
10
|
+
|
11
|
+
def label
|
12
|
+
cell_label = "#{row}#{column}"
|
13
|
+
if valid?
|
14
|
+
cell_label
|
15
|
+
else
|
16
|
+
raise "Invalid cell: #{cell_label}."
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def valid?
|
21
|
+
row_valid? && column_valid?
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
attr_reader :row, :column
|
27
|
+
|
28
|
+
def row_valid?
|
29
|
+
(row =~ ROW_MATCHER) != nil
|
30
|
+
end
|
31
|
+
|
32
|
+
def column_valid?
|
33
|
+
column.is_a?(Integer) && column >= 1
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module Bayonet
|
2
|
+
class NodeCreation
|
3
|
+
|
4
|
+
attr_reader :cell_label, :sheet
|
5
|
+
|
6
|
+
def initialize(cell_label, sheet)
|
7
|
+
@cell_label = cell_label
|
8
|
+
@sheet = sheet
|
9
|
+
end
|
10
|
+
|
11
|
+
def get_or_create_cell_node
|
12
|
+
unless has_cell_node?
|
13
|
+
create_nodes
|
14
|
+
end
|
15
|
+
|
16
|
+
cell_node
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def xml
|
22
|
+
sheet.xml
|
23
|
+
end
|
24
|
+
|
25
|
+
def cell_node
|
26
|
+
@cell_node ||= xml.at_css("c[r=\"#{cell_label}\"]")
|
27
|
+
end
|
28
|
+
|
29
|
+
def has_cell_node?
|
30
|
+
!cell_node.nil?
|
31
|
+
end
|
32
|
+
|
33
|
+
def row_node
|
34
|
+
@row_node ||= xml.at_css("row[r=\"#{row_number}\"]")
|
35
|
+
end
|
36
|
+
|
37
|
+
def has_row_node?
|
38
|
+
!row_node.nil?
|
39
|
+
end
|
40
|
+
|
41
|
+
def row_number
|
42
|
+
@row_number ||= cell_label.gsub(/[^\d]/, '')
|
43
|
+
end
|
44
|
+
|
45
|
+
def sheet_data_node
|
46
|
+
@sheet_data_node ||= xml.at_css('sheetData')
|
47
|
+
end
|
48
|
+
|
49
|
+
def create_cell_node
|
50
|
+
create_node('c', row_node, cell_label)
|
51
|
+
end
|
52
|
+
|
53
|
+
def create_row_node
|
54
|
+
create_node('row', sheet_data_node, row_number)
|
55
|
+
end
|
56
|
+
|
57
|
+
def create_node(tag, parent_node, value)
|
58
|
+
Nokogiri::XML::Node.new(tag, parent_node).tap do |node|
|
59
|
+
node['r'] = value
|
60
|
+
parent_node.add_child(node)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def create_row_node_with_cell_node
|
65
|
+
row_node = create_row_node
|
66
|
+
cell_node = create_cell_node
|
67
|
+
row_node.add_child(cell_node)
|
68
|
+
end
|
69
|
+
|
70
|
+
def create_nodes
|
71
|
+
if has_row_node?
|
72
|
+
create_cell_node
|
73
|
+
else
|
74
|
+
create_row_node_with_cell_node
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module Bayonet
|
2
|
+
class Sheet
|
3
|
+
|
4
|
+
def initialize(name, workbook)
|
5
|
+
@name = name
|
6
|
+
@workbook = workbook
|
7
|
+
end
|
8
|
+
|
9
|
+
def path
|
10
|
+
"xl/worksheets/sheet#{id}.xml"
|
11
|
+
end
|
12
|
+
|
13
|
+
def xml
|
14
|
+
@xml ||= read_and_parse_xml
|
15
|
+
end
|
16
|
+
|
17
|
+
def write_string(cell_row, cell_column, value)
|
18
|
+
set_cell(cell_row, cell_column, value.to_s, :str)
|
19
|
+
end
|
20
|
+
|
21
|
+
def write_number(cell_row, cell_column, value)
|
22
|
+
set_cell(cell_row, cell_column, value, :n)
|
23
|
+
end
|
24
|
+
|
25
|
+
def set_cell(cell_row, cell_column, value, type = nil)
|
26
|
+
cell_node = get_or_create_cell_node(Cell.new(cell_row, cell_column))
|
27
|
+
cell_node['t'] = type unless type.nil?
|
28
|
+
set_value(cell_node, value)
|
29
|
+
end
|
30
|
+
|
31
|
+
def set_typed_cell(cell_row, cell_column, value)
|
32
|
+
if (value.is_a?(Numeric))
|
33
|
+
write_number(cell_row, cell_column, value)
|
34
|
+
else
|
35
|
+
write_string(cell_row, cell_column, value)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
attr_reader :name, :workbook
|
42
|
+
|
43
|
+
def id
|
44
|
+
@id ||= workbook.xml.at_css("sheets sheet[name=\"#{name}\"]")["r:id"][3..-1]
|
45
|
+
end
|
46
|
+
|
47
|
+
def read_and_parse_xml
|
48
|
+
entry = workbook.zip_file.find_entry(path)
|
49
|
+
Nokogiri::XML.parse(entry.get_input_stream)
|
50
|
+
end
|
51
|
+
|
52
|
+
def get_or_create_cell_node(cell)
|
53
|
+
Bayonet::NodeCreation.new(cell.label, self).get_or_create_cell_node
|
54
|
+
end
|
55
|
+
|
56
|
+
def set_value(cell_node, value)
|
57
|
+
if cell_node.children.nil? || cell_node.children.empty?
|
58
|
+
value_node = Nokogiri::XML::Node.new('v', cell_node)
|
59
|
+
value_node.content = value
|
60
|
+
cell_node.add_child value_node
|
61
|
+
else
|
62
|
+
cell_node.at_css("v").content = value
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'zip'
|
2
|
+
require 'nokogiri'
|
3
|
+
|
4
|
+
module Bayonet
|
5
|
+
class Workbook
|
6
|
+
|
7
|
+
WORKBOOK_PATH = 'xl/workbook.xml'
|
8
|
+
|
9
|
+
def initialize(file)
|
10
|
+
@file = file
|
11
|
+
end
|
12
|
+
|
13
|
+
def zip_file
|
14
|
+
@zip_file ||= Zip::File.open(file)
|
15
|
+
end
|
16
|
+
|
17
|
+
def xml
|
18
|
+
@xml ||= read_and_parse_xml
|
19
|
+
end
|
20
|
+
|
21
|
+
def on_sheet(sheet_name, &block)
|
22
|
+
sheet = find_sheet_by_name_and_cache(sheet_name)
|
23
|
+
block.call(sheet)
|
24
|
+
end
|
25
|
+
|
26
|
+
def write(file)
|
27
|
+
Zip::File.open(file, Zip::File::CREATE) do |destination|
|
28
|
+
zip_file.each do |entry|
|
29
|
+
destination.get_output_stream(entry.name) do |file_stream|
|
30
|
+
write_modifications(entry, file_stream)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def close
|
37
|
+
zip_file.close
|
38
|
+
end
|
39
|
+
|
40
|
+
def write_and_close(file)
|
41
|
+
write(file)
|
42
|
+
close
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
attr_reader :file
|
48
|
+
|
49
|
+
def find_sheet_by_name_and_cache(sheet_name)
|
50
|
+
return modified_sheets[sheet_name] if modified_sheets.key?(sheet_name)
|
51
|
+
|
52
|
+
sheet = Bayonet::Sheet.new(sheet_name, self)
|
53
|
+
modified_sheets[sheet_name] = sheet
|
54
|
+
sheet
|
55
|
+
end
|
56
|
+
|
57
|
+
def find_sheet_by_path(path)
|
58
|
+
modified_sheets.values.detect { |sheet| sheet.path == path }
|
59
|
+
end
|
60
|
+
|
61
|
+
def write_modifications(entry, file_stream)
|
62
|
+
sheet = find_sheet_by_path(entry.name)
|
63
|
+
if sheet
|
64
|
+
file_stream.write(sheet.xml.to_s)
|
65
|
+
else
|
66
|
+
file_stream.write(zip_file.read(entry.name))
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def modified_sheets
|
71
|
+
@modified_sheets ||= {}
|
72
|
+
end
|
73
|
+
|
74
|
+
def read_and_parse_xml
|
75
|
+
entry = zip_file.find_entry(WORKBOOK_PATH)
|
76
|
+
Nokogiri::XML.parse(entry.get_input_stream)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
metadata
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bayonet
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Thomas Ritter
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-06-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rubyzip
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.1'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.1'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: nokogiri
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.6'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.6'
|
69
|
+
description: Bayonet is a Microsoft Excel write-only gem that reads and produces XLSX
|
70
|
+
files. It's strength lies in the fact that it's able to open bigger Excel files
|
71
|
+
(even with macros!) -- and write cells without touching the rest of the Excel file.
|
72
|
+
email:
|
73
|
+
- ritter.thomas@gmail.com
|
74
|
+
executables: []
|
75
|
+
extensions: []
|
76
|
+
extra_rdoc_files: []
|
77
|
+
files:
|
78
|
+
- ".gitignore"
|
79
|
+
- ".rspec"
|
80
|
+
- ".ruby-version"
|
81
|
+
- ".travis.yml"
|
82
|
+
- Gemfile
|
83
|
+
- LICENSE.txt
|
84
|
+
- README.md
|
85
|
+
- Rakefile
|
86
|
+
- bayonet.gemspec
|
87
|
+
- bin/console
|
88
|
+
- bin/setup
|
89
|
+
- lib/bayonet.rb
|
90
|
+
- lib/bayonet/cell.rb
|
91
|
+
- lib/bayonet/node_creation.rb
|
92
|
+
- lib/bayonet/sheet.rb
|
93
|
+
- lib/bayonet/version.rb
|
94
|
+
- lib/bayonet/workbook.rb
|
95
|
+
homepage: https://github.com/nethad/bayonet
|
96
|
+
licenses:
|
97
|
+
- MIT
|
98
|
+
metadata: {}
|
99
|
+
post_install_message:
|
100
|
+
rdoc_options: []
|
101
|
+
require_paths:
|
102
|
+
- lib
|
103
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - ">="
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
113
|
+
requirements: []
|
114
|
+
rubyforge_project:
|
115
|
+
rubygems_version: 2.4.5
|
116
|
+
signing_key:
|
117
|
+
specification_version: 4
|
118
|
+
summary: Bayonet is a Microsoft Excel write-only gem that reads and produces XLSX
|
119
|
+
files.
|
120
|
+
test_files: []
|