nurettin-jruby-poi 0.8.2

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.
Files changed (45) hide show
  1. data/.travis.yml +2 -0
  2. data/Gemfile +9 -0
  3. data/Gemfile.lock +29 -0
  4. data/LICENSE +507 -0
  5. data/NOTICE +21 -0
  6. data/README.markdown +87 -0
  7. data/Rakefile +35 -0
  8. data/VERSION +1 -0
  9. data/bin/autospec +16 -0
  10. data/bin/htmldiff +16 -0
  11. data/bin/ldiff +16 -0
  12. data/bin/rdebug +16 -0
  13. data/bin/rspec +16 -0
  14. data/jruby-poi.gemspec +90 -0
  15. data/lib/ooxml-lib/dom4j-1.6.1.jar +0 -0
  16. data/lib/ooxml-lib/geronimo-stax-api_1.0_spec-1.0.jar +0 -0
  17. data/lib/ooxml-lib/xmlbeans-2.3.0.jar +0 -0
  18. data/lib/poi/workbook/area.rb +81 -0
  19. data/lib/poi/workbook/cell.rb +175 -0
  20. data/lib/poi/workbook/named_range.rb +30 -0
  21. data/lib/poi/workbook/row.rb +58 -0
  22. data/lib/poi/workbook/workbook.rb +262 -0
  23. data/lib/poi/workbook/worksheet.rb +78 -0
  24. data/lib/poi/workbook.rb +41 -0
  25. data/lib/poi-3.7-20101029.jar +0 -0
  26. data/lib/poi-examples-3.7-20101029.jar +0 -0
  27. data/lib/poi-ooxml-3.7-20101029.jar +0 -0
  28. data/lib/poi-ooxml-schemas-3.7-20101029.jar +0 -0
  29. data/lib/poi-scratchpad-3.7-20101029.jar +0 -0
  30. data/lib/poi.rb +15 -0
  31. data/spec/data/simple_with_picture.ods +0 -0
  32. data/spec/data/simple_with_picture.xls +0 -0
  33. data/spec/data/spreadsheet.ods +0 -0
  34. data/spec/data/timesheet.xlsx +0 -0
  35. data/spec/data/various_samples.xlsx +0 -0
  36. data/spec/facade_spec.rb +48 -0
  37. data/spec/io_spec.rb +69 -0
  38. data/spec/spec_helper.rb +16 -0
  39. data/spec/support/java/jrubypoi/MockOutputStream.java +24 -0
  40. data/spec/support/java/support.jar +0 -0
  41. data/spec/support/matchers/cell_matcher.rb +17 -0
  42. data/spec/workbook_spec.rb +370 -0
  43. data/spec/writing_spec.rb +146 -0
  44. data/spec_debug.sh +32 -0
  45. metadata +135 -0
data/Rakefile ADDED
@@ -0,0 +1,35 @@
1
+ require 'rubygems'
2
+
3
+ require 'bundler'
4
+ begin
5
+ Bundler.setup(:default, :development)
6
+ rescue Bundler::BundlerError => e
7
+ $stderr.puts e.message
8
+ $stderr.puts "Run `bundle install` to install missing gems"
9
+ exit e.status_code
10
+ end
11
+
12
+ require 'rake'
13
+ require 'jeweler'
14
+ require 'rspec/core'
15
+ require 'rspec/core/rake_task'
16
+
17
+ # gemify
18
+ Jeweler::Tasks.new do |gemspec|
19
+ gemspec.name = "jruby-poi"
20
+ gemspec.summary = "Apache POI class library for jruby"
21
+ gemspec.description = "A rubyesque library for manipulating spreadsheets and other document types for jruby, using Apache POI."
22
+ gemspec.license = "Apache"
23
+ gemspec.email = ["sdeming@makefile.com", "jacaetevha@gmail.com"]
24
+ gemspec.homepage = "http://github.com/kameeoze/jruby-poi"
25
+ gemspec.authors = ["Scott Deming", "Jason Rogers"]
26
+ end
27
+ Jeweler::RubygemsDotOrgTasks.new
28
+
29
+ # test
30
+ RSpec::Core::RakeTask.new(:spec)
31
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
32
+ spec.rcov = true
33
+ end
34
+
35
+ task :default => :spec
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.8.2
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 ADDED
@@ -0,0 +1,90 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{nurettin-jruby-poi}
8
+ s.version = "0.8.2"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Scott Deming", "Jason Rogers", "Nurettin Onur TUĞCU"]
12
+ s.date = %q{2012-04-19}
13
+ s.description = %q{A rubyesque library for manipulating spreadsheets and other document types for jruby, using Apache POI.}
14
+ s.email = ["sdeming@makefile.com", "jacaetevha@gmail.com", "onur.tugcu@gmail.com"]
15
+ s.executables = ["autospec", "htmldiff", "ldiff", "rdebug", "rspec"]
16
+ s.extra_rdoc_files = [
17
+ "LICENSE",
18
+ "README.markdown"
19
+ ]
20
+ s.files = [
21
+ ".travis.yml",
22
+ "Gemfile",
23
+ "Gemfile.lock",
24
+ "LICENSE",
25
+ "NOTICE",
26
+ "README.markdown",
27
+ "Rakefile",
28
+ "VERSION",
29
+ "bin/autospec",
30
+ "bin/htmldiff",
31
+ "bin/ldiff",
32
+ "bin/rdebug",
33
+ "bin/rspec",
34
+ "jruby-poi.gemspec",
35
+ "lib/ooxml-lib/dom4j-1.6.1.jar",
36
+ "lib/ooxml-lib/geronimo-stax-api_1.0_spec-1.0.jar",
37
+ "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",
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/data/simple_with_picture.ods",
52
+ "spec/data/simple_with_picture.xls",
53
+ "spec/data/spreadsheet.ods",
54
+ "spec/data/timesheet.xlsx",
55
+ "spec/data/various_samples.xlsx",
56
+ "spec/facade_spec.rb",
57
+ "spec/io_spec.rb",
58
+ "spec/spec_helper.rb",
59
+ "spec/support/java/jrubypoi/MockOutputStream.java",
60
+ "spec/support/java/support.jar",
61
+ "spec/support/matchers/cell_matcher.rb",
62
+ "spec/workbook_spec.rb",
63
+ "spec/writing_spec.rb",
64
+ "spec_debug.sh"
65
+ ]
66
+ s.homepage = %q{http://github.com/nurettin/jruby-poi}
67
+ s.licenses = ["Apache"]
68
+ s.require_paths = ["lib"]
69
+ s.rubygems_version = %q{1.5.1}
70
+ s.summary = %q{Apache POI class library for jruby}
71
+
72
+ if s.respond_to? :specification_version then
73
+ s.specification_version = 3
74
+
75
+ 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"])
79
+ 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"])
83
+ end
84
+ 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"])
88
+ end
89
+ end
90
+
Binary file
Binary file
@@ -0,0 +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
@@ -0,0 +1,175 @@
1
+ module POI
2
+ class Cells
3
+ include Enumerable
4
+
5
+ def initialize(row)
6
+ @row = row
7
+ @poi_row = row.poi_row
8
+ @cells = {}
9
+ end
10
+
11
+ def [](index)
12
+ @cells[index] ||= Cell.new(@poi_row.cell(index) || @poi_row.create_cell(index), @row)
13
+ end
14
+
15
+ def size
16
+ @poi_row.physical_number_of_cells
17
+ end
18
+
19
+ def each
20
+ it = @poi_row.cell_iterator
21
+ yield Cell.new(it.next, @row) while it.has_next
22
+ end
23
+ end
24
+
25
+ class Cell < Facade(:poi_cell, org.apache.poi.ss.usermodel.Cell)
26
+ DATE_UTIL = Java::org.apache.poi.ss.usermodel.DateUtil
27
+ CELL = Java::org.apache.poi.ss.usermodel.Cell
28
+ CELL_VALUE = Java::org.apache.poi.ss.usermodel.CellValue
29
+ CELL_TYPE_BLANK = CELL::CELL_TYPE_BLANK
30
+ CELL_TYPE_BOOLEAN = CELL::CELL_TYPE_BOOLEAN
31
+ CELL_TYPE_ERROR = CELL::CELL_TYPE_ERROR
32
+ CELL_TYPE_FORMULA = CELL::CELL_TYPE_FORMULA
33
+ CELL_TYPE_NUMERIC = CELL::CELL_TYPE_NUMERIC
34
+ CELL_TYPE_STRING = CELL::CELL_TYPE_STRING
35
+
36
+ def initialize(cell, row)
37
+ @cell = cell
38
+ @row = row
39
+ end
40
+
41
+ def <=> other
42
+ return 1 if other.nil?
43
+ return self.index <=> other.index
44
+ end
45
+
46
+ # This is NOT an inexpensive operation. The purpose of this method is merely to get more information
47
+ # out of cell when one thinks the value returned is incorrect. It may have more value in development
48
+ # than in production.
49
+ def error_value
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))
57
+ else
58
+ nil
59
+ end
60
+ end
61
+
62
+ # returns the formula for this Cell if it has one, otherwise nil
63
+ def formula_value
64
+ poi_cell.cell_type == CELL_TYPE_FORMULA ? poi_cell.cell_formula : nil
65
+ end
66
+
67
+ def value
68
+ return nil if poi_cell.nil?
69
+ value_of(cell_value_for_type(poi_cell.cell_type))
70
+ end
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
+
92
+ def comment
93
+ poi_cell.cell_comment
94
+ end
95
+
96
+ def index
97
+ poi_cell.column_index
98
+ end
99
+
100
+ # Get the String representation of this Cell's value.
101
+ #
102
+ # If this Cell is a formula you can pass a false to this method and
103
+ # get the formula instead of the String representation.
104
+ def to_s(evaluate_formulas=true)
105
+ return '' if poi_cell.nil?
106
+
107
+ if poi_cell.cell_type == CELL_TYPE_FORMULA && evaluate_formulas == false
108
+ formula_value
109
+ else
110
+ value.to_s
111
+ end
112
+ end
113
+
114
+ # returns the underlying org.apache.poi.ss.usermodel.Cell
115
+ def poi_cell
116
+ @cell
117
+ end
118
+
119
+ # :cell_style= comes from the Façade superclass
120
+ alias :style= :cell_style=
121
+
122
+ def style! options
123
+ self.style = @row.worksheet.workbook.create_style(options)
124
+ end
125
+
126
+ private
127
+ def value_of(cell_value)
128
+ return nil if cell_value.nil?
129
+
130
+ case cell_value.cell_type
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
+ else
137
+ raise "unhandled cell type[#{cell_value.cell_type}]"
138
+ end
139
+ end
140
+
141
+ def cell_value_for_type(cell_type)
142
+ return nil if cell_type.nil?
143
+ begin
144
+ case cell_type
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
+ else
151
+ raise "unhandled cell type[#{poi_cell.cell_type}]"
152
+ end
153
+ rescue
154
+ nil
155
+ end
156
+ end
157
+
158
+ def error_value_from(cell_value)
159
+ org.apache.poi.ss.usermodel.ErrorConstants.text(cell_value)
160
+ end
161
+
162
+ def formula_evaluator_for(workbook)
163
+ workbook.creation_helper.create_formula_evaluator
164
+ end
165
+
166
+ def numeric_value_from(cell_value)
167
+ if DATE_UTIL.cell_date_formatted(poi_cell)
168
+ Date.parse(DATE_UTIL.get_java_date(cell_value.number_value).to_s)
169
+ else
170
+ cell_value.number_value
171
+ end
172
+ end
173
+ end
174
+ end
175
+
@@ -0,0 +1,30 @@
1
+ module POI
2
+ class NamedRange
3
+
4
+ # takes an instance of org.apache.poi.ss.usermodel.Name, and a POI::Workbook
5
+ def initialize name, workbook
6
+ @name = name
7
+ @workbook = workbook
8
+ end
9
+
10
+ def name
11
+ @name.name_name
12
+ end
13
+
14
+ def sheet
15
+ @workbook.worksheets[@name.sheet_name]
16
+ end
17
+
18
+ def formula
19
+ @name.refers_to_formula
20
+ end
21
+
22
+ def cells
23
+ @name.is_deleted ? [] : [@workbook.cell(formula)].flatten
24
+ end
25
+
26
+ def values
27
+ cells.collect{|c| c.value}
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,58 @@
1
+ module POI
2
+ class Rows
3
+ include Enumerable
4
+
5
+ def initialize(worksheet)
6
+ @worksheet = worksheet
7
+ @poi_worksheet = worksheet.poi_worksheet
8
+ @rows = {}
9
+ end
10
+
11
+ def [](index)
12
+ @rows[index] ||= Row.new(@poi_worksheet.row(index) || @poi_worksheet.create_row(index), @worksheet)
13
+ end
14
+
15
+ def size
16
+ @poi_worksheet.physical_number_of_rows
17
+ end
18
+
19
+ def each
20
+ it = @poi_worksheet.row_iterator
21
+ yield Row.new(it.next, @worksheet) while it.has_next
22
+ end
23
+ end
24
+
25
+ class Row < Facade(:poi_row, org.apache.poi.ss.usermodel.Row)
26
+ def initialize(row, worksheet)
27
+ @row = row
28
+ @worksheet = worksheet
29
+ end
30
+
31
+ def [](index)
32
+ return nil if poi_row.nil?
33
+ cells[index]
34
+ end
35
+
36
+ def cells
37
+ @cells ||= Cells.new(self)
38
+ end
39
+
40
+ def index
41
+ return nil if poi_row.nil?
42
+ poi_row.row_num
43
+ end
44
+
45
+ # def height_in_points= num
46
+ # set_height_in_points num.to_f
47
+ # end
48
+
49
+ def poi_row
50
+ @row
51
+ end
52
+
53
+ def worksheet
54
+ @worksheet
55
+ end
56
+ end
57
+ end
58
+