jruby-poi 0.6.1 → 0.7.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +6 -0
- data/Gemfile.lock +25 -0
- data/README.markdown +16 -1
- data/Rakefile +22 -0
- data/VERSION +1 -1
- data/bin/autospec +16 -0
- data/bin/htmldiff +16 -0
- data/bin/ldiff +16 -0
- data/bin/rdebug +16 -0
- data/bin/rspec +16 -0
- data/jruby-poi.gemspec +55 -43
- data/lib/poi/workbook.rb +16 -0
- data/lib/poi/workbook/area.rb +60 -3
- data/lib/poi/workbook/cell.rb +83 -34
- data/lib/poi/workbook/named_range.rb +4 -4
- data/lib/poi/workbook/row.rb +20 -10
- data/lib/poi/workbook/workbook.rb +165 -19
- data/lib/poi/workbook/worksheet.rb +33 -15
- data/spec_debug.sh +13 -2
- data/specs/data/simple_with_picture.ods +0 -0
- data/specs/data/various_samples.xlsx +0 -0
- data/specs/spec_helper.rb +2 -1
- data/specs/support/matchers/cell_matcher.rb +1 -1
- data/specs/workbook_spec.rb +47 -10
- data/specs/writing_spec.rb +145 -0
- metadata +92 -66
- data/.gitignore +0 -9
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
columnize (0.3.2)
|
5
|
+
diff-lcs (1.1.2)
|
6
|
+
rspec (2.5.0)
|
7
|
+
rspec-core (~> 2.5.0)
|
8
|
+
rspec-expectations (~> 2.5.0)
|
9
|
+
rspec-mocks (~> 2.5.0)
|
10
|
+
rspec-core (2.5.1)
|
11
|
+
rspec-expectations (2.5.0)
|
12
|
+
diff-lcs (~> 1.1.2)
|
13
|
+
rspec-mocks (2.5.0)
|
14
|
+
ruby-debug (0.10.4)
|
15
|
+
columnize (>= 0.1)
|
16
|
+
ruby-debug-base (~> 0.10.4.0)
|
17
|
+
ruby-debug-base (0.10.4-java)
|
18
|
+
|
19
|
+
PLATFORMS
|
20
|
+
java
|
21
|
+
ruby
|
22
|
+
|
23
|
+
DEPENDENCIES
|
24
|
+
rspec
|
25
|
+
ruby-debug
|
data/README.markdown
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
[jruby-poi](http://github.com/
|
1
|
+
[jruby-poi](http://github.com/kameeoze/jruby-poi)
|
2
2
|
=========
|
3
3
|
|
4
4
|
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.
|
@@ -20,6 +20,7 @@ It's pretty simple really, create a POI::Workbook and access its sheets, rows, a
|
|
20
20
|
# 2 3 B =DATE(YEAR($E$1), MONTH($E$1), A2)
|
21
21
|
# 3 2 C =DATE(YEAR($E$1), MONTH($E$1), A3)
|
22
22
|
# 4 1 D =DATE(YEAR($E$1), MONTH($E$1), A4)
|
23
|
+
|
23
24
|
workbook = POI::Workbook.open('spreadsheet.xlsx')
|
24
25
|
sheet = workbook.worksheets["Sheet 1"]
|
25
26
|
rows = sheet.rows
|
@@ -40,6 +41,20 @@ It's pretty simple really, create a POI::Workbook and access its sheets, rows, a
|
|
40
41
|
workbook.sheets['Sheet 1'][2][2] # => 'C'
|
41
42
|
workbook['Sheet 1'][2][2] # => 'C'
|
42
43
|
|
44
|
+
# you can access a cell in 3D cell format too
|
45
|
+
workbook['Sheet 1!A1'] # => 4.0
|
46
|
+
|
47
|
+
# you can even refer to ranges of cells
|
48
|
+
workbook['Sheet 1!A1:A3'] # => [4.0, 3.0, 2.0]
|
49
|
+
|
50
|
+
# if cells E1 - E4 were a named range, you could refer to those cells by its name
|
51
|
+
# eg. if the cells were named "dates"...
|
52
|
+
workbook['dates'] # => dates from E1 - E4
|
53
|
+
|
54
|
+
# to get the Cell instance, instead of its value, just use the Workbook#cell method
|
55
|
+
workbook.cell('dates') # => cells that contain dates from E1 to E4
|
56
|
+
workbook['Sheet 1!A1:A3'] # => cells that contain 4.0, 3.0, and 2.0
|
57
|
+
|
43
58
|
There's a formatted version of this code [here](http://gist.github.com/557607), but Github doesn't allow embedding script tags in Markdown. Go figure!
|
44
59
|
|
45
60
|
TODO
|
data/Rakefile
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
begin
|
2
2
|
require 'jeweler'
|
3
|
+
|
3
4
|
Jeweler::Tasks.new do |gemspec|
|
4
5
|
gemspec.name = "jruby-poi"
|
5
6
|
gemspec.summary = "Apache POI class library for jruby"
|
@@ -12,3 +13,24 @@ rescue LoadError
|
|
12
13
|
puts "Jeweler not available. Install it with: gem install jeweler"
|
13
14
|
end
|
14
15
|
|
16
|
+
begin
|
17
|
+
require 'rspec/core/rake_task'
|
18
|
+
task :default => :spec
|
19
|
+
|
20
|
+
desc "Run all examples"
|
21
|
+
RSpec::Core::RakeTask.new do |t|
|
22
|
+
t.pattern = 'specs/**/*.rb'
|
23
|
+
t.rspec_opts = ['-c']
|
24
|
+
end
|
25
|
+
|
26
|
+
desc "Run all examples with RCov"
|
27
|
+
RSpec::Core::RakeTask.new(:coverage) do |t|
|
28
|
+
t.pattern = 'specs/**/*.rb'
|
29
|
+
t.rspec_opts = ['-c']
|
30
|
+
t.rcov = true
|
31
|
+
t.rcov_opts = ['--include', '/lib/', '--exclude', '/gems/,/^specs/,/^.eval.$/']
|
32
|
+
end
|
33
|
+
rescue
|
34
|
+
puts $!.message
|
35
|
+
puts "RCov not available. Install it with: gem install rcov (--no-rdoc --no-ri)"
|
36
|
+
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.7.1
|
data/bin/autospec
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env jruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'autospec' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('rspec-core', 'autospec')
|
data/bin/htmldiff
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env jruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'htmldiff' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('diff-lcs', 'htmldiff')
|
data/bin/ldiff
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env jruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'ldiff' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('diff-lcs', 'ldiff')
|
data/bin/rdebug
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env jruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'rdebug' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('ruby-debug', 'rdebug')
|
data/bin/rspec
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env jruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'rspec' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('rspec-core', 'rspec')
|
data/jruby-poi.gemspec
CHANGED
@@ -1,72 +1,84 @@
|
|
1
1
|
# Generated by jeweler
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{jruby-poi}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.7.1"
|
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{
|
12
|
+
s.date = %q{2011-03-27}
|
13
13
|
s.description = %q{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"]
|
15
16
|
s.extra_rdoc_files = [
|
16
17
|
"LICENSE",
|
17
|
-
|
18
|
+
"README.markdown"
|
18
19
|
]
|
19
20
|
s.files = [
|
20
|
-
"
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
21
|
+
"Gemfile",
|
22
|
+
"Gemfile.lock",
|
23
|
+
"LICENSE",
|
24
|
+
"NOTICE",
|
25
|
+
"README.markdown",
|
26
|
+
"Rakefile",
|
27
|
+
"VERSION",
|
28
|
+
"bin/autospec",
|
29
|
+
"bin/htmldiff",
|
30
|
+
"bin/ldiff",
|
31
|
+
"bin/rdebug",
|
32
|
+
"bin/rspec",
|
33
|
+
"jruby-poi.gemspec",
|
34
|
+
"lib/ooxml-lib/dom4j-1.6.1.jar",
|
35
|
+
"lib/ooxml-lib/geronimo-stax-api_1.0_spec-1.0.jar",
|
36
|
+
"lib/ooxml-lib/xmlbeans-2.3.0.jar",
|
37
|
+
"lib/poi-3.6-20091214.jar",
|
38
|
+
"lib/poi-contrib-3.6-20091214.jar",
|
39
|
+
"lib/poi-examples-3.6-20091214.jar",
|
40
|
+
"lib/poi-ooxml-3.6-20091214.jar",
|
41
|
+
"lib/poi-ooxml-schemas-3.6-20091214.jar",
|
42
|
+
"lib/poi-scratchpad-3.6-20091214.jar",
|
43
|
+
"lib/poi.rb",
|
44
|
+
"lib/poi/workbook.rb",
|
45
|
+
"lib/poi/workbook/area.rb",
|
46
|
+
"lib/poi/workbook/cell.rb",
|
47
|
+
"lib/poi/workbook/named_range.rb",
|
48
|
+
"lib/poi/workbook/row.rb",
|
49
|
+
"lib/poi/workbook/workbook.rb",
|
50
|
+
"lib/poi/workbook/worksheet.rb",
|
51
|
+
"spec_debug.sh",
|
52
|
+
"specs/data/simple_with_picture.ods",
|
53
|
+
"specs/data/simple_with_picture.xls",
|
54
|
+
"specs/data/spreadsheet.ods",
|
55
|
+
"specs/data/various_samples.xlsx",
|
56
|
+
"specs/io_spec.rb",
|
57
|
+
"specs/spec_helper.rb",
|
58
|
+
"specs/support/java/jrubypoi/MockOutputStream.java",
|
59
|
+
"specs/support/java/support.jar",
|
60
|
+
"specs/support/matchers/cell_matcher.rb",
|
61
|
+
"specs/workbook_spec.rb",
|
62
|
+
"specs/writing_spec.rb"
|
55
63
|
]
|
56
64
|
s.homepage = %q{http://github.com/sdeming/jruby-poi}
|
57
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
58
65
|
s.require_paths = ["lib"]
|
59
|
-
s.rubygems_version = %q{1.
|
66
|
+
s.rubygems_version = %q{1.6.0}
|
60
67
|
s.summary = %q{Apache POI class library for jruby}
|
61
68
|
|
62
69
|
if s.respond_to? :specification_version then
|
63
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
64
70
|
s.specification_version = 3
|
65
71
|
|
66
|
-
if Gem::Version.new(Gem::
|
72
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
73
|
+
s.add_development_dependency(%q<rspec>, [">= 0"])
|
74
|
+
s.add_development_dependency(%q<ruby-debug>, [">= 0"])
|
67
75
|
else
|
76
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
77
|
+
s.add_dependency(%q<ruby-debug>, [">= 0"])
|
68
78
|
end
|
69
79
|
else
|
80
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
81
|
+
s.add_dependency(%q<ruby-debug>, [">= 0"])
|
70
82
|
end
|
71
83
|
end
|
72
84
|
|
data/lib/poi/workbook.rb
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
module POI
|
2
|
+
AREA_REF = org.apache.poi.ss.util.AreaReference
|
3
|
+
CELL_REF = org.apache.poi.ss.util.CellReference
|
4
|
+
|
5
|
+
def self.Facade(delegate, java_class)
|
6
|
+
cls = Class.new
|
7
|
+
java_class.java_class.java_instance_methods.select{|e| e.public?}.each do | method |
|
8
|
+
args = method.arity.times.collect{|i| "arg#{i}"}.join(", ")
|
9
|
+
method_name = method.name.gsub(/([A-Z])/){|e| "_#{e.downcase}"}
|
10
|
+
code = "def #{method_name}(#{args}); #{delegate}.#{method.name}(#{args}); end"
|
11
|
+
cls.class_eval(code, __FILE__, __LINE__)
|
12
|
+
end
|
13
|
+
cls
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
1
17
|
require File.join(JRUBY_POI_LIB_PATH, 'poi', 'workbook', 'area')
|
2
18
|
require File.join(JRUBY_POI_LIB_PATH, 'poi', 'workbook', 'named_range')
|
3
19
|
require File.join(JRUBY_POI_LIB_PATH, 'poi', 'workbook', 'workbook')
|
data/lib/poi/workbook/area.rb
CHANGED
@@ -5,20 +5,77 @@ module POI
|
|
5
5
|
end
|
6
6
|
|
7
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
|
+
|
8
13
|
begin
|
9
|
-
|
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
|
10
50
|
rescue
|
11
51
|
[]
|
12
52
|
end
|
13
53
|
end
|
14
54
|
|
15
55
|
def single_cell_reference?
|
16
|
-
|
56
|
+
area.single_cell? #@ref == getFirstCell.formatAsString rescue false
|
17
57
|
end
|
18
58
|
|
19
59
|
private
|
20
60
|
def area
|
21
|
-
@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
|
22
79
|
end
|
23
80
|
end
|
24
81
|
end
|
data/lib/poi/workbook/cell.rb
CHANGED
@@ -3,25 +3,27 @@ module POI
|
|
3
3
|
include Enumerable
|
4
4
|
|
5
5
|
def initialize(row)
|
6
|
-
@row
|
6
|
+
@row = row
|
7
7
|
@poi_row = row.poi_row
|
8
|
+
@cells = {}
|
8
9
|
end
|
9
10
|
|
10
11
|
def [](index)
|
11
|
-
Cell.new(@poi_row.
|
12
|
+
@cells[index] ||= Cell.new(@poi_row.cell(index) || @poi_row.create_cell(index), @row)
|
12
13
|
end
|
13
14
|
|
14
15
|
def size
|
15
|
-
@poi_row.
|
16
|
+
@poi_row.physical_number_of_cells
|
16
17
|
end
|
17
18
|
|
18
19
|
def each
|
19
|
-
it = @poi_row.
|
20
|
-
yield Cell.new(it.next) while it.
|
20
|
+
it = @poi_row.cell_iterator
|
21
|
+
yield Cell.new(it.next, @row) while it.has_next
|
21
22
|
end
|
22
23
|
end
|
23
24
|
|
24
|
-
class Cell
|
25
|
+
class Cell < Facade(:poi_cell, org.apache.poi.ss.usermodel.Cell)
|
26
|
+
DATE_UTIL = Java::org.apache.poi.ss.usermodel.DateUtil
|
25
27
|
CELL = Java::org.apache.poi.ss.usermodel.Cell
|
26
28
|
CELL_VALUE = Java::org.apache.poi.ss.usermodel.CellValue
|
27
29
|
CELL_TYPE_BLANK = CELL::CELL_TYPE_BLANK
|
@@ -31,19 +33,27 @@ module POI
|
|
31
33
|
CELL_TYPE_NUMERIC = CELL::CELL_TYPE_NUMERIC
|
32
34
|
CELL_TYPE_STRING = CELL::CELL_TYPE_STRING
|
33
35
|
|
34
|
-
def initialize(cell)
|
36
|
+
def initialize(cell, row)
|
35
37
|
@cell = cell
|
38
|
+
@row = row
|
39
|
+
end
|
40
|
+
|
41
|
+
def <=> other
|
42
|
+
return 1 if other.nil?
|
43
|
+
return self.index <=> other.index
|
36
44
|
end
|
37
45
|
|
38
46
|
# This is NOT an inexpensive operation. The purpose of this method is merely to get more information
|
39
47
|
# out of cell when one thinks the value returned is incorrect. It may have more value in development
|
40
48
|
# than in production.
|
41
49
|
def error_value
|
42
|
-
if poi_cell.
|
43
|
-
|
44
|
-
elsif poi_cell.
|
45
|
-
|
46
|
-
|
50
|
+
if poi_cell.cell_type == CELL_TYPE_ERROR
|
51
|
+
error_value_from(poi_cell.error_cell_value)
|
52
|
+
elsif poi_cell.cell_type == CELL_TYPE_FORMULA &&
|
53
|
+
poi_cell.cached_formula_result_type == CELL_TYPE_ERROR
|
54
|
+
|
55
|
+
# breaks Law of Demeter by reaching into the Row's Worksheet, but it makes sense to do in this case
|
56
|
+
value_of(@row.worksheet.workbook.formula_evaluator.evaluate(poi_cell))
|
47
57
|
else
|
48
58
|
nil
|
49
59
|
end
|
@@ -51,20 +61,40 @@ module POI
|
|
51
61
|
|
52
62
|
# returns the formula for this Cell if it has one, otherwise nil
|
53
63
|
def formula_value
|
54
|
-
poi_cell.
|
64
|
+
poi_cell.cell_type == CELL_TYPE_FORMULA ? poi_cell.cell_formula : nil
|
55
65
|
end
|
56
66
|
|
57
67
|
def value
|
58
68
|
return nil if poi_cell.nil?
|
59
|
-
value_of(cell_value_for_type(poi_cell.
|
69
|
+
value_of(cell_value_for_type(poi_cell.cell_type))
|
60
70
|
end
|
61
|
-
|
71
|
+
|
72
|
+
def formula= new_value
|
73
|
+
poi_cell.cell_formula = new_value
|
74
|
+
@row.worksheet.workbook.on_formula_update self
|
75
|
+
self
|
76
|
+
end
|
77
|
+
|
78
|
+
def formula
|
79
|
+
poi_cell.cell_formula
|
80
|
+
end
|
81
|
+
|
82
|
+
def value= new_value
|
83
|
+
set_cell_value new_value
|
84
|
+
if new_value.nil?
|
85
|
+
@row.worksheet.workbook.on_delete self
|
86
|
+
else
|
87
|
+
@row.worksheet.workbook.on_update self
|
88
|
+
end
|
89
|
+
self
|
90
|
+
end
|
91
|
+
|
62
92
|
def comment
|
63
|
-
poi_cell.
|
93
|
+
poi_cell.cell_comment
|
64
94
|
end
|
65
95
|
|
66
96
|
def index
|
67
|
-
poi_cell.
|
97
|
+
poi_cell.column_index
|
68
98
|
end
|
69
99
|
|
70
100
|
# Get the String representation of this Cell's value.
|
@@ -74,7 +104,7 @@ module POI
|
|
74
104
|
def to_s(evaluate_formulas=true)
|
75
105
|
return '' if poi_cell.nil?
|
76
106
|
|
77
|
-
if poi_cell.
|
107
|
+
if poi_cell.cell_type == CELL_TYPE_FORMULA && evaluate_formulas == false
|
78
108
|
formula_value
|
79
109
|
else
|
80
110
|
value.to_s
|
@@ -86,23 +116,26 @@ module POI
|
|
86
116
|
@cell
|
87
117
|
end
|
88
118
|
|
119
|
+
def style= a_style
|
120
|
+
set_cell_style a_style
|
121
|
+
end
|
122
|
+
|
123
|
+
def style! options
|
124
|
+
self.style = @row.worksheet.workbook.create_style(options)
|
125
|
+
end
|
126
|
+
|
89
127
|
private
|
90
128
|
def value_of(cell_value)
|
91
129
|
return nil if cell_value.nil?
|
92
130
|
|
93
|
-
case cell_value.
|
131
|
+
case cell_value.cell_type
|
94
132
|
when CELL_TYPE_BLANK: nil
|
95
|
-
when CELL_TYPE_BOOLEAN: cell_value.
|
96
|
-
when CELL_TYPE_ERROR:
|
97
|
-
when CELL_TYPE_NUMERIC
|
98
|
-
|
99
|
-
Date.parse(Java::org.apache.poi.ss.usermodel.DateUtil.getJavaDate(cell_value.getNumberValue).to_s)
|
100
|
-
else
|
101
|
-
cell_value.getNumberValue
|
102
|
-
end
|
103
|
-
when CELL_TYPE_STRING: cell_value.getStringValue
|
133
|
+
when CELL_TYPE_BOOLEAN: cell_value.boolean_value
|
134
|
+
when CELL_TYPE_ERROR: error_value_from(cell_value.error_value)
|
135
|
+
when CELL_TYPE_NUMERIC: numeric_value_from(cell_value)
|
136
|
+
when CELL_TYPE_STRING: cell_value.string_value
|
104
137
|
else
|
105
|
-
raise "unhandled cell type[#{cell_value.
|
138
|
+
raise "unhandled cell type[#{cell_value.cell_type}]"
|
106
139
|
end
|
107
140
|
end
|
108
141
|
|
@@ -111,17 +144,33 @@ module POI
|
|
111
144
|
begin
|
112
145
|
case cell_type
|
113
146
|
when CELL_TYPE_BLANK: nil
|
114
|
-
when CELL_TYPE_BOOLEAN: CELL_VALUE.
|
115
|
-
when CELL_TYPE_FORMULA: cell_value_for_type(poi_cell.
|
116
|
-
when CELL_TYPE_STRING: CELL_VALUE.new(poi_cell.
|
117
|
-
when CELL_TYPE_ERROR, CELL_TYPE_NUMERIC: CELL_VALUE.new(poi_cell.
|
147
|
+
when CELL_TYPE_BOOLEAN: CELL_VALUE.value_of(poi_cell.boolean_cell_value)
|
148
|
+
when CELL_TYPE_FORMULA: cell_value_for_type(poi_cell.cached_formula_result_type)
|
149
|
+
when CELL_TYPE_STRING: CELL_VALUE.new(poi_cell.string_cell_value)
|
150
|
+
when CELL_TYPE_ERROR, CELL_TYPE_NUMERIC: CELL_VALUE.new(poi_cell.numeric_cell_value)
|
118
151
|
else
|
119
|
-
raise "unhandled cell type[#{poi_cell.
|
152
|
+
raise "unhandled cell type[#{poi_cell.cell_type}]"
|
120
153
|
end
|
121
154
|
rescue
|
122
155
|
nil
|
123
156
|
end
|
124
157
|
end
|
158
|
+
|
159
|
+
def error_value_from(cell_value)
|
160
|
+
org.apache.poi.ss.usermodel.ErrorConstants.text(cell_value)
|
161
|
+
end
|
162
|
+
|
163
|
+
def formula_evaluator_for(workbook)
|
164
|
+
workbook.creation_helper.create_formula_evaluator
|
165
|
+
end
|
166
|
+
|
167
|
+
def numeric_value_from(cell_value)
|
168
|
+
if DATE_UTIL.cell_date_formatted(poi_cell)
|
169
|
+
Date.parse(DATE_UTIL.get_java_date(cell_value.number_value).to_s)
|
170
|
+
else
|
171
|
+
cell_value.number_value
|
172
|
+
end
|
173
|
+
end
|
125
174
|
end
|
126
175
|
end
|
127
176
|
|