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.
- 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
|