jruby-poi 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown CHANGED
@@ -1,13 +1,53 @@
1
1
  jruby-poi
2
2
  =========
3
3
 
4
- This little gem provides an alternative interface to the Apache POI java library, for jruby.
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.
5
5
 
6
- INSTALL:
7
- ========
6
+ INSTALL
7
+ =======
8
8
 
9
9
  * gem install jruby-poi
10
10
 
11
+ USAGE
12
+ =====
13
+ It's pretty simple really, create a POI::Workbook and access its sheets, rows, and cells. You can read from the spreadsheet, save it (as the filename with which you created or as a new spreadsheet via Workbook#save_as).
14
+
15
+ require 'poi'
16
+
17
+ # given an Excel spreadsheet whose first sheet (Sheet 1) has this data:
18
+ # A B C D E
19
+ # 1 4 A 2010-01-04
20
+ # 2 3 B =DATE(YEAR($E$1), MONTH($E$1), A2)
21
+ # 3 2 C =DATE(YEAR($E$1), MONTH($E$1), A3)
22
+ # 4 1 D =DATE(YEAR($E$1), MONTH($E$1), A4)
23
+ workbook = POI::Workbook.open('spreadsheet.xlsx')
24
+ sheet = workbook.worksheets["Sheet 1"]
25
+ rows = sheet.rows
26
+
27
+ # get a cell's value -- returns the value as its proper type, evaluating formulas if need be
28
+ rows[0][0].value # => 4.0
29
+ rows[0][1].value # => nil
30
+ rows[0][2].value # => 'A'
31
+ rows[0][3].value # => nil
32
+ rows[0][4].value # => 2010-01-04 as a Date instance
33
+ rows[1][4].value # => 2010-01-03 as a Date instance
34
+ rows[2][4].value # => 2010-01-02 as a Date instance
35
+ rows[3][4].value # => 2010-01-01 as a Date instance
36
+
37
+ # you can access a cell in array style as well... these snippets are all equivalent
38
+ workbook.sheets[0][2][2] # => 'C'
39
+ workbook[0][2][2] # => 'C'
40
+ workbook.sheets['Sheet 1'][2][2] # => 'C'
41
+ workbook['Sheet 1'][2][2] # => 'C'
42
+
43
+ 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
+
45
+ TODO
46
+ ====
47
+ * fix reading ODS files -- we have a broken spec for this in io_spec.rb
48
+ * add APIs for updating cells in a spreadsheet
49
+ * create API for non-spreadsheet files
50
+
11
51
  Contributors
12
52
  ============
13
53
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.0
1
+ 0.5.0
data/jruby-poi.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{jruby-poi}
8
- s.version = "0.4.0"
8
+ s.version = "0.5.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"]
12
- s.date = %q{2010-08-27}
12
+ s.date = %q{2010-08-30}
13
13
  s.description = %q{A rubyesque library for manipulating spreadsheets and other document types for jruby, using Apache POI.}
14
14
  s.email = %q{sdeming@makefile.com}
15
15
  s.extra_rdoc_files = [
@@ -42,9 +42,12 @@ Gem::Specification.new do |s|
42
42
  "spec_debug.sh",
43
43
  "specs/data/simple_with_picture.ods",
44
44
  "specs/data/simple_with_picture.xls",
45
+ "specs/data/spreadsheet.ods",
45
46
  "specs/data/various_samples.xlsx",
46
47
  "specs/io_spec.rb",
47
48
  "specs/spec_helper.rb",
49
+ "specs/support/java/jrubypoi/MockOutputStream.java",
50
+ "specs/support/java/support.jar",
48
51
  "specs/support/matchers/cell_matcher.rb",
49
52
  "specs/workbook_spec.rb"
50
53
  ]
@@ -36,6 +36,7 @@ module POI
36
36
  end
37
37
 
38
38
  def value
39
+ return nil if @cell.nil?
39
40
  value_of(cell_value_for_type(@cell.getCellType))
40
41
  end
41
42
 
@@ -61,6 +62,8 @@ module POI
61
62
 
62
63
  private
63
64
  def value_of(cell_value)
65
+ return nil if cell_value.nil?
66
+
64
67
  case cell_value.getCellType
65
68
  when CELL_TYPE_BLANK: nil
66
69
  when CELL_TYPE_BOOLEAN: cell_value.getBooleanValue
@@ -7,7 +7,7 @@ module POI
7
7
  name, stream = if filename_or_stream.kind_of?(java.io.InputStream)
8
8
  [File.join(Dir.tmpdir, "spreadsheet.xlsx"), filename_or_stream]
9
9
  elsif filename_or_stream.kind_of?(IO) || StringIO === filename_or_stream || filename_or_stream.respond_to?(:read)
10
- # NOTE: the String.unpack here can be very inefficient
10
+ # NOTE: the String.unpack here can be very inefficient on large files
11
11
  [File.join(Dir.tmpdir, "spreadsheet.xlsx"), java.io.ByteArrayInputStream.new(filename_or_stream.read.unpack('c*').to_java(:byte))]
12
12
  else
13
13
  raise Exception, "FileNotFound" unless File.exists?( filename_or_stream )
@@ -33,7 +33,16 @@ module POI
33
33
  end
34
34
 
35
35
  def save_as(filename)
36
- @workbook.write(java.io.FileOutputStream.new(filename))
36
+ output = output_stream filename
37
+ begin
38
+ @workbook.write(output)
39
+ ensure
40
+ output.close
41
+ end
42
+ end
43
+
44
+ def output_stream name
45
+ java.io.FileOutputStream.new(name)
37
46
  end
38
47
 
39
48
  def close
@@ -44,6 +53,10 @@ module POI
44
53
  Worksheets.new(self)
45
54
  end
46
55
 
56
+ def [](sheet_index)
57
+ worksheets[sheet_index]
58
+ end
59
+
47
60
  def poi_workbook
48
61
  @workbook
49
62
  end
@@ -38,6 +38,10 @@ module POI
38
38
  def rows
39
39
  Rows.new(self)
40
40
  end
41
+
42
+ def [](row_index)
43
+ rows[row_index]
44
+ end
41
45
 
42
46
  def poi_worksheet
43
47
  @worksheet
Binary file
data/specs/io_spec.rb CHANGED
@@ -1,8 +1,28 @@
1
1
  require File.join(File.dirname(__FILE__), 'spec_helper')
2
2
 
3
3
  describe POI::Workbook do
4
+ before :each do
5
+ @mock_output_stream = nil
6
+ class POI::Workbook
7
+ def mock_output_stream name
8
+ @mock_output_stream ||= Java::jrubypoi.MockOutputStream.new name
9
+ @mock_output_stream
10
+ end
11
+
12
+ alias_method :original_output_stream, :output_stream unless method_defined?(:original_output_stream)
13
+ alias_method :output_stream, :mock_output_stream
14
+ end
15
+ end
16
+
17
+ after :each do
18
+ @mock_output_stream = nil
19
+ class POI::Workbook
20
+ alias_method :output_stream, :original_output_stream
21
+ end
22
+ end
23
+
4
24
  it "should read an xlsx file" do
5
- name = TestDataFile.expand_path("simple_with_picture.xlsx")
25
+ name = TestDataFile.expand_path("various_samples.xlsx")
6
26
  book = nil
7
27
  lambda { book = POI::Workbook.open(name) }.should_not raise_exception
8
28
  book.should be_kind_of POI::Workbook
@@ -16,35 +36,34 @@ describe POI::Workbook do
16
36
  end
17
37
 
18
38
  it "should read an ods file" do
19
- pending "get a valid, non excel produced ods file" do
20
- name = TestDataFile.expand_path("simple_with_picture.ods")
21
- book = nil
22
- lambda { book = POI::Workbook.open(name) }.should_not raise_exception
23
- book.should be_kind_of POI::Workbook
24
- end
39
+ name = TestDataFile.expand_path("spreadsheet.ods")
40
+ book = nil
41
+ lambda { book = POI::Workbook.open(name) }.should_not raise_exception
42
+ book.should be_kind_of POI::Workbook
25
43
  end
26
44
 
27
45
  it "should write an open workbook" do
28
- name = TestDataFile.expand_path("simple_with_picture.xlsx")
46
+ name = TestDataFile.expand_path("various_samples.xlsx")
29
47
  POI::Workbook.open(name) do |book|
30
48
  lambda { book.save }.should_not raise_exception
49
+ verify_mock_output_stream book.instance_variable_get("@mock_output_stream"), name
31
50
  end
32
51
  end
33
52
 
34
53
  it "should write an open workbook to a new file" do
35
- pending "write to a temp directory to avoid git polution" do
36
- name = TestDataFile.expand_path("simple_with_picture.xlsx")
37
- new_name = TestDataFile.expand_path("saved-as.xlsx")
54
+ name = TestDataFile.expand_path("various_samples.xlsx")
55
+ new_name = TestDataFile.expand_path("saved-as.xlsx")
38
56
 
39
- POI::Workbook.open(name) do |book|
40
- lambda { book.save_as(new_name) }.should_not raise_exception
41
- end
42
-
43
- book = nil
44
- lambda { book = POI::Workbook.open(new_name) }.should_not raise_exception
45
- book.should be_kind_of POI::Workbook
46
-
47
- File.exists?(new_name).should == true
57
+ POI::Workbook.open(name) do |book|
58
+ @mock_output_stream.should be_nil
59
+ lambda { book.save_as(new_name) }.should_not raise_exception
60
+ verify_mock_output_stream book.instance_variable_get("@mock_output_stream"), new_name
48
61
  end
49
62
  end
63
+
64
+ def verify_mock_output_stream mock_output_stream, name
65
+ mock_output_stream.should_not be_nil
66
+ name.should == mock_output_stream.name
67
+ true.should == mock_output_stream.write_called
68
+ end
50
69
  end
data/specs/spec_helper.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'poi'))
2
2
  Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each {|f| require f}
3
+ require File.join(File.dirname(__FILE__), "support", "java", "support.jar")
3
4
 
4
5
  class TestDataFile
5
6
  def self.expand_path(name)
@@ -0,0 +1,24 @@
1
+ package jrubypoi;
2
+ import java.io.*;
3
+
4
+ public class MockOutputStream extends OutputStream {
5
+ public String name;
6
+ public boolean write_called;
7
+
8
+ public MockOutputStream(String name) {
9
+ this.name = name;
10
+ this.write_called = false;
11
+ }
12
+
13
+ public void write(int b) throws IOException {
14
+ this.write_called = true;
15
+ }
16
+
17
+ public void write(byte[] b) throws IOException {
18
+ this.write_called = true;
19
+ }
20
+
21
+ public void write(byte[] b, int offset, int length) throws IOException {
22
+ this.write_called = true;
23
+ }
24
+ }
Binary file
@@ -133,6 +133,19 @@ describe POI::Cells do
133
133
  rows[9][3].to_s.should == '3.0'
134
134
  end
135
135
 
136
+
137
+ it "should handle array access from the workbook down to cells" do
138
+ book[1][9][0].to_s.should == '9.0'
139
+ book[1][9][1].to_s.should == '81.0'
140
+ book[1][9][2].to_s.should == '729.0'
141
+ book[1][9][3].to_s.should == '3.0'
142
+
143
+ book["numbers"][9][0].to_s.should == '9.0'
144
+ book["numbers"][9][1].to_s.should == '81.0'
145
+ book["numbers"][9][2].to_s.should == '729.0'
146
+ book["numbers"][9][3].to_s.should == '3.0'
147
+ end
148
+
136
149
  it "should provide error text for error cells" do
137
150
  sheet = book.worksheets["bools & errors"]
138
151
  rows = sheet.rows
@@ -219,5 +232,11 @@ describe POI::Cells do
219
232
  sheet = book.worksheets["text & pic"]
220
233
  sheet.rows[9][0].to_s(false).should == 'CONCATENATE(A1," ", A2," ", A3," ", A4," ", A5," ", A6,".")'
221
234
  end
235
+
236
+ it "should handle getting values out of 'non-existent' cells" do
237
+ sheet = book.worksheets["bools & errors"]
238
+ sheet.rows[14][2].value.should be_nil
239
+ end
240
+
222
241
  end
223
242
 
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 4
7
+ - 5
8
8
  - 0
9
- version: 0.4.0
9
+ version: 0.5.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Scott Deming
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-08-27 00:00:00 -04:00
17
+ date: 2010-08-30 00:00:00 -04:00
18
18
  default_executable:
19
19
  dependencies: []
20
20
 
@@ -53,9 +53,12 @@ files:
53
53
  - spec_debug.sh
54
54
  - specs/data/simple_with_picture.ods
55
55
  - specs/data/simple_with_picture.xls
56
+ - specs/data/spreadsheet.ods
56
57
  - specs/data/various_samples.xlsx
57
58
  - specs/io_spec.rb
58
59
  - specs/spec_helper.rb
60
+ - specs/support/java/jrubypoi/MockOutputStream.java
61
+ - specs/support/java/support.jar
59
62
  - specs/support/matchers/cell_matcher.rb
60
63
  - specs/workbook_spec.rb
61
64
  has_rdoc: true