spreadsheetx 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.rspec +1 -0
- data/Gemfile +14 -0
- data/Gemfile.lock +30 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +27 -0
- data/Rakefile +49 -0
- data/VERSION +1 -0
- data/lib/spreadsheetx.rb +21 -0
- data/lib/spreadsheetx/workbook.rb +55 -0
- data/lib/spreadsheetx/worksheet.rb +88 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/spreadsheetx_spec.rb +85 -0
- data/templates/spec.xlsx +0 -0
- metadata +127 -0
data/.document
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
|
6
|
+
# Add dependencies to develop your gem here.
|
7
|
+
# Include everything needed to run rake, tests, features, etc.
|
8
|
+
group :development do
|
9
|
+
gem "rspec", "~> 2.3.0"
|
10
|
+
gem "bundler", "~> 1.0.0"
|
11
|
+
gem "jeweler", "~> 1.6.2"
|
12
|
+
gem "rcov", ">= 0"
|
13
|
+
gem "zipruby", "~> 0.3.6"
|
14
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
diff-lcs (1.1.2)
|
5
|
+
git (1.2.5)
|
6
|
+
jeweler (1.6.3)
|
7
|
+
bundler (~> 1.0)
|
8
|
+
git (>= 1.2.5)
|
9
|
+
rake
|
10
|
+
rake (0.9.2)
|
11
|
+
rcov (0.9.9)
|
12
|
+
rspec (2.3.0)
|
13
|
+
rspec-core (~> 2.3.0)
|
14
|
+
rspec-expectations (~> 2.3.0)
|
15
|
+
rspec-mocks (~> 2.3.0)
|
16
|
+
rspec-core (2.3.1)
|
17
|
+
rspec-expectations (2.3.0)
|
18
|
+
diff-lcs (~> 1.1.2)
|
19
|
+
rspec-mocks (2.3.0)
|
20
|
+
zipruby (0.3.6)
|
21
|
+
|
22
|
+
PLATFORMS
|
23
|
+
ruby
|
24
|
+
|
25
|
+
DEPENDENCIES
|
26
|
+
bundler (~> 1.0.0)
|
27
|
+
jeweler (~> 1.6.2)
|
28
|
+
rcov
|
29
|
+
rspec (~> 2.3.0)
|
30
|
+
zipruby (~> 0.3.6)
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Craig Ulliott
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
= spreadsheetx
|
2
|
+
|
3
|
+
This gem facilitates a templatized approach to working with Excel files. It only supports Microsoft's new .xlsx format (because it's xml based and somewhat sane to work with).
|
4
|
+
|
5
|
+
We use this gem to generate reports for clients, where the reports have substantial charts and styling throughout.
|
6
|
+
|
7
|
+
The work flow goes a little something like this:
|
8
|
+
* Create a report in Excel that has all your charts and styling
|
9
|
+
* Save the report with placeholder data
|
10
|
+
* Programmatically replace or add rows and cells
|
11
|
+
* When the new file is opened, formatting and charts are preserved
|
12
|
+
|
13
|
+
== Contributing to spreadsheetx
|
14
|
+
|
15
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
16
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
17
|
+
* Fork the project
|
18
|
+
* Start a feature/bugfix branch
|
19
|
+
* Commit and push until you are happy with your contribution
|
20
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
21
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
22
|
+
|
23
|
+
== Copyright
|
24
|
+
|
25
|
+
Copyright (c) 2011 Craig Ulliott. See LICENSE.txt for
|
26
|
+
further details.
|
27
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
+
gem.name = "spreadsheetx"
|
18
|
+
gem.homepage = "http://github.com/craigulliott/spreadsheetx"
|
19
|
+
gem.license = "MIT"
|
20
|
+
gem.summary = %Q{Facilitates opening and modifying existing xlsx excel spreadsheets}
|
21
|
+
gem.description = %Q{Using an existing xlsx file as a template, it allows you to modify cell values and add rows and columns. Facilitating a templateized approach to creating a new xlsx spreadsheet}
|
22
|
+
gem.email = "craigulliott@gmail.com"
|
23
|
+
gem.authors = ["Craig Ulliott"]
|
24
|
+
# dependencies defined in Gemfile
|
25
|
+
end
|
26
|
+
Jeweler::RubygemsDotOrgTasks.new
|
27
|
+
|
28
|
+
require 'rspec/core'
|
29
|
+
require 'rspec/core/rake_task'
|
30
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
31
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
32
|
+
end
|
33
|
+
|
34
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
35
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
36
|
+
spec.rcov = true
|
37
|
+
end
|
38
|
+
|
39
|
+
task :default => :spec
|
40
|
+
|
41
|
+
require 'rake/rdoctask'
|
42
|
+
Rake::RDocTask.new do |rdoc|
|
43
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
44
|
+
|
45
|
+
rdoc.rdoc_dir = 'rdoc'
|
46
|
+
rdoc.title = "spreadsheetx #{version}"
|
47
|
+
rdoc.rdoc_files.include('README*')
|
48
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
49
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/lib/spreadsheetx.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# zipruby is nice as it can modify an existing zip file, perfect for our usecase
|
2
|
+
require 'zipruby'
|
3
|
+
# we use this because it comes with ruby
|
4
|
+
require 'rexml/document'
|
5
|
+
# for copying files
|
6
|
+
require 'fileutils'
|
7
|
+
#
|
8
|
+
require 'spreadsheetx/workbook'
|
9
|
+
require 'spreadsheetx/worksheet'
|
10
|
+
|
11
|
+
module SpreadsheetX
|
12
|
+
|
13
|
+
class << self
|
14
|
+
|
15
|
+
def open(path)
|
16
|
+
SpreadsheetX::Workbook.new(path)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module SpreadsheetX
|
2
|
+
|
3
|
+
# This class represents an XLSX Document on disk
|
4
|
+
class Workbook
|
5
|
+
|
6
|
+
attr_reader :path
|
7
|
+
attr_reader :worksheets
|
8
|
+
|
9
|
+
# return a Workbook object which relates to an existing xlsx file on disk
|
10
|
+
def initialize(path)
|
11
|
+
@path = path
|
12
|
+
Zip::Archive.open(path) do |archive|
|
13
|
+
|
14
|
+
# open the workbook
|
15
|
+
archive.fopen('xl/workbook.xml') do |f|
|
16
|
+
|
17
|
+
# read contents of this file
|
18
|
+
file_contents = f.read
|
19
|
+
|
20
|
+
#parse the XML and build the worksheets
|
21
|
+
@worksheets = []
|
22
|
+
REXML::Document.new(file_contents).elements.each('workbook/sheets/sheet') do |node|
|
23
|
+
sheet_id = node.attributes['sheetId'].to_i
|
24
|
+
r_id = node.attributes['r:id'].gsub('rId','').to_i
|
25
|
+
name = node.attributes['name'].to_s
|
26
|
+
@worksheets.push SpreadsheetX::Worksheet.new(archive, sheet_id, r_id, name)
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# saves the binary form of the complete xlsx file to a new xlsx file
|
35
|
+
def save(destination_path)
|
36
|
+
|
37
|
+
# copy the xlsx file to the destination
|
38
|
+
FileUtils.cp(@path, destination_path)
|
39
|
+
|
40
|
+
# replace the xlsx files with the new workbooks
|
41
|
+
Zip::Archive.open(destination_path) do |ar|
|
42
|
+
|
43
|
+
# replace with the new worksheets
|
44
|
+
@worksheets.each do |worksheet|
|
45
|
+
ar.replace_buffer("xl/worksheets/sheet#{worksheet.r_id}.xml", worksheet.to_s)
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module SpreadsheetX
|
2
|
+
|
3
|
+
# Workbooks are made up of N Worksheets, this class represents a specific Worksheet.
|
4
|
+
class Worksheet
|
5
|
+
|
6
|
+
attr_reader :sheet_id
|
7
|
+
attr_reader :r_id
|
8
|
+
attr_reader :name
|
9
|
+
|
10
|
+
# return a Worksheet object which relates to a specific Worksheet
|
11
|
+
def initialize(archive, sheet_id, r_id, name)
|
12
|
+
@sheet_id = sheet_id
|
13
|
+
@r_id = r_id
|
14
|
+
@name = name
|
15
|
+
|
16
|
+
# open the workbook
|
17
|
+
archive.fopen("xl/worksheets/sheet#{@r_id}.xml") do |f|
|
18
|
+
|
19
|
+
# read contents of this file
|
20
|
+
file_contents = f.read
|
21
|
+
#parse the XML and hold the doc
|
22
|
+
@xml_doc = REXML::Document.new(file_contents)
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
# update the value of a particular cell, if the row or cell doesnt exist in the XML, then it will be created
|
29
|
+
def update_cell(col_number, row_number, val)
|
30
|
+
|
31
|
+
cell_id = SpreadsheetX::Worksheet.cell_id(col_number, row_number)
|
32
|
+
|
33
|
+
rows = @xml_doc.get_elements("worksheet/sheetData/row[@r=#{row_number}]")
|
34
|
+
# was this row found
|
35
|
+
if rows.empty?
|
36
|
+
# build a new row
|
37
|
+
row = @xml_doc.elements['worksheet'].elements['sheetData'].add_element('row', {'r' => row_number})
|
38
|
+
else
|
39
|
+
# x path returns an array, but we know there is only one row with this number
|
40
|
+
row = rows.first
|
41
|
+
end
|
42
|
+
|
43
|
+
cells = row.get_elements("c[@r='#{cell_id}']")
|
44
|
+
if cells.empty?
|
45
|
+
cell = row.add_element('c', {'r' => cell_id})
|
46
|
+
else
|
47
|
+
# x path returns an array, but we know there is only one row with this number
|
48
|
+
cell = cells.first
|
49
|
+
end
|
50
|
+
|
51
|
+
# first clear out any existing values
|
52
|
+
cell.delete_element('*')
|
53
|
+
|
54
|
+
# now we put the value in the cell
|
55
|
+
if val.kind_of? String
|
56
|
+
cell.attributes['t'] = 'inlineStr'
|
57
|
+
cell.add_element('is').add_element('t').add_text(val)
|
58
|
+
else
|
59
|
+
cell.attributes['t'] = nil
|
60
|
+
cell.add_element('v').add_text(val.to_s)
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
# the number of rows containing data this sheet has
|
66
|
+
# NOTE: this is the count of those rows, not the length of the document
|
67
|
+
def row_count
|
68
|
+
count = 0
|
69
|
+
@xml_doc.elements.each('worksheet/sheetData/row'){ count+=1 }
|
70
|
+
count
|
71
|
+
end
|
72
|
+
|
73
|
+
# returns the xml representation of this worksheet
|
74
|
+
def to_s
|
75
|
+
@xml_doc.to_s
|
76
|
+
end
|
77
|
+
|
78
|
+
# turns a cell address into its excel name, 1,1 = A1 2,3 = C2 etc.
|
79
|
+
def self.cell_id(col_number, row_number)
|
80
|
+
letter = 'A'
|
81
|
+
# some day, speed this up
|
82
|
+
(col_number.to_i-1).times{letter = letter.succ}
|
83
|
+
"#{letter}#{row_number}"
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
require 'rspec'
|
4
|
+
require 'spreadsheetx'
|
5
|
+
|
6
|
+
# Requires supporting files with custom matchers and macros, etc,
|
7
|
+
# in ./support/ and its subdirectories.
|
8
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
|
12
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "Spreadsheetx" do
|
4
|
+
|
5
|
+
it "opens xlsx files successfully" do
|
6
|
+
|
7
|
+
# a valid xlsx file used for testing
|
8
|
+
empty_xlsx_file = "#{File.dirname(__FILE__)}/../templates/spec.xlsx"
|
9
|
+
workbook = SpreadsheetX.open(empty_xlsx_file)
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
it "allow accessing worksheets" do
|
14
|
+
|
15
|
+
# a valid xlsx file used for testing
|
16
|
+
empty_xlsx_file = "#{File.dirname(__FILE__)}/../templates/spec.xlsx"
|
17
|
+
workbook = SpreadsheetX.open(empty_xlsx_file)
|
18
|
+
|
19
|
+
workbook.worksheets.length.should == 2
|
20
|
+
workbook.worksheets.last.name.should == 'Test'
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
it "allow accessing row counts" do
|
25
|
+
|
26
|
+
# a valid xlsx file used for testing
|
27
|
+
empty_xlsx_file = "#{File.dirname(__FILE__)}/../templates/spec.xlsx"
|
28
|
+
workbook = SpreadsheetX.open(empty_xlsx_file)
|
29
|
+
|
30
|
+
workbook.worksheets.last.row_count.should == 4
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
it "can be saved" do
|
35
|
+
|
36
|
+
# a valid xlsx file used for testing
|
37
|
+
empty_xlsx_file = "#{File.dirname(__FILE__)}/../templates/spec.xlsx"
|
38
|
+
workbook = SpreadsheetX.open(empty_xlsx_file)
|
39
|
+
|
40
|
+
new_xlsx_file = "#{File.dirname(__FILE__)}/../templates/spec_out.xlsx"
|
41
|
+
workbook.save(new_xlsx_file)
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
it "can convert an address of a cell to a cell name" do
|
46
|
+
|
47
|
+
SpreadsheetX::Worksheet.cell_id(1, 1).should == 'A1'
|
48
|
+
SpreadsheetX::Worksheet.cell_id(2, 1).should == 'B1'
|
49
|
+
SpreadsheetX::Worksheet.cell_id(27, 9).should == 'AA9'
|
50
|
+
SpreadsheetX::Worksheet.cell_id(26, 4).should == 'Z4'
|
51
|
+
SpreadsheetX::Worksheet.cell_id(820, 496).should == 'AEN496'
|
52
|
+
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
it "allows cell values to be updated" do
|
57
|
+
|
58
|
+
# a valid xlsx file used for testing
|
59
|
+
empty_xlsx_file = "#{File.dirname(__FILE__)}/../templates/spec.xlsx"
|
60
|
+
workbook = SpreadsheetX.open(empty_xlsx_file)
|
61
|
+
|
62
|
+
workbook.worksheets.last.update_cell(1, 1, 9)
|
63
|
+
workbook.worksheets.last.update_cell(1, 2, 'A')
|
64
|
+
workbook.worksheets.last.update_cell(1, 3, nil)
|
65
|
+
|
66
|
+
new_xlsx_file = "#{File.dirname(__FILE__)}/../templates/spec_changed_out.xlsx"
|
67
|
+
workbook.save(new_xlsx_file)
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
it "allows cells to be added" do
|
72
|
+
|
73
|
+
# a valid xlsx file used for testing
|
74
|
+
empty_xlsx_file = "#{File.dirname(__FILE__)}/../templates/spec.xlsx"
|
75
|
+
workbook = SpreadsheetX.open(empty_xlsx_file)
|
76
|
+
|
77
|
+
workbook.worksheets.last.update_cell(9, 9, 9)
|
78
|
+
workbook.worksheets.last.update_cell(9, 10, 'A')
|
79
|
+
|
80
|
+
new_xlsx_file = "#{File.dirname(__FILE__)}/../templates/spec_added_out.xlsx"
|
81
|
+
workbook.save(new_xlsx_file)
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
data/templates/spec.xlsx
ADDED
Binary file
|
metadata
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: spreadsheetx
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.1.0
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Craig Ulliott
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-07-02 00:00:00 -05:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: rspec
|
18
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
20
|
+
requirements:
|
21
|
+
- - ~>
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 2.3.0
|
24
|
+
type: :development
|
25
|
+
prerelease: false
|
26
|
+
version_requirements: *id001
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
30
|
+
none: false
|
31
|
+
requirements:
|
32
|
+
- - ~>
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: 1.0.0
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: *id002
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: jeweler
|
40
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 1.6.2
|
46
|
+
type: :development
|
47
|
+
prerelease: false
|
48
|
+
version_requirements: *id003
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: rcov
|
51
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: "0"
|
57
|
+
type: :development
|
58
|
+
prerelease: false
|
59
|
+
version_requirements: *id004
|
60
|
+
- !ruby/object:Gem::Dependency
|
61
|
+
name: zipruby
|
62
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ~>
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: 0.3.6
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: *id005
|
71
|
+
description: Using an existing xlsx file as a template, it allows you to modify cell values and add rows and columns. Facilitating a templateized approach to creating a new xlsx spreadsheet
|
72
|
+
email: craigulliott@gmail.com
|
73
|
+
executables: []
|
74
|
+
|
75
|
+
extensions: []
|
76
|
+
|
77
|
+
extra_rdoc_files:
|
78
|
+
- LICENSE.txt
|
79
|
+
- README.rdoc
|
80
|
+
files:
|
81
|
+
- .document
|
82
|
+
- .rspec
|
83
|
+
- Gemfile
|
84
|
+
- Gemfile.lock
|
85
|
+
- LICENSE.txt
|
86
|
+
- README.rdoc
|
87
|
+
- Rakefile
|
88
|
+
- VERSION
|
89
|
+
- lib/spreadsheetx.rb
|
90
|
+
- lib/spreadsheetx/workbook.rb
|
91
|
+
- lib/spreadsheetx/worksheet.rb
|
92
|
+
- spec/spec_helper.rb
|
93
|
+
- spec/spreadsheetx_spec.rb
|
94
|
+
- templates/spec.xlsx
|
95
|
+
has_rdoc: true
|
96
|
+
homepage: http://github.com/craigulliott/spreadsheetx
|
97
|
+
licenses:
|
98
|
+
- MIT
|
99
|
+
post_install_message:
|
100
|
+
rdoc_options: []
|
101
|
+
|
102
|
+
require_paths:
|
103
|
+
- lib
|
104
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
hash: -715639084265841052
|
110
|
+
segments:
|
111
|
+
- 0
|
112
|
+
version: "0"
|
113
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
114
|
+
none: false
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: "0"
|
119
|
+
requirements: []
|
120
|
+
|
121
|
+
rubyforge_project:
|
122
|
+
rubygems_version: 1.6.2
|
123
|
+
signing_key:
|
124
|
+
specification_version: 3
|
125
|
+
summary: Facilitates opening and modifying existing xlsx excel spreadsheets
|
126
|
+
test_files: []
|
127
|
+
|