jruby-poi 0.8.2 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml CHANGED
@@ -1,2 +1,4 @@
1
- rvm:
2
- - jruby
1
+ language: ruby
2
+ rvm:
3
+ - jruby-18mode
4
+ - jruby-19mode
data/Gemfile CHANGED
@@ -3,7 +3,7 @@ source "http://rubygems.org"
3
3
  # Add dependencies to develop your gem here.
4
4
  # Include everything needed to run rake, tests, features, etc.
5
5
  group :development do
6
- gem "rspec", ">= 2.5.0"
7
- gem "jeweler", ">= 1.6.0"
8
- gem "rcov", ">= 0"
6
+ gem "rspec", ">= 2.11.0"
7
+ gem "jeweler", ">= 1.8.4"
8
+ gem "jruby-openssl"
9
9
  end
data/Gemfile.lock CHANGED
@@ -1,29 +1,35 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
- diff-lcs (1.1.2)
4
+ bouncy-castle-java (1.5.0146.1)
5
+ diff-lcs (1.1.3)
5
6
  git (1.2.5)
6
- jeweler (1.6.0)
7
- bundler (~> 1.0.0)
7
+ jeweler (1.8.4)
8
+ bundler (~> 1.0)
8
9
  git (>= 1.2.5)
9
10
  rake
10
- rake (0.9.0)
11
- rcov (0.9.9)
12
- rcov (0.9.9-java)
13
- rspec (2.6.0)
14
- rspec-core (~> 2.6.0)
15
- rspec-expectations (~> 2.6.0)
16
- rspec-mocks (~> 2.6.0)
17
- rspec-core (2.6.2)
18
- rspec-expectations (2.6.0)
19
- diff-lcs (~> 1.1.2)
20
- rspec-mocks (2.6.0)
11
+ rdoc
12
+ jruby-openssl (0.7.7)
13
+ bouncy-castle-java (>= 1.5.0146.1)
14
+ json (1.7.3)
15
+ json (1.7.3-java)
16
+ rake (0.9.2.2)
17
+ rdoc (3.12)
18
+ json (~> 1.4)
19
+ rspec (2.11.0)
20
+ rspec-core (~> 2.11.0)
21
+ rspec-expectations (~> 2.11.0)
22
+ rspec-mocks (~> 2.11.0)
23
+ rspec-core (2.11.1)
24
+ rspec-expectations (2.11.1)
25
+ diff-lcs (~> 1.1.3)
26
+ rspec-mocks (2.11.1)
21
27
 
22
28
  PLATFORMS
23
29
  java
24
30
  ruby
25
31
 
26
32
  DEPENDENCIES
27
- jeweler (>= 1.6.0)
28
- rcov
29
- rspec (>= 2.5.0)
33
+ jeweler (>= 1.8.4)
34
+ jruby-openssl
35
+ rspec (>= 2.11.0)
data/README.markdown CHANGED
@@ -1,6 +1,8 @@
1
1
  [jruby-poi](http://github.com/kameeoze/jruby-poi)
2
2
  =========
3
3
 
4
+ [![Build Status](https://secure.travis-ci.org/kameeoze/jruby-poi.png)](http://travis-ci.org/kameeoze/jruby-poi)
5
+
4
6
  This little gem provides an alternative interface to the Apache POI java library, for JRuby. For now the API is targeted at wrapping spreadsheets. We may expand this in the future.
5
7
 
6
8
  INSTALL
@@ -62,6 +64,8 @@ TODO
62
64
  * fix reading ODS files -- we have a broken spec for this in io_spec.rb
63
65
  * add APIs for updating cells in a spreadsheet
64
66
  * create API for non-spreadsheet files
67
+ * rdocs
68
+ * tutorials, and/or better samples
65
69
 
66
70
  Contributors
67
71
  ============
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.8.2
1
+ 0.9.0
data/jruby-poi.gemspec CHANGED
@@ -4,15 +4,14 @@
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
- s.name = %q{jruby-poi}
8
- s.version = "0.8.2"
7
+ s.name = "jruby-poi"
8
+ s.version = "0.9.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Scott Deming", "Jason Rogers"]
12
- s.date = %q{2011-05-22}
13
- s.description = %q{A rubyesque library for manipulating spreadsheets and other document types for jruby, using Apache POI.}
12
+ s.date = "2012-10-15"
13
+ s.description = "A rubyesque library for manipulating spreadsheets and other document types for jruby, using Apache POI."
14
14
  s.email = ["sdeming@makefile.com", "jacaetevha@gmail.com"]
15
- s.executables = ["autospec", "htmldiff", "ldiff", "rdebug", "rspec"]
16
15
  s.extra_rdoc_files = [
17
16
  "LICENSE",
18
17
  "README.markdown"
@@ -26,20 +25,16 @@ Gem::Specification.new do |s|
26
25
  "README.markdown",
27
26
  "Rakefile",
28
27
  "VERSION",
29
- "bin/autospec",
30
- "bin/htmldiff",
31
- "bin/ldiff",
32
- "bin/rdebug",
33
- "bin/rspec",
34
28
  "jruby-poi.gemspec",
35
29
  "lib/ooxml-lib/dom4j-1.6.1.jar",
36
- "lib/ooxml-lib/geronimo-stax-api_1.0_spec-1.0.jar",
30
+ "lib/ooxml-lib/stax-api-1.0.1.jar",
37
31
  "lib/ooxml-lib/xmlbeans-2.3.0.jar",
38
- "lib/poi-3.7-20101029.jar",
39
- "lib/poi-examples-3.7-20101029.jar",
40
- "lib/poi-ooxml-3.7-20101029.jar",
41
- "lib/poi-ooxml-schemas-3.7-20101029.jar",
42
- "lib/poi-scratchpad-3.7-20101029.jar",
32
+ "lib/poi-3.8-20120326.jar",
33
+ "lib/poi-examples-3.8-20120326.jar",
34
+ "lib/poi-excelant-3.8-20120326.jar",
35
+ "lib/poi-ooxml-3.8-20120326.jar",
36
+ "lib/poi-ooxml-schemas-3.8-20120326.jar",
37
+ "lib/poi-scratchpad-3.8-20120326.jar",
43
38
  "lib/poi.rb",
44
39
  "lib/poi/workbook.rb",
45
40
  "lib/poi/workbook/area.rb",
@@ -63,28 +58,28 @@ Gem::Specification.new do |s|
63
58
  "spec/writing_spec.rb",
64
59
  "spec_debug.sh"
65
60
  ]
66
- s.homepage = %q{http://github.com/kameeoze/jruby-poi}
61
+ s.homepage = "http://github.com/kameeoze/jruby-poi"
67
62
  s.licenses = ["Apache"]
68
63
  s.require_paths = ["lib"]
69
- s.rubygems_version = %q{1.5.1}
70
- s.summary = %q{Apache POI class library for jruby}
64
+ s.rubygems_version = "1.8.24"
65
+ s.summary = "Apache POI class library for jruby"
71
66
 
72
67
  if s.respond_to? :specification_version then
73
68
  s.specification_version = 3
74
69
 
75
70
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
76
- s.add_development_dependency(%q<rspec>, [">= 2.5.0"])
77
- s.add_development_dependency(%q<jeweler>, [">= 1.6.0"])
78
- s.add_development_dependency(%q<rcov>, [">= 0"])
71
+ s.add_development_dependency(%q<rspec>, [">= 2.11.0"])
72
+ s.add_development_dependency(%q<jeweler>, [">= 1.8.4"])
73
+ s.add_development_dependency(%q<jruby-openssl>, [">= 0"])
79
74
  else
80
- s.add_dependency(%q<rspec>, [">= 2.5.0"])
81
- s.add_dependency(%q<jeweler>, [">= 1.6.0"])
82
- s.add_dependency(%q<rcov>, [">= 0"])
75
+ s.add_dependency(%q<rspec>, [">= 2.11.0"])
76
+ s.add_dependency(%q<jeweler>, [">= 1.8.4"])
77
+ s.add_dependency(%q<jruby-openssl>, [">= 0"])
83
78
  end
84
79
  else
85
- s.add_dependency(%q<rspec>, [">= 2.5.0"])
86
- s.add_dependency(%q<jeweler>, [">= 1.6.0"])
87
- s.add_dependency(%q<rcov>, [">= 0"])
80
+ s.add_dependency(%q<rspec>, [">= 2.11.0"])
81
+ s.add_dependency(%q<jeweler>, [">= 1.8.4"])
82
+ s.add_dependency(%q<jruby-openssl>, [">= 0"])
88
83
  end
89
84
  end
90
85
 
Binary file
Binary file
Binary file
Binary file
Binary file
data/lib/poi.rb CHANGED
@@ -2,14 +2,13 @@ JRUBY_POI_LIB_PATH=File.expand_path(File.dirname(__FILE__))
2
2
 
3
3
  # Java
4
4
  require 'java'
5
- require File.join(JRUBY_POI_LIB_PATH, 'poi-3.7-20101029.jar')
6
- require File.join(JRUBY_POI_LIB_PATH, 'poi-ooxml-3.7-20101029.jar')
7
- require File.join(JRUBY_POI_LIB_PATH, 'poi-ooxml-schemas-3.7-20101029.jar')
8
- require File.join(JRUBY_POI_LIB_PATH, 'poi-scratchpad-3.7-20101029.jar')
5
+ require File.join(JRUBY_POI_LIB_PATH, 'poi-3.8-20120326.jar')
6
+ require File.join(JRUBY_POI_LIB_PATH, 'poi-ooxml-3.8-20120326.jar')
7
+ require File.join(JRUBY_POI_LIB_PATH, 'poi-ooxml-schemas-3.8-20120326.jar')
8
+ require File.join(JRUBY_POI_LIB_PATH, 'poi-scratchpad-3.8-20120326.jar')
9
9
  require File.join(JRUBY_POI_LIB_PATH, 'ooxml-lib', 'xmlbeans-2.3.0.jar')
10
10
  require File.join(JRUBY_POI_LIB_PATH, 'ooxml-lib', 'dom4j-1.6.1.jar')
11
- require File.join(JRUBY_POI_LIB_PATH, 'ooxml-lib', 'geronimo-stax-api_1.0_spec-1.0.jar')
12
-
11
+ require File.join(JRUBY_POI_LIB_PATH, 'ooxml-lib', 'stax-api-1.0.1.jar')
13
12
 
14
13
  # Ruby
15
14
  require File.join(JRUBY_POI_LIB_PATH, 'poi', 'workbook')
@@ -1,81 +1,81 @@
1
- module POI
2
- class Area
3
- def initialize reference
4
- @ref = reference
5
- end
6
-
7
- def in workbook
8
- if single_cell_reference?
9
- ref = area.all_referenced_cells.first
10
- return [workbook.single_cell ref]
11
- end
12
-
13
- begin
14
- by_column = {}
15
- # refs = area.all_referenced_cells
16
- # slices = refs.enum_slice(refs.length/15)
17
- # slices.collect do |cell_refs|
18
- # Thread.start do
19
- # cell_refs.each do |cell_ref|
20
- # first = workbook.worksheets[cell_ref.sheet_name].first_row
21
- # last = workbook.worksheets[cell_ref.sheet_name].last_row
22
- # next unless cell_ref.row >= first && cell_ref.row <= last
23
- #
24
- # # ref = POI::CELL_REF.new(c.format_as_string)
25
- # cell = workbook.single_cell cell_ref
26
- # (by_column[cell_ref.cell_ref_parts.collect.last] ||= []) << cell
27
- # end
28
- # end
29
- # end.each {|t| t.join}
30
-
31
- area.all_referenced_cells.each do |cell_ref|
32
- first = workbook.worksheets[cell_ref.sheet_name].first_row
33
- last = workbook.worksheets[cell_ref.sheet_name].last_row
34
- next unless cell_ref.row >= first && cell_ref.row <= last
35
-
36
- # ref = POI::CELL_REF.new(c.format_as_string)
37
- cell = workbook.single_cell cell_ref
38
- (by_column[cell_ref.cell_ref_parts.collect.last] ||= []) << cell
39
- end
40
-
41
- by_column.each do |key, cells|
42
- by_column[key] = cells.compact
43
- end
44
-
45
- if by_column.length == 1
46
- by_column.values.flatten
47
- else
48
- by_column
49
- end
50
- rescue
51
- []
52
- end
53
- end
54
-
55
- def single_cell_reference?
56
- area.single_cell? #@ref == getFirstCell.formatAsString rescue false
57
- end
58
-
59
- private
60
- def area
61
- @area ||= new_area_reference
62
- end
63
-
64
- def new_area_reference
65
- begin
66
- return POI::AREA_REF.new(@ref)
67
- rescue
68
- # not a valid reference, so proceed through to see if it's a column-based reference
69
- end
70
- sheet_parts = @ref.split('!')
71
- area_parts = sheet_parts.last.split(':')
72
- area_start = "#{sheet_parts.first}!#{area_parts.first}"
73
- area_end = area_parts.last
74
- begin
75
- POI::AREA_REF.getWholeColumn(area_start, area_end)
76
- rescue
77
- raise "could not determine area reference for #{@ref}: #{$!.message}"
78
- end
79
- end
80
- end
81
- end
1
+ module POI
2
+ class Area
3
+ def initialize reference
4
+ @ref = reference
5
+ end
6
+
7
+ def in workbook
8
+ if single_cell_reference?
9
+ ref = area.all_referenced_cells.first
10
+ return [workbook.single_cell(ref)]
11
+ end
12
+
13
+ begin
14
+ by_column = {}
15
+ # refs = area.all_referenced_cells
16
+ # slices = refs.enum_slice(refs.length/15)
17
+ # slices.collect do |cell_refs|
18
+ # Thread.start do
19
+ # cell_refs.each do |cell_ref|
20
+ # first = workbook.worksheets[cell_ref.sheet_name].first_row
21
+ # last = workbook.worksheets[cell_ref.sheet_name].last_row
22
+ # next unless cell_ref.row >= first && cell_ref.row <= last
23
+ #
24
+ # # ref = POI::CELL_REF.new(c.format_as_string)
25
+ # cell = workbook.single_cell cell_ref
26
+ # (by_column[cell_ref.cell_ref_parts.collect.last] ||= []) << cell
27
+ # end
28
+ # end
29
+ # end.each {|t| t.join}
30
+
31
+ area.all_referenced_cells.each do |cell_ref|
32
+ first = workbook.worksheets[cell_ref.sheet_name].first_row
33
+ last = workbook.worksheets[cell_ref.sheet_name].last_row
34
+ next unless cell_ref.row >= first && cell_ref.row <= last
35
+
36
+ # ref = POI::CELL_REF.new(c.format_as_string)
37
+ cell = workbook.single_cell cell_ref
38
+ (by_column[cell_ref.cell_ref_parts.to_a.last] ||= []) << cell
39
+ end
40
+
41
+ by_column.each do |key, cells|
42
+ by_column[key] = cells.compact
43
+ end
44
+
45
+ if by_column.length == 1
46
+ by_column.values.flatten
47
+ else
48
+ by_column
49
+ end
50
+ rescue
51
+ []
52
+ end
53
+ end
54
+
55
+ def single_cell_reference?
56
+ area.single_cell? #@ref == getFirstCell.formatAsString rescue false
57
+ end
58
+
59
+ private
60
+ def area
61
+ @area ||= new_area_reference
62
+ end
63
+
64
+ def new_area_reference
65
+ begin
66
+ return POI::AREA_REF.new(@ref)
67
+ rescue
68
+ # not a valid reference, so proceed through to see if it's a column-based reference
69
+ end
70
+ sheet_parts = @ref.split('!')
71
+ area_parts = sheet_parts.last.split(':')
72
+ area_start = "#{sheet_parts.first}!#{area_parts.first}"
73
+ area_end = area_parts.last
74
+ begin
75
+ POI::AREA_REF.getWholeColumn(area_start, area_end)
76
+ rescue
77
+ raise "could not determine area reference for #{@ref}: #{$!.message}"
78
+ end
79
+ end
80
+ end
81
+ end
@@ -128,11 +128,11 @@ module POI
128
128
  return nil if cell_value.nil?
129
129
 
130
130
  case cell_value.cell_type
131
- when CELL_TYPE_BLANK: nil
132
- when CELL_TYPE_BOOLEAN: cell_value.boolean_value
133
- when CELL_TYPE_ERROR: error_value_from(cell_value.error_value)
134
- when CELL_TYPE_NUMERIC: numeric_value_from(cell_value)
135
- when CELL_TYPE_STRING: cell_value.string_value
131
+ when CELL_TYPE_BLANK then nil
132
+ when CELL_TYPE_BOOLEAN then cell_value.boolean_value
133
+ when CELL_TYPE_ERROR then error_value_from(cell_value.error_value)
134
+ when CELL_TYPE_NUMERIC then numeric_value_from(cell_value)
135
+ when CELL_TYPE_STRING then cell_value.string_value
136
136
  else
137
137
  raise "unhandled cell type[#{cell_value.cell_type}]"
138
138
  end
@@ -142,11 +142,11 @@ module POI
142
142
  return nil if cell_type.nil?
143
143
  begin
144
144
  case cell_type
145
- when CELL_TYPE_BLANK: nil
146
- when CELL_TYPE_BOOLEAN: CELL_VALUE.value_of(poi_cell.boolean_cell_value)
147
- when CELL_TYPE_FORMULA: cell_value_for_type(poi_cell.cached_formula_result_type)
148
- when CELL_TYPE_STRING: CELL_VALUE.new(poi_cell.string_cell_value)
149
- when CELL_TYPE_ERROR, CELL_TYPE_NUMERIC: CELL_VALUE.new(poi_cell.numeric_cell_value)
145
+ when CELL_TYPE_BLANK then nil
146
+ when CELL_TYPE_BOOLEAN then CELL_VALUE.value_of(poi_cell.boolean_cell_value)
147
+ when CELL_TYPE_FORMULA then cell_value_for_type(poi_cell.cached_formula_result_type)
148
+ when CELL_TYPE_STRING then CELL_VALUE.new(poi_cell.string_cell_value)
149
+ when CELL_TYPE_ERROR, CELL_TYPE_NUMERIC then CELL_VALUE.new(poi_cell.numeric_cell_value)
150
150
  else
151
151
  raise "unhandled cell type[#{poi_cell.cell_type}]"
152
152
  end
@@ -31,15 +31,21 @@ module POI
31
31
  instance
32
32
  end
33
33
 
34
- def self.create(filename)
35
- self.new(filename, nil)
34
+ def self.create(filename, options={})
35
+ self.new(filename, nil, options)
36
36
  end
37
37
 
38
38
  attr_reader :filename
39
39
 
40
- def initialize(filename, io_stream)
40
+ def initialize(filename, io_stream, options={})
41
41
  @filename = filename
42
- @workbook = io_stream ? org.apache.poi.ss.usermodel.WorkbookFactory.create(io_stream) : org.apache.poi.xssf.usermodel.XSSFWorkbook.new
42
+ @workbook = if io_stream
43
+ org.apache.poi.ss.usermodel.WorkbookFactory.create(io_stream)
44
+ elsif options[:format] == :hssf
45
+ org.apache.poi.hssf.usermodel.HSSFWorkbook.new
46
+ else
47
+ org.apache.poi.xssf.usermodel.XSSFWorkbook.new
48
+ end
43
49
  end
44
50
 
45
51
  def formula_evaluator
@@ -1,370 +1,385 @@
1
- require 'spec_helper'
2
-
3
- require 'date'
4
- require 'stringio'
5
-
6
- describe POI::Workbook do
7
- it "should open a workbook and allow access to its worksheets" do
8
- name = TestDataFile.expand_path("various_samples.xlsx")
9
- book = POI::Workbook.open(name)
10
- book.worksheets.size.should == 5
11
- book.filename.should == name
12
- end
13
-
14
- it "should be able to create a Workbook from an IO object" do
15
- content = StringIO.new(open(TestDataFile.expand_path("various_samples.xlsx"), 'rb'){|f| f.read})
16
- book = POI::Workbook.open(content)
17
- book.worksheets.size.should == 5
18
- book.filename.should =~ /spreadsheet.xlsx$/
19
- end
20
-
21
- it "should be able to create a Workbook from a Java input stream" do
22
- content = java.io.FileInputStream.new(TestDataFile.expand_path("various_samples.xlsx"))
23
- book = POI::Workbook.open(content)
24
- book.worksheets.size.should == 5
25
- book.filename.should =~ /spreadsheet.xlsx$/
26
- end
27
-
28
- it "should return a column of cells by reference" do
29
- name = TestDataFile.expand_path("various_samples.xlsx")
30
- book = POI::Workbook.open(name)
31
- book["numbers!$A"].should == book['numbers'].rows.collect{|e| e[0].value}
32
- book["numbers!A"].should == book['numbers'].rows.collect{|e| e[0].value}
33
- book["numbers!C"].should == book['numbers'].rows.collect{|e| e[2].value}
34
- book["numbers!$D:$D"].should == book['numbers'].rows.collect{|e| e[3].value}
35
- book["numbers!$c:$D"].should == {"C" => book['numbers'].rows.collect{|e| e[2].value}, "D" => book['numbers'].rows.collect{|e| e[3].value}}
36
- end
37
-
38
- it "should return cells by reference" do
39
- name = TestDataFile.expand_path("various_samples.xlsx")
40
- book = POI::Workbook.open(name)
41
- book.cell("numbers!A1").value.should == 'NUM'
42
- book.cell("numbers!A2").to_s.should == '1.0'
43
- book.cell("numbers!A3").to_s.should == '2.0'
44
- book.cell("numbers!A4").to_s.should == '3.0'
45
-
46
- book.cell("numbers!A10").to_s.should == '9.0'
47
- book.cell("numbers!B10").to_s.should == '81.0'
48
- book.cell("numbers!C10").to_s.should == '729.0'
49
- book.cell("numbers!D10").to_s.should == '3.0'
50
-
51
- book.cell("text & pic!A10").value.should == 'This is an Excel XLSX workbook.'
52
- book.cell("bools & errors!B3").value.should == true
53
- book.cell("high refs!AM619").value.should == 'This is some text'
54
- book.cell("high refs!AO624").value.should == 24.0
55
- book.cell("high refs!AP631").value.should == 13.0
56
-
57
- book.cell(%Q{'text & pic'!A10}).value.should == 'This is an Excel XLSX workbook.'
58
- book.cell(%Q{'bools & errors'!B3}).value.should == true
59
- book.cell(%Q{'high refs'!AM619}).value.should == 'This is some text'
60
- book.cell(%Q{'high refs'!AO624}).value.should == 24.0
61
- book.cell(%Q{'high refs'!AP631}).value.should == 13.0
62
- end
63
-
64
- it "should handle named cell ranges" do
65
- name = TestDataFile.expand_path("various_samples.xlsx")
66
- book = POI::Workbook.open(name)
67
-
68
- book.named_ranges.length.should == 3
69
- book.named_ranges.collect{|e| e.name}.should == %w{four_times_six NAMES nums}
70
- book.named_ranges.collect{|e| e.sheet.name}.should == ['high refs', 'bools & errors', 'high refs']
71
- book.named_ranges.collect{|e| e.formula}.should == ["'high refs'!$AO$624", "'bools & errors'!$D$2:$D$11", "'high refs'!$AP$619:$AP$631"]
72
- book['four_times_six'].should == 24.0
73
- book['nums'].should == (1..13).collect{|e| e * 1.0}
74
-
75
- # NAMES is a range of empty cells
76
- book['NAMES'].should == [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil]
77
- book.cell('NAMES').each do | cell |
78
- cell.value.should be_nil
79
- cell.poi_cell.should_not be_nil
80
- cell.to_s.should be_empty
81
- end
82
- end
83
-
84
- it "should return an array of cell values by reference" do
85
- name = TestDataFile.expand_path("various_samples.xlsx")
86
- book = POI::Workbook.open(name)
87
- book['dates!A2:A16'].should == (Date.parse('2010-02-28')..Date.parse('2010-03-14')).to_a
88
- end
89
-
90
- it "should return cell values by reference" do
91
- name = TestDataFile.expand_path("various_samples.xlsx")
92
- book = POI::Workbook.open(name)
93
-
94
- book['text & pic!A10'].should == 'This is an Excel XLSX workbook.'
95
- book['bools & errors!B3'].should == true
96
- book['high refs!AM619'].should == 'This is some text'
97
- book['high refs!AO624'].should == 24.0
98
- book['high refs!AP631'].should == 13.0
99
- end
100
- end
101
-
102
- describe POI::Worksheets do
103
- it "should allow indexing worksheets by ordinal" do
104
- name = TestDataFile.expand_path("various_samples.xlsx")
105
- book = POI::Workbook.open(name)
106
-
107
- book.worksheets[0].name.should == "text & pic"
108
- book.worksheets[1].name.should == "numbers"
109
- book.worksheets[2].name.should == "dates"
110
- book.worksheets[3].name.should == "bools & errors"
111
- end
112
-
113
- it "should allow indexing worksheets by name" do
114
- name = TestDataFile.expand_path("various_samples.xlsx")
115
- book = POI::Workbook.open(name)
116
-
117
- book.worksheets["text & pic"].name.should == "text & pic"
118
- book.worksheets["numbers"].name.should == "numbers"
119
- book.worksheets["dates"].name.should == "dates"
120
- end
121
-
122
- it "should be enumerable" do
123
- name = TestDataFile.expand_path("various_samples.xlsx")
124
- book = POI::Workbook.open(name)
125
- book.worksheets.should be_kind_of Enumerable
126
-
127
- book.worksheets.each do |sheet|
128
- sheet.should be_kind_of POI::Worksheet
129
- end
130
-
131
- book.worksheets.size.should == 5
132
- book.worksheets.collect.size.should == 5
133
- end
134
-
135
- it "returns cells when passing a cell reference" do
136
- name = TestDataFile.expand_path("various_samples.xlsx")
137
- book = POI::Workbook.open(name)
138
- book['dates']['A2'].to_s.should == '2010-02-28'
139
- book['dates']['a2'].to_s.should == '2010-02-28'
140
- book['dates']['B2'].to_s.should == '2010-03-14'
141
- book['dates']['b2'].to_s.should == '2010-03-14'
142
- book['dates']['C2'].to_s.should == '2010-03-28'
143
- book['dates']['c2'].to_s.should == '2010-03-28'
144
- end
145
- end
146
-
147
- describe POI::Rows do
148
- it "should be enumerable" do
149
- name = TestDataFile.expand_path("various_samples.xlsx")
150
- book = POI::Workbook.open(name)
151
- sheet = book.worksheets["text & pic"]
152
- sheet.rows.should be_kind_of Enumerable
153
-
154
- sheet.rows.each do |row|
155
- row.should be_kind_of POI::Row
156
- end
157
-
158
- sheet.rows.size.should == 7
159
- sheet.rows.collect.size.should == 7
160
- end
161
- end
162
-
163
- describe POI::Cells do
164
- before :each do
165
- @name = TestDataFile.expand_path("various_samples.xlsx")
166
- @book = POI::Workbook.open(@name)
167
- end
168
-
169
- def book
170
- @book
171
- end
172
-
173
- def name
174
- @name
175
- end
176
-
177
- it "should be enumerable" do
178
- sheet = book.worksheets["text & pic"]
179
- rows = sheet.rows
180
- cells = rows[0].cells
181
-
182
- cells.should be_kind_of Enumerable
183
- cells.size.should == 1
184
- cells.collect.size.should == 1
185
- end
186
- end
187
-
188
- describe POI::Cell do
189
- before :each do
190
- @name = TestDataFile.expand_path("various_samples.xlsx")
191
- @book = POI::Workbook.open(@name)
192
- end
193
-
194
- def book
195
- @book
196
- end
197
-
198
- def name
199
- @name
200
- end
201
-
202
- it "should provide dates for date cells" do
203
- sheet = book.worksheets["dates"]
204
- rows = sheet.rows
205
-
206
- dates_by_column = [
207
- (Date.parse('2010-02-28')..Date.parse('2010-03-14')),
208
- (Date.parse('2010-03-14')..Date.parse('2010-03-28')),
209
- (Date.parse('2010-03-28')..Date.parse('2010-04-11'))]
210
- (0..2).each do |col|
211
- dates_by_column[col].each_with_index do |date, index|
212
- row = index + 1
213
- rows[row][col].value.should equal_at_cell(date, row, col)
214
- end
215
- end
216
- end
217
-
218
- it "should provide numbers for numeric cells" do
219
- sheet = book.worksheets["numbers"]
220
- rows = sheet.rows
221
-
222
- (1..15).each do |number|
223
- row = number
224
- rows[row][0].value.should equal_at_cell(number, row, 0)
225
- rows[row][1].value.should equal_at_cell(number ** 2, row, 1)
226
- rows[row][2].value.should equal_at_cell(number ** 3, row, 2)
227
- rows[row][3].value.should equal_at_cell(Math.sqrt(number), row, 3)
228
- end
229
-
230
- rows[9][0].to_s.should == '9.0'
231
- rows[9][1].to_s.should == '81.0'
232
- rows[9][2].to_s.should == '729.0'
233
- rows[9][3].to_s.should == '3.0'
234
- end
235
-
236
- it "should handle array access from the workbook down to cells" do
237
- book[1][9][0].to_s.should == '9.0'
238
- book[1][9][1].to_s.should == '81.0'
239
- book[1][9][2].to_s.should == '729.0'
240
- book[1][9][3].to_s.should == '3.0'
241
-
242
- book["numbers"][9][0].to_s.should == '9.0'
243
- book["numbers"][9][1].to_s.should == '81.0'
244
- book["numbers"][9][2].to_s.should == '729.0'
245
- book["numbers"][9][3].to_s.should == '3.0'
246
- end
247
-
248
- it "should provide error text for error cells" do
249
- sheet = book.worksheets["bools & errors"]
250
- rows = sheet.rows
251
-
252
- rows[6][0].value.should == 0.0 #'~CIRCULAR~REF~'
253
- rows[6][0].error_value.should be_nil
254
-
255
- rows[7][0].value.should be_nil
256
- rows[7][0].error_value.should == '#DIV/0!'
257
-
258
- rows[8][0].value.should be_nil
259
- rows[8][0].error_value.should == '#N/A'
260
-
261
- rows[9][0].value.should be_nil
262
- rows[9][0].error_value.should == '#NAME?'
263
-
264
- rows[10][0].value.should be_nil
265
- rows[10][0].error_value.should == '#NULL!'
266
-
267
- rows[11][0].value.should be_nil
268
- rows[11][0].error_value.should == '#NUM!'
269
-
270
- rows[12][0].value.should be_nil
271
- rows[12][0].error_value.should == '#REF!'
272
-
273
- rows[13][0].value.should be_nil
274
- rows[13][0].error_value.should == '#VALUE!'
275
-
276
- lambda{ rows[14][0].value }.should_not raise_error(Java::java.lang.RuntimeException)
277
-
278
- rows[6][0].to_s.should == '0.0' #'~CIRCULAR~REF~'
279
- rows[7][0].to_s.should == '' #'#DIV/0!'
280
- rows[8][0].to_s.should == '' #'#N/A'
281
- rows[9][0].to_s.should == '' #'#NAME?'
282
- rows[10][0].to_s.should == '' #'#NULL!'
283
- rows[11][0].to_s.should == '' #'#NUM!'
284
- rows[12][0].to_s.should == '' #'#REF!'
285
- rows[13][0].to_s.should == '' #'#VALUE!'
286
- rows[14][0].to_s.should == ''
287
- end
288
-
289
- it "should provide booleans for boolean cells" do
290
- sheet = book.worksheets["bools & errors"]
291
- rows = sheet.rows
292
- rows[1][0].value.should == false
293
- rows[1][0].to_s.should == 'false'
294
-
295
- rows[1][1].value.should == false
296
- rows[1][1].to_s.should == 'false'
297
-
298
- rows[2][0].value.should == true
299
- rows[2][0].to_s.should == 'true'
300
-
301
- rows[2][1].value.should == true
302
- rows[2][1].to_s.should == 'true'
303
- end
304
-
305
- it "should provide the cell value as a string" do
306
- sheet = book.worksheets["text & pic"]
307
- rows = sheet.rows
308
-
309
- rows[0][0].value.should == "This"
310
- rows[1][0].value.should == "is"
311
- rows[2][0].value.should == "an"
312
- rows[3][0].value.should == "Excel"
313
- rows[4][0].value.should == "XLSX"
314
- rows[5][0].value.should == "workbook"
315
- rows[9][0].value.should == 'This is an Excel XLSX workbook.'
316
-
317
-
318
- rows[0][0].to_s.should == "This"
319
- rows[1][0].to_s.should == "is"
320
- rows[2][0].to_s.should == "an"
321
- rows[3][0].to_s.should == "Excel"
322
- rows[4][0].to_s.should == "XLSX"
323
- rows[5][0].to_s.should == "workbook"
324
- rows[9][0].to_s.should == 'This is an Excel XLSX workbook.'
325
- end
326
-
327
- it "should provide formulas instead of string-ified values" do
328
- sheet = book.worksheets["numbers"]
329
- rows = sheet.rows
330
-
331
- (1..15).each do |number|
332
- row = number
333
- rows[row][0].to_s(false).should == "#{number}.0"
334
- rows[row][1].to_s(false).should == "A#{row + 1}*A#{row + 1}"
335
- rows[row][2].to_s(false).should == "B#{row + 1}*A#{row + 1}"
336
- rows[row][3].to_s(false).should == "SQRT(A#{row + 1})"
337
- end
338
-
339
- sheet = book.worksheets["bools & errors"]
340
- rows = sheet.rows
341
- rows[1][0].to_s(false).should == '1=2'
342
- rows[1][1].to_s(false).should == 'FALSE'
343
- rows[2][0].to_s(false).should == '1=1'
344
- rows[2][1].to_s(false).should == 'TRUE'
345
- rows[14][0].to_s(false).should == 'foobar(1)'
346
-
347
- sheet = book.worksheets["text & pic"]
348
- sheet.rows[9][0].to_s(false).should == 'CONCATENATE(A1," ", A2," ", A3," ", A4," ", A5," ", A6,".")'
349
- end
350
-
351
- it "should handle getting values out of 'non-existent' cells" do
352
- sheet = book.worksheets["bools & errors"]
353
- sheet.rows[14][2].value.should be_nil
354
- end
355
-
356
- it "should notify the workbook that I have been updated" do
357
- book['dates!A10'].to_s.should == '2010-03-08'
358
- book['dates!A16'].to_s.should == '2010-03-14'
359
- book['dates!B2'].to_s.should == '2010-03-14'
360
-
361
- cell = book.cell('dates!B2')
362
- cell.formula.should == 'A16'
363
-
364
- cell.formula = 'A10 + 1'
365
- book.cell('dates!B2').poi_cell.should === cell.poi_cell
366
- book.cell('dates!B2').formula.should == 'A10 + 1'
367
-
368
- book['dates!B2'].to_s.should == '2010-03-09'
369
- end
370
- end
1
+ require 'spec_helper'
2
+
3
+ require 'date'
4
+ require 'stringio'
5
+
6
+ describe POI::Workbook do
7
+ it "should open a workbook and allow access to its worksheets" do
8
+ name = TestDataFile.expand_path("various_samples.xlsx")
9
+ book = POI::Workbook.open(name)
10
+ book.worksheets.size.should == 5
11
+ book.filename.should == name
12
+ end
13
+
14
+ it "should be able to create a Workbook from an IO object" do
15
+ content = StringIO.new(open(TestDataFile.expand_path("various_samples.xlsx"), 'rb'){|f| f.read})
16
+ book = POI::Workbook.open(content)
17
+ book.worksheets.size.should == 5
18
+ book.filename.should =~ /spreadsheet.xlsx$/
19
+ end
20
+
21
+ it "should be able to create a Workbook from a Java input stream" do
22
+ content = java.io.FileInputStream.new(TestDataFile.expand_path("various_samples.xlsx"))
23
+ book = POI::Workbook.open(content)
24
+ book.worksheets.size.should == 5
25
+ book.filename.should =~ /spreadsheet.xlsx$/
26
+ end
27
+
28
+ it "should create an HSSFWorkbook when passed a :format => :hssf option" do
29
+ book = POI::Workbook.create('test.xls', :format => :hssf)
30
+ book.poi_workbook.should be_kind_of(org.apache.poi.hssf.usermodel.HSSFWorkbook)
31
+ end
32
+
33
+ it "should create an XSSFWorkbook when passed a :format => :xssf option" do
34
+ book = POI::Workbook.create('test.xlsx', :format => :xssf)
35
+ book.poi_workbook.should be_kind_of(org.apache.poi.xssf.usermodel.XSSFWorkbook)
36
+ end
37
+
38
+ it "should create an XSSFWorkbook by default" do
39
+ book = POI::Workbook.create('test.xlsx')
40
+ book.poi_workbook.should be_kind_of(org.apache.poi.xssf.usermodel.XSSFWorkbook)
41
+ end
42
+
43
+ it "should return a column of cells by reference" do
44
+ name = TestDataFile.expand_path("various_samples.xlsx")
45
+ book = POI::Workbook.open(name)
46
+ book["numbers!$A"].should == book['numbers'].rows.collect{|e| e[0].value}
47
+ book["numbers!A"].should == book['numbers'].rows.collect{|e| e[0].value}
48
+ book["numbers!C"].should == book['numbers'].rows.collect{|e| e[2].value}
49
+ book["numbers!$D:$D"].should == book['numbers'].rows.collect{|e| e[3].value}
50
+ book["numbers!$c:$D"].should == {"C" => book['numbers'].rows.collect{|e| e[2].value}, "D" => book['numbers'].rows.collect{|e| e[3].value}}
51
+ end
52
+
53
+ it "should return cells by reference" do
54
+ name = TestDataFile.expand_path("various_samples.xlsx")
55
+ book = POI::Workbook.open(name)
56
+ book.cell("numbers!A1").value.should == 'NUM'
57
+ book.cell("numbers!A2").to_s.should == '1.0'
58
+ book.cell("numbers!A3").to_s.should == '2.0'
59
+ book.cell("numbers!A4").to_s.should == '3.0'
60
+
61
+ book.cell("numbers!A10").to_s.should == '9.0'
62
+ book.cell("numbers!B10").to_s.should == '81.0'
63
+ book.cell("numbers!C10").to_s.should == '729.0'
64
+ book.cell("numbers!D10").to_s.should == '3.0'
65
+
66
+ book.cell("text & pic!A10").value.should == 'This is an Excel XLSX workbook.'
67
+ book.cell("bools & errors!B3").value.should == true
68
+ book.cell("high refs!AM619").value.should == 'This is some text'
69
+ book.cell("high refs!AO624").value.should == 24.0
70
+ book.cell("high refs!AP631").value.should == 13.0
71
+
72
+ book.cell(%Q{'text & pic'!A10}).value.should == 'This is an Excel XLSX workbook.'
73
+ book.cell(%Q{'bools & errors'!B3}).value.should == true
74
+ book.cell(%Q{'high refs'!AM619}).value.should == 'This is some text'
75
+ book.cell(%Q{'high refs'!AO624}).value.should == 24.0
76
+ book.cell(%Q{'high refs'!AP631}).value.should == 13.0
77
+ end
78
+
79
+ it "should handle named cell ranges" do
80
+ name = TestDataFile.expand_path("various_samples.xlsx")
81
+ book = POI::Workbook.open(name)
82
+
83
+ book.named_ranges.length.should == 3
84
+ book.named_ranges.collect{|e| e.name}.should == %w{four_times_six NAMES nums}
85
+ book.named_ranges.collect{|e| e.sheet.name}.should == ['high refs', 'bools & errors', 'high refs']
86
+ book.named_ranges.collect{|e| e.formula}.should == ["'high refs'!$AO$624", "'bools & errors'!$D$2:$D$11", "'high refs'!$AP$619:$AP$631"]
87
+ book['four_times_six'].should == 24.0
88
+ book['nums'].should == (1..13).collect{|e| e * 1.0}
89
+
90
+ # NAMES is a range of empty cells
91
+ book['NAMES'].should == [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil]
92
+ book.cell('NAMES').each do | cell |
93
+ cell.value.should be_nil
94
+ cell.poi_cell.should_not be_nil
95
+ cell.to_s.should be_empty
96
+ end
97
+ end
98
+
99
+ it "should return an array of cell values by reference" do
100
+ name = TestDataFile.expand_path("various_samples.xlsx")
101
+ book = POI::Workbook.open(name)
102
+ book['dates!A2:A16'].should == (Date.parse('2010-02-28')..Date.parse('2010-03-14')).to_a
103
+ end
104
+
105
+ it "should return cell values by reference" do
106
+ name = TestDataFile.expand_path("various_samples.xlsx")
107
+ book = POI::Workbook.open(name)
108
+
109
+ book['text & pic!A10'].should == 'This is an Excel XLSX workbook.'
110
+ book['bools & errors!B3'].should == true
111
+ book['high refs!AM619'].should == 'This is some text'
112
+ book['high refs!AO624'].should == 24.0
113
+ book['high refs!AP631'].should == 13.0
114
+ end
115
+ end
116
+
117
+ describe POI::Worksheets do
118
+ it "should allow indexing worksheets by ordinal" do
119
+ name = TestDataFile.expand_path("various_samples.xlsx")
120
+ book = POI::Workbook.open(name)
121
+
122
+ book.worksheets[0].name.should == "text & pic"
123
+ book.worksheets[1].name.should == "numbers"
124
+ book.worksheets[2].name.should == "dates"
125
+ book.worksheets[3].name.should == "bools & errors"
126
+ end
127
+
128
+ it "should allow indexing worksheets by name" do
129
+ name = TestDataFile.expand_path("various_samples.xlsx")
130
+ book = POI::Workbook.open(name)
131
+
132
+ book.worksheets["text & pic"].name.should == "text & pic"
133
+ book.worksheets["numbers"].name.should == "numbers"
134
+ book.worksheets["dates"].name.should == "dates"
135
+ end
136
+
137
+ it "should be enumerable" do
138
+ name = TestDataFile.expand_path("various_samples.xlsx")
139
+ book = POI::Workbook.open(name)
140
+ book.worksheets.should be_kind_of Enumerable
141
+
142
+ book.worksheets.each do |sheet|
143
+ sheet.should be_kind_of POI::Worksheet
144
+ end
145
+
146
+ book.worksheets.count.should == 5
147
+ book.worksheets.collect.count.should == 5
148
+ end
149
+
150
+ it "returns cells when passing a cell reference" do
151
+ name = TestDataFile.expand_path("various_samples.xlsx")
152
+ book = POI::Workbook.open(name)
153
+ book['dates']['A2'].to_s.should == '2010-02-28'
154
+ book['dates']['a2'].to_s.should == '2010-02-28'
155
+ book['dates']['B2'].to_s.should == '2010-03-14'
156
+ book['dates']['b2'].to_s.should == '2010-03-14'
157
+ book['dates']['C2'].to_s.should == '2010-03-28'
158
+ book['dates']['c2'].to_s.should == '2010-03-28'
159
+ end
160
+ end
161
+
162
+ describe POI::Rows do
163
+ it "should be enumerable" do
164
+ name = TestDataFile.expand_path("various_samples.xlsx")
165
+ book = POI::Workbook.open(name)
166
+ sheet = book.worksheets["text & pic"]
167
+ sheet.rows.should be_kind_of Enumerable
168
+
169
+ sheet.rows.each do |row|
170
+ row.should be_kind_of POI::Row
171
+ end
172
+
173
+ sheet.rows.count.should == 7
174
+ sheet.rows.collect.count.should == 7
175
+ end
176
+ end
177
+
178
+ describe POI::Cells do
179
+ before :each do
180
+ @name = TestDataFile.expand_path("various_samples.xlsx")
181
+ @book = POI::Workbook.open(@name)
182
+ end
183
+
184
+ def book
185
+ @book
186
+ end
187
+
188
+ def name
189
+ @name
190
+ end
191
+
192
+ it "should be enumerable" do
193
+ sheet = book.worksheets["text & pic"]
194
+ rows = sheet.rows
195
+ cells = rows[0].cells
196
+
197
+ cells.should be_kind_of Enumerable
198
+ cells.count.should == 1
199
+ cells.collect.count.should == 1
200
+ end
201
+ end
202
+
203
+ describe POI::Cell do
204
+ before :each do
205
+ @name = TestDataFile.expand_path("various_samples.xlsx")
206
+ @book = POI::Workbook.open(@name)
207
+ end
208
+
209
+ def book
210
+ @book
211
+ end
212
+
213
+ def name
214
+ @name
215
+ end
216
+
217
+ it "should provide dates for date cells" do
218
+ sheet = book.worksheets["dates"]
219
+ rows = sheet.rows
220
+
221
+ dates_by_column = [
222
+ (Date.parse('2010-02-28')..Date.parse('2010-03-14')),
223
+ (Date.parse('2010-03-14')..Date.parse('2010-03-28')),
224
+ (Date.parse('2010-03-28')..Date.parse('2010-04-11'))]
225
+ (0..2).each do |col|
226
+ dates_by_column[col].each_with_index do |date, index|
227
+ row = index + 1
228
+ rows[row][col].value.should equal_at_cell(date, row, col)
229
+ end
230
+ end
231
+ end
232
+
233
+ it "should provide numbers for numeric cells" do
234
+ sheet = book.worksheets["numbers"]
235
+ rows = sheet.rows
236
+
237
+ (1..15).each do |number|
238
+ row = number
239
+ rows[row][0].value.should equal_at_cell(number, row, 0)
240
+ rows[row][1].value.should equal_at_cell(number ** 2, row, 1)
241
+ rows[row][2].value.should equal_at_cell(number ** 3, row, 2)
242
+ rows[row][3].value.should equal_at_cell(Math.sqrt(number), row, 3)
243
+ end
244
+
245
+ rows[9][0].to_s.should == '9.0'
246
+ rows[9][1].to_s.should == '81.0'
247
+ rows[9][2].to_s.should == '729.0'
248
+ rows[9][3].to_s.should == '3.0'
249
+ end
250
+
251
+ it "should handle array access from the workbook down to cells" do
252
+ book[1][9][0].to_s.should == '9.0'
253
+ book[1][9][1].to_s.should == '81.0'
254
+ book[1][9][2].to_s.should == '729.0'
255
+ book[1][9][3].to_s.should == '3.0'
256
+
257
+ book["numbers"][9][0].to_s.should == '9.0'
258
+ book["numbers"][9][1].to_s.should == '81.0'
259
+ book["numbers"][9][2].to_s.should == '729.0'
260
+ book["numbers"][9][3].to_s.should == '3.0'
261
+ end
262
+
263
+ it "should provide error text for error cells" do
264
+ sheet = book.worksheets["bools & errors"]
265
+ rows = sheet.rows
266
+
267
+ rows[6][0].value.should == 0.0 #'~CIRCULAR~REF~'
268
+ rows[6][0].error_value.should be_nil
269
+
270
+ rows[7][0].value.should be_nil
271
+ rows[7][0].error_value.should == '#DIV/0!'
272
+
273
+ rows[8][0].value.should be_nil
274
+ rows[8][0].error_value.should == '#N/A'
275
+
276
+ rows[9][0].value.should be_nil
277
+ rows[9][0].error_value.should == '#NAME?'
278
+
279
+ rows[10][0].value.should be_nil
280
+ rows[10][0].error_value.should == '#NULL!'
281
+
282
+ rows[11][0].value.should be_nil
283
+ rows[11][0].error_value.should == '#NUM!'
284
+
285
+ rows[12][0].value.should be_nil
286
+ rows[12][0].error_value.should == '#REF!'
287
+
288
+ rows[13][0].value.should be_nil
289
+ rows[13][0].error_value.should == '#VALUE!'
290
+
291
+ lambda{ rows[14][0].value }.should_not raise_error(Java::java.lang.RuntimeException)
292
+
293
+ rows[6][0].to_s.should == '0.0' #'~CIRCULAR~REF~'
294
+ rows[7][0].to_s.should == '' #'#DIV/0!'
295
+ rows[8][0].to_s.should == '' #'#N/A'
296
+ rows[9][0].to_s.should == '' #'#NAME?'
297
+ rows[10][0].to_s.should == '' #'#NULL!'
298
+ rows[11][0].to_s.should == '' #'#NUM!'
299
+ rows[12][0].to_s.should == '' #'#REF!'
300
+ rows[13][0].to_s.should == '' #'#VALUE!'
301
+ rows[14][0].to_s.should == ''
302
+ end
303
+
304
+ it "should provide booleans for boolean cells" do
305
+ sheet = book.worksheets["bools & errors"]
306
+ rows = sheet.rows
307
+ rows[1][0].value.should == false
308
+ rows[1][0].to_s.should == 'false'
309
+
310
+ rows[1][1].value.should == false
311
+ rows[1][1].to_s.should == 'false'
312
+
313
+ rows[2][0].value.should == true
314
+ rows[2][0].to_s.should == 'true'
315
+
316
+ rows[2][1].value.should == true
317
+ rows[2][1].to_s.should == 'true'
318
+ end
319
+
320
+ it "should provide the cell value as a string" do
321
+ sheet = book.worksheets["text & pic"]
322
+ rows = sheet.rows
323
+
324
+ rows[0][0].value.should == "This"
325
+ rows[1][0].value.should == "is"
326
+ rows[2][0].value.should == "an"
327
+ rows[3][0].value.should == "Excel"
328
+ rows[4][0].value.should == "XLSX"
329
+ rows[5][0].value.should == "workbook"
330
+ rows[9][0].value.should == 'This is an Excel XLSX workbook.'
331
+
332
+
333
+ rows[0][0].to_s.should == "This"
334
+ rows[1][0].to_s.should == "is"
335
+ rows[2][0].to_s.should == "an"
336
+ rows[3][0].to_s.should == "Excel"
337
+ rows[4][0].to_s.should == "XLSX"
338
+ rows[5][0].to_s.should == "workbook"
339
+ rows[9][0].to_s.should == 'This is an Excel XLSX workbook.'
340
+ end
341
+
342
+ it "should provide formulas instead of string-ified values" do
343
+ sheet = book.worksheets["numbers"]
344
+ rows = sheet.rows
345
+
346
+ (1..15).each do |number|
347
+ row = number
348
+ rows[row][0].to_s(false).should == "#{number}.0"
349
+ rows[row][1].to_s(false).should == "A#{row + 1}*A#{row + 1}"
350
+ rows[row][2].to_s(false).should == "B#{row + 1}*A#{row + 1}"
351
+ rows[row][3].to_s(false).should == "SQRT(A#{row + 1})"
352
+ end
353
+
354
+ sheet = book.worksheets["bools & errors"]
355
+ rows = sheet.rows
356
+ rows[1][0].to_s(false).should == '1=2'
357
+ rows[1][1].to_s(false).should == 'FALSE'
358
+ rows[2][0].to_s(false).should == '1=1'
359
+ rows[2][1].to_s(false).should == 'TRUE'
360
+ rows[14][0].to_s(false).should == 'foobar(1)'
361
+
362
+ sheet = book.worksheets["text & pic"]
363
+ sheet.rows[9][0].to_s(false).should == 'CONCATENATE(A1," ", A2," ", A3," ", A4," ", A5," ", A6,".")'
364
+ end
365
+
366
+ it "should handle getting values out of 'non-existent' cells" do
367
+ sheet = book.worksheets["bools & errors"]
368
+ sheet.rows[14][2].value.should be_nil
369
+ end
370
+
371
+ it "should notify the workbook that I have been updated" do
372
+ book['dates!A10'].to_s.should == '2010-03-08'
373
+ book['dates!A16'].to_s.should == '2010-03-14'
374
+ book['dates!B2'].to_s.should == '2010-03-14'
375
+
376
+ cell = book.cell('dates!B2')
377
+ cell.formula.should == 'A16'
378
+
379
+ cell.formula = 'A10 + 1'
380
+ book.cell('dates!B2').poi_cell.should === cell.poi_cell
381
+ book.cell('dates!B2').formula.should == 'A10 + 1'
382
+
383
+ book['dates!B2'].to_s.should == '2010-03-09'
384
+ end
385
+ end