nurettin-jruby-poi 0.8.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +2 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +29 -0
- data/LICENSE +507 -0
- data/NOTICE +21 -0
- data/README.markdown +87 -0
- data/Rakefile +35 -0
- data/VERSION +1 -0
- 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 +90 -0
- data/lib/ooxml-lib/dom4j-1.6.1.jar +0 -0
- data/lib/ooxml-lib/geronimo-stax-api_1.0_spec-1.0.jar +0 -0
- data/lib/ooxml-lib/xmlbeans-2.3.0.jar +0 -0
- data/lib/poi/workbook/area.rb +81 -0
- data/lib/poi/workbook/cell.rb +175 -0
- data/lib/poi/workbook/named_range.rb +30 -0
- data/lib/poi/workbook/row.rb +58 -0
- data/lib/poi/workbook/workbook.rb +262 -0
- data/lib/poi/workbook/worksheet.rb +78 -0
- data/lib/poi/workbook.rb +41 -0
- data/lib/poi-3.7-20101029.jar +0 -0
- data/lib/poi-examples-3.7-20101029.jar +0 -0
- data/lib/poi-ooxml-3.7-20101029.jar +0 -0
- data/lib/poi-ooxml-schemas-3.7-20101029.jar +0 -0
- data/lib/poi-scratchpad-3.7-20101029.jar +0 -0
- data/lib/poi.rb +15 -0
- data/spec/data/simple_with_picture.ods +0 -0
- data/spec/data/simple_with_picture.xls +0 -0
- data/spec/data/spreadsheet.ods +0 -0
- data/spec/data/timesheet.xlsx +0 -0
- data/spec/data/various_samples.xlsx +0 -0
- data/spec/facade_spec.rb +48 -0
- data/spec/io_spec.rb +69 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/support/java/jrubypoi/MockOutputStream.java +24 -0
- data/spec/support/java/support.jar +0 -0
- data/spec/support/matchers/cell_matcher.rb +17 -0
- data/spec/workbook_spec.rb +370 -0
- data/spec/writing_spec.rb +146 -0
- data/spec_debug.sh +32 -0
- metadata +135 -0
@@ -0,0 +1,262 @@
|
|
1
|
+
require 'tmpdir'
|
2
|
+
require 'stringio'
|
3
|
+
require 'java'
|
4
|
+
|
5
|
+
module POI
|
6
|
+
class Workbook < Facade(:poi_workbook, org.apache.poi.ss.usermodel.Workbook)
|
7
|
+
FONT = org.apache.poi.ss.usermodel.Font
|
8
|
+
FONT_CONSTANTS = Hash[*FONT.constants.map{|e| [e.downcase.to_sym, FONT.const_get(e)]}.flatten]
|
9
|
+
|
10
|
+
CELL_STYLE = org.apache.poi.ss.usermodel.CellStyle
|
11
|
+
CELL_STYLE_CONSTANTS = Hash[*CELL_STYLE.constants.map{|e| [e.downcase.to_sym, CELL_STYLE.const_get(e)]}.flatten]
|
12
|
+
|
13
|
+
INDEXED_COLORS = org.apache.poi.ss.usermodel.IndexedColors
|
14
|
+
INDEXED_COLORS_CONSTANTS = Hash[*INDEXED_COLORS.constants.map{|e| [e.downcase.to_sym, INDEXED_COLORS.const_get(e)]}.flatten]
|
15
|
+
|
16
|
+
def self.open(filename_or_stream)
|
17
|
+
name, stream = if filename_or_stream.kind_of?(java.io.InputStream)
|
18
|
+
[File.join(Dir.tmpdir, "spreadsheet.xlsx"), filename_or_stream]
|
19
|
+
elsif filename_or_stream.kind_of?(IO) || StringIO === filename_or_stream || filename_or_stream.respond_to?(:read)
|
20
|
+
# NOTE: the String.unpack here can be very inefficient on large files
|
21
|
+
[File.join(Dir.tmpdir, "spreadsheet.xlsx"), java.io.ByteArrayInputStream.new(filename_or_stream.read.unpack('c*').to_java(:byte))]
|
22
|
+
else
|
23
|
+
raise Exception, "FileNotFound" unless File.exists?( filename_or_stream )
|
24
|
+
[filename_or_stream, java.io.FileInputStream.new(filename_or_stream)]
|
25
|
+
end
|
26
|
+
instance = self.new(name, stream)
|
27
|
+
if block_given?
|
28
|
+
result = yield instance
|
29
|
+
return result
|
30
|
+
end
|
31
|
+
instance
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.create(filename)
|
35
|
+
self.new(filename, nil)
|
36
|
+
end
|
37
|
+
|
38
|
+
attr_reader :filename
|
39
|
+
|
40
|
+
def initialize(filename, io_stream)
|
41
|
+
@filename = filename
|
42
|
+
@workbook = io_stream ? org.apache.poi.ss.usermodel.WorkbookFactory.create(io_stream) : org.apache.poi.xssf.usermodel.XSSFWorkbook.new
|
43
|
+
end
|
44
|
+
|
45
|
+
def formula_evaluator
|
46
|
+
@formula_evaluator ||= @workbook.creation_helper.create_formula_evaluator
|
47
|
+
end
|
48
|
+
|
49
|
+
def save
|
50
|
+
save_as(@filename)
|
51
|
+
end
|
52
|
+
|
53
|
+
def save_as(filename)
|
54
|
+
output = output_stream filename
|
55
|
+
begin
|
56
|
+
@workbook.write(output)
|
57
|
+
ensure
|
58
|
+
output.close
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def output_stream name
|
63
|
+
java.io.FileOutputStream.new(name)
|
64
|
+
end
|
65
|
+
|
66
|
+
def close
|
67
|
+
#noop
|
68
|
+
end
|
69
|
+
|
70
|
+
def create_sheet name='New Sheet'
|
71
|
+
# @workbook.createSheet name
|
72
|
+
worksheets[name]
|
73
|
+
end
|
74
|
+
|
75
|
+
def create_style options={}
|
76
|
+
font = @workbook.createFont
|
77
|
+
set_value( font, :font_height_in_points, options ) do | value |
|
78
|
+
value.to_i
|
79
|
+
end
|
80
|
+
set_value font, :bold_weight, options, FONT_CONSTANTS
|
81
|
+
set_value font, :color, options, INDEXED_COLORS_CONSTANTS do | value |
|
82
|
+
value.index
|
83
|
+
end
|
84
|
+
|
85
|
+
style = @workbook.createCellStyle
|
86
|
+
[:alignment, :vertical_alignment, :fill_pattern, :border_right, :border_left, :border_top, :border_bottom].each do | sym |
|
87
|
+
set_value style, sym, options, CELL_STYLE_CONSTANTS do | value |
|
88
|
+
value.to_i
|
89
|
+
end
|
90
|
+
end
|
91
|
+
[:right_border_color, :left_border_color, :top_border_color, :bottom_border_color, :fill_foreground_color, :fill_background_color].each do | sym |
|
92
|
+
set_value( style, sym, options, INDEXED_COLORS_CONSTANTS ) do | value |
|
93
|
+
value.index
|
94
|
+
end
|
95
|
+
end
|
96
|
+
[:hidden, :locked, :wrap_text].each do | sym |
|
97
|
+
set_value style, sym, options
|
98
|
+
end
|
99
|
+
[:rotation, :indentation].each do | sym |
|
100
|
+
set_value( style, sym, options ) do | value |
|
101
|
+
value.to_i
|
102
|
+
end
|
103
|
+
end
|
104
|
+
set_value( style, :data_format, options ) do |value|
|
105
|
+
@workbook.create_data_format.getFormat(value)
|
106
|
+
end
|
107
|
+
style.font = font
|
108
|
+
style
|
109
|
+
end
|
110
|
+
|
111
|
+
def set_value on, value_sym, from, using=nil
|
112
|
+
return on unless from.has_key?(value_sym)
|
113
|
+
value = if using
|
114
|
+
using[from[value_sym]]
|
115
|
+
else
|
116
|
+
from[value_sym]
|
117
|
+
end
|
118
|
+
value = yield value if block_given?
|
119
|
+
on.send("set_#{value_sym}", value)
|
120
|
+
on
|
121
|
+
end
|
122
|
+
|
123
|
+
def worksheets
|
124
|
+
@worksheets ||= Worksheets.new(self)
|
125
|
+
end
|
126
|
+
|
127
|
+
def named_ranges
|
128
|
+
@named_ranges ||= (0...@workbook.number_of_names).collect do | idx |
|
129
|
+
NamedRange.new @workbook.name_at(idx), self
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# reference can be a Fixnum, referring to the 0-based sheet or
|
134
|
+
# a String which is the sheet name or a cell reference.
|
135
|
+
#
|
136
|
+
# If a cell reference is passed the value of that cell is returned.
|
137
|
+
#
|
138
|
+
# If the reference refers to a contiguous range of cells an Array of values will be returned.
|
139
|
+
#
|
140
|
+
# If the reference refers to a multiple columns a Hash of values will be returned by column name.
|
141
|
+
def [](reference)
|
142
|
+
if Fixnum === reference
|
143
|
+
return worksheets[reference]
|
144
|
+
end
|
145
|
+
|
146
|
+
if sheet = worksheets.detect{|e| e.name == reference}
|
147
|
+
return sheet.poi_worksheet.nil? ? nil : sheet
|
148
|
+
end
|
149
|
+
|
150
|
+
cell = cell(reference)
|
151
|
+
if Array === cell
|
152
|
+
cell.collect{|e| e.value}
|
153
|
+
elsif Hash === cell
|
154
|
+
values = {}
|
155
|
+
cell.each_pair{|column_name, cells| values[column_name] = cells.collect{|e| e.value}}
|
156
|
+
values
|
157
|
+
else
|
158
|
+
cell.value
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
# takes a String in the form of a 3D cell reference and returns the Cell (eg. "Sheet 1!A1")
|
163
|
+
#
|
164
|
+
# If the reference refers to a contiguous range of cells an array of Cells will be returned
|
165
|
+
def cell reference
|
166
|
+
# if the reference is to a named range of cells, get that range and return it
|
167
|
+
if named_range = named_ranges.detect{|e| e.name == reference}
|
168
|
+
cells = named_range.cells.compact
|
169
|
+
if cells.empty?
|
170
|
+
return nil
|
171
|
+
else
|
172
|
+
return cells.length == 1 ? cells.first : cells
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
# check if the named_range is a full column reference
|
177
|
+
if column_reference?(named_range)
|
178
|
+
return all_cells_in_column named_range.formula
|
179
|
+
end
|
180
|
+
|
181
|
+
# if the reference is to an area of cells, get all the cells in that area and return them
|
182
|
+
cells = cells_in_area(reference)
|
183
|
+
unless cells.empty?
|
184
|
+
return cells.length == 1 ? cells.first : cells
|
185
|
+
end
|
186
|
+
|
187
|
+
if column_reference?(reference)
|
188
|
+
return all_cells_in_column reference
|
189
|
+
end
|
190
|
+
|
191
|
+
ref = POI::CELL_REF.new(reference)
|
192
|
+
single_cell ref
|
193
|
+
end
|
194
|
+
|
195
|
+
# ref is a POI::CELL_REF instance
|
196
|
+
def single_cell ref
|
197
|
+
if ref.sheet_name.nil?
|
198
|
+
raise 'cell references at the workbook level must include a sheet reference (eg. Sheet1!A1)'
|
199
|
+
else
|
200
|
+
worksheets[ref.sheet_name][ref.row][ref.col]
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
def cells_in_area reference
|
205
|
+
area = Area.new(reference)
|
206
|
+
area.in(self)
|
207
|
+
end
|
208
|
+
|
209
|
+
def poi_workbook
|
210
|
+
@workbook
|
211
|
+
end
|
212
|
+
|
213
|
+
def on_update cell
|
214
|
+
#clear_all_formula_results
|
215
|
+
#formula_evaluator.notify_update_cell cell.poi_cell
|
216
|
+
end
|
217
|
+
|
218
|
+
def on_formula_update cell
|
219
|
+
#clear_all_formula_results
|
220
|
+
formula_evaluator.notify_set_formula cell.poi_cell
|
221
|
+
formula_evaluator.evaluate_formula_cell(cell.poi_cell)
|
222
|
+
end
|
223
|
+
|
224
|
+
def on_delete cell
|
225
|
+
#clear_all_formula_results
|
226
|
+
formula_evaluator.notify_delete_cell cell.poi_cell
|
227
|
+
end
|
228
|
+
|
229
|
+
def clear_all_formula_results
|
230
|
+
formula_evaluator.clear_all_cached_result_values
|
231
|
+
end
|
232
|
+
|
233
|
+
def all_cells_in_column reference
|
234
|
+
sheet_parts = reference.split('!')
|
235
|
+
area_parts = sheet_parts.last.split(':')
|
236
|
+
area_start = "#{sheet_parts.first}!#{area_parts.first}"
|
237
|
+
area_end = area_parts.last
|
238
|
+
|
239
|
+
area = org.apache.poi.ss.util.AreaReference.getWholeColumn(area_start, area_end)
|
240
|
+
full_ref = "#{area.first_cell.format_as_string}:#{area.last_cell.format_as_string}"
|
241
|
+
Area.new(full_ref).in(self)
|
242
|
+
# cell_reference = org.apache.poi.ss.util.CellReference.new( reference + "1" )
|
243
|
+
# column = cell_reference.get_col
|
244
|
+
# sheet = cell_reference.get_sheet_name
|
245
|
+
# worksheets[sheet].rows.collect{|row| row[column]}
|
246
|
+
end
|
247
|
+
|
248
|
+
private
|
249
|
+
def column_reference? named_range_or_reference
|
250
|
+
return false if named_range_or_reference.nil?
|
251
|
+
|
252
|
+
reference = named_range_or_reference
|
253
|
+
if NamedRange === named_range_or_reference
|
254
|
+
reference = named_range_or_reference.formula
|
255
|
+
end
|
256
|
+
cell_reference = reference.split('!', 2).last
|
257
|
+
beginning, ending = cell_reference.split(':')
|
258
|
+
!(beginning =~ /\d/ || (ending.nil? ? false : ending =~ /\d/))
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module POI
|
2
|
+
class Worksheets
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
def initialize(workbook)
|
6
|
+
@workbook = workbook
|
7
|
+
@poi_workbook = workbook.poi_workbook
|
8
|
+
end
|
9
|
+
|
10
|
+
def [](index_or_name)
|
11
|
+
worksheet = case
|
12
|
+
when index_or_name.kind_of?(Numeric)
|
13
|
+
@poi_workbook.sheet_at(index_or_name) || @poi_workbook.create_sheet
|
14
|
+
else
|
15
|
+
@poi_workbook.get_sheet(index_or_name) || @poi_workbook.create_sheet(index_or_name)
|
16
|
+
end
|
17
|
+
Worksheet.new(worksheet, @workbook)
|
18
|
+
end
|
19
|
+
|
20
|
+
def size
|
21
|
+
@poi_workbook.number_of_sheets
|
22
|
+
end
|
23
|
+
|
24
|
+
def each
|
25
|
+
(0...size).each { |i| yield Worksheet.new(@poi_workbook.sheet_at(i), @workbook) }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class Worksheet < Facade(:poi_worksheet, org.apache.poi.ss.usermodel.Sheet)
|
30
|
+
|
31
|
+
def initialize(worksheet, workbook)
|
32
|
+
@worksheet = worksheet
|
33
|
+
@workbook = workbook
|
34
|
+
end
|
35
|
+
|
36
|
+
def name
|
37
|
+
@worksheet.sheet_name
|
38
|
+
end
|
39
|
+
|
40
|
+
def first_row
|
41
|
+
@worksheet.first_row_num
|
42
|
+
end
|
43
|
+
|
44
|
+
def last_row
|
45
|
+
@worksheet.last_row_num
|
46
|
+
end
|
47
|
+
|
48
|
+
def rows
|
49
|
+
@rows ||= Rows.new(self)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Accepts a Fixnum or a String as the row_index
|
53
|
+
#
|
54
|
+
# row_index as Fixnum: returns the 0-based row
|
55
|
+
#
|
56
|
+
# row_index as String: assumes a cell reference within this sheet
|
57
|
+
# if the value of the reference is non-nil the value is returned,
|
58
|
+
# otherwise the referenced cell is returned
|
59
|
+
def [](row_index)
|
60
|
+
if Fixnum === row_index
|
61
|
+
rows[row_index]
|
62
|
+
else
|
63
|
+
ref = org.apache.poi.ss.util.CellReference.new(row_index)
|
64
|
+
cell = rows[ref.row][ref.col]
|
65
|
+
cell && cell.value ? cell.value : cell
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def poi_worksheet
|
70
|
+
@worksheet
|
71
|
+
end
|
72
|
+
|
73
|
+
def workbook
|
74
|
+
@workbook
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
data/lib/poi/workbook.rb
ADDED
@@ -0,0 +1,41 @@
|
|
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
|
+
|
12
|
+
if method_name =~ /^get_[a-z]/
|
13
|
+
alias_method_name = method_name.sub('get_', '')
|
14
|
+
code += "\nalias :#{alias_method_name} :#{method_name}"
|
15
|
+
if method.return_type.to_s == 'boolean'
|
16
|
+
code += "\nalias :#{alias_method_name}? :#{method_name}"
|
17
|
+
end
|
18
|
+
elsif method_name =~ /^set_[a-z]/ && method.arity == 1
|
19
|
+
alias_method_name = "#{method_name.sub('set_', '')}"
|
20
|
+
code += "\nalias :#{alias_method_name}= :#{method_name}"
|
21
|
+
if method.argument_types.first.to_s == 'boolean'
|
22
|
+
code += "\ndef #{alias_method_name}!; #{alias_method_name} = true; end"
|
23
|
+
end
|
24
|
+
elsif method.return_type.to_s == 'boolean' && method_name =~ /is_/
|
25
|
+
code += "\nalias :#{method_name.sub('is_', '')}? :#{method_name}"
|
26
|
+
elsif method.return_type.nil? && (method.argument_types.nil? || method.argument_types.empty?)
|
27
|
+
code += "\nalias :#{method_name}! :#{method_name}"
|
28
|
+
end
|
29
|
+
|
30
|
+
cls.class_eval(code, __FILE__, __LINE__)
|
31
|
+
end
|
32
|
+
cls
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
require File.join(JRUBY_POI_LIB_PATH, 'poi', 'workbook', 'area')
|
37
|
+
require File.join(JRUBY_POI_LIB_PATH, 'poi', 'workbook', 'named_range')
|
38
|
+
require File.join(JRUBY_POI_LIB_PATH, 'poi', 'workbook', 'workbook')
|
39
|
+
require File.join(JRUBY_POI_LIB_PATH, 'poi', 'workbook', 'worksheet')
|
40
|
+
require File.join(JRUBY_POI_LIB_PATH, 'poi', 'workbook', 'row')
|
41
|
+
require File.join(JRUBY_POI_LIB_PATH, 'poi', 'workbook', 'cell')
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/lib/poi.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
JRUBY_POI_LIB_PATH=File.expand_path(File.dirname(__FILE__))
|
2
|
+
|
3
|
+
# Java
|
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')
|
9
|
+
require File.join(JRUBY_POI_LIB_PATH, 'ooxml-lib', 'xmlbeans-2.3.0.jar')
|
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
|
+
|
13
|
+
|
14
|
+
# Ruby
|
15
|
+
require File.join(JRUBY_POI_LIB_PATH, 'poi', 'workbook')
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/spec/facade_spec.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "POI.Facade" do
|
4
|
+
it "should create specialized methods for boolean methods, getters, and setters" do
|
5
|
+
book = POI::Workbook.create('foo.xlsx')
|
6
|
+
sheet = book.create_sheet
|
7
|
+
sheet.respond_to?(:column_broken?).should be_true
|
8
|
+
sheet.respond_to?(:column_hidden?).should be_true
|
9
|
+
sheet.respond_to?(:display_formulas?).should be_true
|
10
|
+
sheet.respond_to?(:display_gridlines?).should be_true
|
11
|
+
sheet.respond_to?(:selected?).should be_true
|
12
|
+
sheet.respond_to?(:column_breaks).should be_true
|
13
|
+
sheet.respond_to?(:column_break=).should be_true
|
14
|
+
sheet.respond_to?(:autobreaks?).should be_true
|
15
|
+
sheet.respond_to?(:autobreaks=).should be_true
|
16
|
+
sheet.respond_to?(:autobreaks!).should be_true
|
17
|
+
sheet.respond_to?(:column_broken?).should be_true
|
18
|
+
sheet.respond_to?(:fit_to_page).should be_true
|
19
|
+
sheet.respond_to?(:fit_to_page?).should be_true
|
20
|
+
sheet.respond_to?(:fit_to_page=).should be_true
|
21
|
+
sheet.respond_to?(:fit_to_page!).should be_true
|
22
|
+
|
23
|
+
sheet.respond_to?(:array_formula).should_not be_true
|
24
|
+
sheet.respond_to?(:array_formula=).should_not be_true
|
25
|
+
|
26
|
+
row = sheet[0]
|
27
|
+
row.respond_to?(:first_cell_num).should be_true
|
28
|
+
row.respond_to?(:height).should be_true
|
29
|
+
row.respond_to?(:height=).should be_true
|
30
|
+
row.respond_to?(:height_in_points).should be_true
|
31
|
+
row.respond_to?(:height_in_points=).should be_true
|
32
|
+
row.respond_to?(:zero_height?).should be_true
|
33
|
+
row.respond_to?(:zero_height!).should be_true
|
34
|
+
row.respond_to?(:zero_height=).should be_true
|
35
|
+
|
36
|
+
cell = row[0]
|
37
|
+
cell.respond_to?(:boolean_cell_value).should be_true
|
38
|
+
cell.respond_to?(:boolean_cell_value?).should be_true
|
39
|
+
cell.respond_to?(:cached_formula_result_type).should be_true
|
40
|
+
cell.respond_to?(:cell_error_value=).should be_true
|
41
|
+
cell.respond_to?(:cell_value=).should be_true
|
42
|
+
cell.respond_to?(:hyperlink=).should be_true
|
43
|
+
cell.respond_to?(:cell_value!).should be_true
|
44
|
+
cell.respond_to?(:remove_cell_comment!).should be_true
|
45
|
+
cell.respond_to?(:cell_style).should be_true
|
46
|
+
cell.respond_to?(:cell_style=).should be_true
|
47
|
+
end
|
48
|
+
end
|
data/spec/io_spec.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
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
|
+
|
24
|
+
it "should read an xlsx file" do
|
25
|
+
name = TestDataFile.expand_path("various_samples.xlsx")
|
26
|
+
book = nil
|
27
|
+
lambda { book = POI::Workbook.open(name) }.should_not raise_exception
|
28
|
+
book.should be_kind_of POI::Workbook
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should read an xls file" do
|
32
|
+
name = TestDataFile.expand_path("simple_with_picture.xls")
|
33
|
+
book = nil
|
34
|
+
lambda { book = POI::Workbook.open(name) }.should_not raise_exception
|
35
|
+
book.should be_kind_of POI::Workbook
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should read an ods file", :unimplemented => true do
|
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
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should write an open workbook" do
|
46
|
+
name = TestDataFile.expand_path("various_samples.xlsx")
|
47
|
+
POI::Workbook.open(name) do |book|
|
48
|
+
lambda { book.save }.should_not raise_exception
|
49
|
+
verify_mock_output_stream book.instance_variable_get("@mock_output_stream"), name
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should write an open workbook to a new file" do
|
54
|
+
name = TestDataFile.expand_path("various_samples.xlsx")
|
55
|
+
new_name = TestDataFile.expand_path("saved-as.xlsx")
|
56
|
+
|
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
|
61
|
+
end
|
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
|
69
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.configure do |c|
|
4
|
+
c.filter_run_excluding :unimplemented => true
|
5
|
+
end
|
6
|
+
|
7
|
+
require File.expand_path('../lib/poi', File.dirname(__FILE__))
|
8
|
+
|
9
|
+
Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each {|f| require f}
|
10
|
+
require File.join(File.dirname(__FILE__), "support", "java", "support.jar")
|
11
|
+
|
12
|
+
class TestDataFile
|
13
|
+
def self.expand_path(name)
|
14
|
+
File.expand_path(File.join(File.dirname(__FILE__), 'data', name))
|
15
|
+
end
|
16
|
+
end
|
@@ -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
|
@@ -0,0 +1,17 @@
|
|
1
|
+
RSpec::Matchers.define :equal_at_cell do |expected, row, col|
|
2
|
+
match do |actual|
|
3
|
+
actual == expected
|
4
|
+
end
|
5
|
+
|
6
|
+
failure_message_for_should do |actual|
|
7
|
+
"expected #{actual} to equal #{expected} (row:#{row}, cell:#{col})"
|
8
|
+
end
|
9
|
+
|
10
|
+
failure_message_for_should_not do |actual|
|
11
|
+
"expected #{actual} not to equal #{expected} (row:#{row}, cell:#{col})"
|
12
|
+
end
|
13
|
+
|
14
|
+
description do
|
15
|
+
"to equal #{expected}"
|
16
|
+
end
|
17
|
+
end
|