rubyexcel 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/rubyexcel/address.rb +88 -5
- data/lib/rubyexcel/data.rb +209 -21
- data/lib/rubyexcel/element.rb +67 -6
- data/lib/rubyexcel/excel_tools.rb +62 -3
- data/lib/rubyexcel/rubyexcel_components.rb +8 -0
- data/lib/rubyexcel/section.rb +150 -14
- data/lib/rubyexcel.rb +448 -32
- metadata +2 -2
data/lib/rubyexcel/address.rb
CHANGED
@@ -1,15 +1,40 @@
|
|
1
1
|
module RubyExcel
|
2
2
|
|
3
|
+
#
|
4
|
+
#Provides address translation methods to RubyExcel's classes
|
5
|
+
#
|
6
|
+
|
3
7
|
module Address
|
4
8
|
|
9
|
+
#
|
10
|
+
# Translates an address to a column index
|
11
|
+
#
|
12
|
+
# @param [String] address the address to translate
|
13
|
+
# @return [Fixnum] the column index
|
14
|
+
#
|
15
|
+
|
5
16
|
def address_to_col_index( address )
|
6
17
|
col_index( column_id( address ) )
|
7
18
|
end
|
8
19
|
|
20
|
+
#
|
21
|
+
# Translates an address to indices
|
22
|
+
#
|
23
|
+
# @param [String] address the address to translate
|
24
|
+
# @return [Array<Fixnum>] row index, column index
|
25
|
+
#
|
26
|
+
|
9
27
|
def address_to_indices( address )
|
10
28
|
[ row_id( address ), address_to_col_index( address ) ]
|
11
29
|
end
|
12
30
|
|
31
|
+
#
|
32
|
+
# Translates a column id to an index
|
33
|
+
#
|
34
|
+
# @param [String] letter the column id to translate
|
35
|
+
# @return [Fixnum] the corresponding index
|
36
|
+
#
|
37
|
+
|
13
38
|
def col_index( letter )
|
14
39
|
return letter if letter.is_a? Fixnum
|
15
40
|
letter !~ /[^A-Z]/ && [1,2,3].include?( letter.length ) or fail ArgumentError, "Invalid column reference: #{ letter }"
|
@@ -17,16 +42,37 @@ module RubyExcel
|
|
17
42
|
loop { return idx if a == letter; idx+=1; a.next! }
|
18
43
|
end
|
19
44
|
|
45
|
+
#
|
46
|
+
# Translates an index to a column letter
|
47
|
+
#
|
48
|
+
# @param [Fixnum] index the index to translate
|
49
|
+
# @return [String] the column letter
|
50
|
+
#
|
51
|
+
|
20
52
|
def col_letter( index )
|
21
53
|
return index if index.is_a? String
|
22
54
|
index > 0 or fail ArgumentError, 'Indexing is 1-based'
|
23
55
|
a = 'A'; ( index - 1 ).times { a.next! }; a
|
24
56
|
end
|
25
57
|
|
58
|
+
#
|
59
|
+
# Translates an address to a column id
|
60
|
+
#
|
61
|
+
# @param [String] address the address to translate
|
62
|
+
# @return [String] the column id
|
63
|
+
#
|
64
|
+
|
26
65
|
def column_id( address )
|
27
66
|
address[/[A-Z]+/]
|
28
67
|
end
|
29
68
|
|
69
|
+
#
|
70
|
+
# Expands an address to all contained addresses
|
71
|
+
#
|
72
|
+
# @param [String] address the address to translate
|
73
|
+
# @return [Array<String>] all addresses included within the given address
|
74
|
+
#
|
75
|
+
|
30
76
|
def expand( address )
|
31
77
|
return [[address]] unless address.include? ':'
|
32
78
|
address.upcase.match( /([A-Z]+)(\d+):([A-Z]+)(\d+)/i )
|
@@ -34,27 +80,64 @@ module RubyExcel
|
|
34
80
|
( start_row..end_row ).map { |r| ( start_col..end_col ).map { |c| c + r.to_s } }
|
35
81
|
end
|
36
82
|
|
83
|
+
#
|
84
|
+
# Translates indices to an address
|
85
|
+
#
|
86
|
+
# @param [Fixnum] row_idx the row index
|
87
|
+
# @param [Fixnum] column_idx the column index
|
88
|
+
# @return [String] the corresponding address
|
89
|
+
#
|
90
|
+
|
37
91
|
def indices_to_address( row_idx, column_idx )
|
38
92
|
[ row_idx, column_idx ].all? { |a| a.is_a?( Fixnum ) } or fail ArgumentError, 'Input must be Fixnum'
|
39
93
|
col_letter( column_idx ) + row_idx.to_s
|
40
94
|
end
|
41
95
|
|
96
|
+
#
|
97
|
+
# Checks whether an object is a multidimensional Array
|
98
|
+
#
|
99
|
+
# @param [Object] obj the object to test
|
100
|
+
# @return [Boolean] whether the object is a multidimensional Array
|
101
|
+
#
|
102
|
+
|
42
103
|
def multi_array?( obj )
|
43
104
|
obj.all? { |el| el.is_a?( Array ) } && obj.is_a?( Array ) rescue false
|
44
105
|
end
|
45
106
|
|
107
|
+
#
|
108
|
+
# Offsets an address by row and column
|
109
|
+
#
|
110
|
+
# @param [String] address the address to offset
|
111
|
+
# @param [Fixnum] row the number of rows to offset by
|
112
|
+
# @param [Fixnum] col the number of columns to offset by
|
113
|
+
# @return [String] the new address
|
114
|
+
#
|
115
|
+
|
46
116
|
def offset(address, row, col)
|
47
117
|
( col_letter( address_to_col_index( address ) + col ) ) + ( row_id( address ) + row ).to_s
|
48
118
|
end
|
49
119
|
|
120
|
+
#
|
121
|
+
# Translates two objects to a range address
|
122
|
+
#
|
123
|
+
# @param [String, RubyExcel::Element] obj1 the first address element
|
124
|
+
# @param [String, RubyExcel::Element] obj2 the second address element
|
125
|
+
# @return [String] the new address
|
126
|
+
#
|
127
|
+
|
50
128
|
def to_range_address( obj1, obj2 )
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
obj1.is_a?( String ) ? obj1 : obj1.address
|
55
|
-
end
|
129
|
+
addr = obj1.respond_to?( :address ) ? obj1.address : obj1.to_s
|
130
|
+
addr << ':' + ( obj2.respond_to?( :address ) ? obj2.address : obj2.to_s ) if obj2
|
131
|
+
addr
|
56
132
|
end
|
57
133
|
|
134
|
+
#
|
135
|
+
# Translates an address to a row id
|
136
|
+
#
|
137
|
+
# @param [String] address the address to translate
|
138
|
+
# @return [Fixnum] the row id
|
139
|
+
#
|
140
|
+
|
58
141
|
def row_id( address )
|
59
142
|
address[/\d+/].to_i
|
60
143
|
end
|
data/lib/rubyexcel/data.rb
CHANGED
@@ -2,12 +2,30 @@ module RubyExcel
|
|
2
2
|
|
3
3
|
require_relative 'address.rb'
|
4
4
|
|
5
|
+
#
|
6
|
+
# The class which holds a Sheet's data
|
7
|
+
#
|
8
|
+
|
5
9
|
class Data
|
6
|
-
|
10
|
+
include Address
|
11
|
+
include Enumerable
|
12
|
+
|
13
|
+
#The number of rows in the data
|
14
|
+
attr_reader :rows
|
15
|
+
|
16
|
+
#The number of columns in the data
|
17
|
+
attr_reader :cols
|
18
|
+
|
19
|
+
#The parent Sheet
|
7
20
|
attr_accessor :sheet
|
8
21
|
alias parent sheet
|
9
22
|
|
10
|
-
|
23
|
+
#
|
24
|
+
# Creates a RubyExcel::Data instance
|
25
|
+
#
|
26
|
+
# @param [RubyExcel::Sheet] sheet the parent Sheet
|
27
|
+
# @param [Array<Array>] input_data the multidimensional Array which holds the data
|
28
|
+
#
|
11
29
|
|
12
30
|
def initialize( sheet, input_data )
|
13
31
|
( input_data.kind_of?( Array ) && input_data.all? { |el| el.kind_of?( Array ) } ) or fail ArgumentError, 'Input must be Array of Arrays'
|
@@ -16,37 +34,76 @@ require_relative 'address.rb'
|
|
16
34
|
calc_dimensions
|
17
35
|
end
|
18
36
|
|
37
|
+
#
|
38
|
+
# Returns a copy of the data
|
39
|
+
#
|
40
|
+
|
19
41
|
def all
|
20
42
|
@data.dup
|
21
43
|
end
|
22
44
|
|
45
|
+
#
|
46
|
+
# Appends a multidimensional Array to the end of the data
|
47
|
+
#
|
48
|
+
# @param [Array<Array>] multi_array the multidimensional Array to add to the data
|
49
|
+
#
|
50
|
+
|
23
51
|
def append( multi_array )
|
24
52
|
@data << multi_array
|
25
53
|
calc_dimensions
|
26
54
|
end
|
27
55
|
|
56
|
+
#
|
57
|
+
# Finds a Column reference bu a header
|
58
|
+
#
|
59
|
+
# @param [String] header the header to search for
|
60
|
+
# @return [String] the Column reference
|
61
|
+
# @raise [NoMethodError] 'No header rows present'
|
62
|
+
# @raise [IndexError] header.to_s + ' is not a valid header'
|
63
|
+
#
|
64
|
+
|
28
65
|
def colref_by_header( header )
|
66
|
+
return header.idx if header.is_a?( Column )
|
29
67
|
sheet.header_rows > 0 or fail NoMethodError, 'No header rows present'
|
30
68
|
@data[ 0..sheet.header_rows-1 ].each { |r| idx = r.index( header ); return col_letter( idx+1 ) if idx }
|
31
|
-
fail IndexError,
|
69
|
+
fail IndexError, header.to_s + ' is not a valid header'
|
32
70
|
end
|
33
71
|
|
72
|
+
#
|
73
|
+
# Removes empty rows and columns from the data
|
74
|
+
#
|
75
|
+
|
34
76
|
def compact!
|
35
77
|
compact_columns!
|
36
78
|
compact_rows!
|
37
79
|
end
|
38
80
|
|
81
|
+
#
|
82
|
+
# Removes empty columns from the data
|
83
|
+
#
|
84
|
+
|
39
85
|
def compact_columns!
|
40
86
|
ensure_shape
|
41
87
|
@data = @data.transpose.delete_if { |ar| ar.all? { |el| el.to_s.empty? } || ar.empty? }.transpose
|
42
88
|
calc_dimensions
|
43
89
|
end
|
44
90
|
|
91
|
+
#
|
92
|
+
# Removes empty rows from the data
|
93
|
+
#
|
94
|
+
|
45
95
|
def compact_rows!
|
46
96
|
@data.delete_if { |ar| ar.all? { |el| el.to_s.empty? } || ar.empty? }
|
47
97
|
calc_dimensions
|
48
98
|
end
|
49
99
|
|
100
|
+
#
|
101
|
+
# Deletes the data referenced by an object
|
102
|
+
#
|
103
|
+
# @param [RubyExcel::Column, RubyExcel::Element, RubyExcel::Row] object the object to delete
|
104
|
+
# @raise [NoMethodError] object.class.to_s + ' is not supported"
|
105
|
+
#
|
106
|
+
|
50
107
|
def delete( object )
|
51
108
|
case object
|
52
109
|
when Row
|
@@ -60,41 +117,89 @@ require_relative 'address.rb'
|
|
60
117
|
@data[ indices[0]..indices[2] ].each { |r| r.slice!( indices[1], indices[3] - indices[1] + 1 ) }
|
61
118
|
@data.delete_if.with_index { |r,i| r.empty? && i.between?( indices[0], indices[2] ) }
|
62
119
|
else
|
63
|
-
fail NoMethodError,
|
120
|
+
fail NoMethodError, object.class.to_s + ' is not supported'
|
64
121
|
end
|
65
122
|
calc_dimensions
|
66
123
|
end
|
67
124
|
|
125
|
+
#
|
126
|
+
# Deletes the data referenced by a column id
|
127
|
+
#
|
128
|
+
|
68
129
|
def delete_column( ref )
|
69
130
|
delete( Column.new( sheet, ref ) )
|
70
131
|
calc_dimensions
|
71
132
|
end
|
72
133
|
|
134
|
+
#
|
135
|
+
# Deletes the data referenced by a row id
|
136
|
+
#
|
137
|
+
|
73
138
|
def delete_row( ref )
|
74
139
|
delete( Row.new( sheet, ref ) )
|
75
140
|
calc_dimensions
|
76
141
|
end
|
77
142
|
|
143
|
+
#
|
144
|
+
# Deletes the data referenced by an address
|
145
|
+
#
|
146
|
+
|
78
147
|
def delete_range( ref )
|
79
148
|
delete( Element.new( sheet, ref ) )
|
80
149
|
calc_dimensions
|
81
150
|
end
|
82
151
|
|
152
|
+
#
|
153
|
+
# Return a copy of self
|
154
|
+
#
|
155
|
+
# @return [RubyExcel::Data]
|
156
|
+
#
|
157
|
+
|
83
158
|
def dup
|
84
159
|
Data.new( sheet, @data.map(&:dup) )
|
85
160
|
end
|
86
161
|
|
162
|
+
#
|
163
|
+
# Check whether the data is empty
|
164
|
+
#
|
165
|
+
# @return [Boolean]
|
166
|
+
#
|
167
|
+
|
87
168
|
def empty?
|
88
169
|
no_headers.empty?
|
89
170
|
end
|
90
171
|
|
172
|
+
#
|
173
|
+
# Yields each "Row" as an Array
|
174
|
+
#
|
175
|
+
|
176
|
+
def each
|
177
|
+
@data.each { |ar| yield ar }
|
178
|
+
end
|
179
|
+
|
180
|
+
#
|
181
|
+
# Removes all Rows (omitting headers) where the block is false
|
182
|
+
#
|
183
|
+
# @param [String] header the header of the Column to pass to the block
|
184
|
+
# @yield [Object] the value at the intersection of Column and Row
|
185
|
+
# @return [self]
|
186
|
+
#
|
187
|
+
|
91
188
|
def filter!( header )
|
92
189
|
hrows = sheet.header_rows
|
93
|
-
idx =
|
190
|
+
idx = index_by_header( header )
|
94
191
|
@data = @data.select.with_index { |row, i| hrows > i || yield( row[ idx -1 ] ) }
|
95
192
|
calc_dimensions
|
193
|
+
self
|
96
194
|
end
|
97
195
|
|
196
|
+
#
|
197
|
+
# Select and re-order Columns by a list of headers
|
198
|
+
#
|
199
|
+
# @param [Array<String>] headers the ordered list of headers to keep
|
200
|
+
# @note Invalid headers will be skipped
|
201
|
+
#
|
202
|
+
|
98
203
|
def get_columns!( *headers )
|
99
204
|
headers = headers.flatten
|
100
205
|
hrow = sheet.header_rows - 1
|
@@ -104,6 +209,32 @@ require_relative 'address.rb'
|
|
104
209
|
calc_dimensions
|
105
210
|
end
|
106
211
|
|
212
|
+
#
|
213
|
+
# Return the header section of the data
|
214
|
+
#
|
215
|
+
|
216
|
+
def headers
|
217
|
+
sheet.header_rows > 0 ? @data[ 0..sheet.header_rows-1 ] : nil
|
218
|
+
end
|
219
|
+
|
220
|
+
#
|
221
|
+
# Find a Column index by header
|
222
|
+
#
|
223
|
+
# @param [String] header the Column header to search for
|
224
|
+
# @return [Fixnum] the index of the given header
|
225
|
+
#
|
226
|
+
|
227
|
+
def index_by_header( header )
|
228
|
+
col_index( sheet.header_rows > 0 ? colref_by_header( header ) : header )
|
229
|
+
end
|
230
|
+
|
231
|
+
#
|
232
|
+
# Insert blank Columns into the data
|
233
|
+
#
|
234
|
+
# @param [String, Fixnum] before the Column reference to insert before.
|
235
|
+
# @param [Fixnum] number the number of new Columns to insert
|
236
|
+
#
|
237
|
+
|
107
238
|
def insert_columns( before, number=1 )
|
108
239
|
a = Array.new( number, nil )
|
109
240
|
before = col_index( before ) - 1
|
@@ -111,45 +242,117 @@ require_relative 'address.rb'
|
|
111
242
|
calc_dimensions
|
112
243
|
end
|
113
244
|
|
245
|
+
#
|
246
|
+
# Insert blank Rows into the data
|
247
|
+
#
|
248
|
+
# @param [Fixnum] before the Row index to insert before.
|
249
|
+
# @param [Fixnum] number the number of new Rows to insert
|
250
|
+
#
|
251
|
+
|
114
252
|
def insert_rows( before, number=1 )
|
115
253
|
@data = @data.insert( ( col_index( before ) - 1 ), *Array.new( number, [nil] ) )
|
116
254
|
calc_dimensions
|
117
255
|
end
|
118
256
|
|
257
|
+
#
|
258
|
+
# Return the data without headers
|
259
|
+
#
|
260
|
+
|
119
261
|
def no_headers
|
120
262
|
@data[ sheet.header_rows..-1 ]
|
121
263
|
end
|
122
264
|
|
265
|
+
#
|
266
|
+
# Split the data into two sections by evaluating each value in a column
|
267
|
+
#
|
268
|
+
# @param [String] header the header of the Column which contains the yield value
|
269
|
+
# @yield [value] yields the value of each row under the given header
|
270
|
+
#
|
271
|
+
|
272
|
+
def partition( header, &block )
|
273
|
+
idx = index_by_header( header )
|
274
|
+
d1, d2 = no_headers.partition { |row| yield row[ idx -1 ] }
|
275
|
+
[ headers + d1, headers + d2 ] if headers
|
276
|
+
end
|
277
|
+
|
278
|
+
#
|
279
|
+
# Read a value by address
|
280
|
+
#
|
281
|
+
|
123
282
|
def read( addr )
|
124
283
|
row_idx, col_idx = address_to_indices( addr )
|
125
284
|
@data[ row_idx-1 ][ col_idx-1 ]
|
126
285
|
end
|
127
286
|
alias [] read
|
128
287
|
|
288
|
+
#
|
289
|
+
# Reverse the data Columns
|
290
|
+
#
|
291
|
+
|
129
292
|
def reverse_columns!
|
130
293
|
ensure_shape
|
131
294
|
@data = @data.transpose.reverse.transpose
|
132
295
|
end
|
296
|
+
|
297
|
+
#
|
298
|
+
# Reverse the data Rows (without affecting the headers)
|
299
|
+
#
|
133
300
|
|
134
301
|
def reverse_rows!
|
135
302
|
@data = skip_headers &:reverse
|
136
303
|
end
|
304
|
+
|
305
|
+
#
|
306
|
+
# Perform an operation on the data without affecting the headers
|
307
|
+
#
|
308
|
+
# @yield [data] yield the data without the headers
|
309
|
+
# @return [Array<Array>] returns the data with the block operation performed on it, and the headers back in place
|
310
|
+
#
|
137
311
|
|
312
|
+
def skip_headers
|
313
|
+
return to_enum(:skip_headers) unless block_given?
|
314
|
+
hr = sheet.header_rows
|
315
|
+
if hr > 0
|
316
|
+
@data[ 0..hr - 1 ] + yield( @data[ hr..-1 ] )
|
317
|
+
else
|
318
|
+
yield( @data )
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
#
|
323
|
+
# Sort the data according to the block
|
324
|
+
#
|
325
|
+
|
138
326
|
def sort!( &block )
|
139
327
|
@data = skip_headers { |d| d.sort( &block ) }; self
|
140
328
|
end
|
141
329
|
|
330
|
+
#
|
331
|
+
# Sort the data according to the block value
|
332
|
+
#
|
333
|
+
|
142
334
|
def sort_by!( &block )
|
143
335
|
@data = skip_headers { |d| d.sort_by( &block ) }
|
144
336
|
end
|
145
337
|
|
338
|
+
#
|
339
|
+
# Unique the rows according to the values within a Column, selected by header
|
340
|
+
#
|
341
|
+
|
146
342
|
def uniq!( header )
|
147
343
|
column = col_index( colref_by_header( header ) )
|
148
|
-
@data =
|
344
|
+
@data = skip_headers { |d| d.uniq { |row| row[ column - 1 ] } }
|
149
345
|
calc_dimensions
|
150
346
|
end
|
151
347
|
alias unique! uniq!
|
152
348
|
|
349
|
+
#
|
350
|
+
# Write a value into the data
|
351
|
+
#
|
352
|
+
# @param [String] addr the address to write the value to
|
353
|
+
# @param val the value to write to the address
|
354
|
+
#
|
355
|
+
|
153
356
|
def write( addr, val )
|
154
357
|
row_idx, col_idx = address_to_indices( addr )
|
155
358
|
( row_idx - rows ).times { @data << [] }
|
@@ -157,12 +360,6 @@ require_relative 'address.rb'
|
|
157
360
|
calc_dimensions
|
158
361
|
end
|
159
362
|
alias []= write
|
160
|
-
|
161
|
-
include Enumerable
|
162
|
-
|
163
|
-
def each
|
164
|
-
@data.each { |ar| yield ar }
|
165
|
-
end
|
166
363
|
|
167
364
|
private
|
168
365
|
|
@@ -175,15 +372,6 @@ require_relative 'address.rb'
|
|
175
372
|
@data = @data.map { |ar| ar.length == cols ? ar : ar + Array.new( cols - ar.length, nil) }
|
176
373
|
end
|
177
374
|
|
178
|
-
def skip_headers
|
179
|
-
hr = sheet.header_rows
|
180
|
-
if hr > 0
|
181
|
-
block_given? ? @data[ 0..hr - 1 ] + yield( @data[ hr..-1 ] ) : @data[ hr..-1 ]
|
182
|
-
else
|
183
|
-
block_given? ? yield( @data ) : @data
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
375
|
end
|
188
376
|
|
189
377
|
end
|
data/lib/rubyexcel/element.rb
CHANGED
@@ -1,10 +1,32 @@
|
|
1
1
|
module RubyExcel
|
2
2
|
|
3
3
|
class Element
|
4
|
+
include Address
|
5
|
+
include Enumerable
|
4
6
|
|
5
|
-
|
7
|
+
#The parent Sheet
|
8
|
+
attr_reader :sheet
|
6
9
|
alias parent sheet
|
7
|
-
|
10
|
+
|
11
|
+
#The address
|
12
|
+
attr_reader :address
|
13
|
+
|
14
|
+
#The Data underlying the Sheet
|
15
|
+
attr_reader :data
|
16
|
+
|
17
|
+
#The first Column id in the address
|
18
|
+
attr_reader :column
|
19
|
+
|
20
|
+
#The first Row id in the address
|
21
|
+
attr_reader :row
|
22
|
+
|
23
|
+
#
|
24
|
+
# Creates a RubyExcel::Element instance
|
25
|
+
#
|
26
|
+
# @param [RubyExcel::Sheet] sheet the parent Sheet
|
27
|
+
# @param [String] addr the address to reference
|
28
|
+
#
|
29
|
+
|
8
30
|
def initialize( sheet, addr )
|
9
31
|
fail ArgumentError, "Invalid range: #{ addr }" unless addr =~ /\A[A-Z]+\d+:[A-Z]+\d+\z|\A[A-Z]+\d+\z/
|
10
32
|
@sheet = sheet
|
@@ -13,17 +35,31 @@ module RubyExcel
|
|
13
35
|
@column = column_id( addr )
|
14
36
|
@row = row_id( addr )
|
15
37
|
end
|
38
|
+
|
39
|
+
#
|
40
|
+
# Delete the data referenced by self.address
|
41
|
+
#
|
16
42
|
|
17
43
|
def delete
|
18
44
|
data.delete( self )
|
19
45
|
end
|
20
|
-
|
21
|
-
|
46
|
+
|
47
|
+
#
|
48
|
+
# Return the value at this Element's address
|
49
|
+
#
|
50
|
+
# @return [Object, Array<Object>] the Object or Array of Objects within the data, referenced by the address
|
51
|
+
#
|
22
52
|
|
23
53
|
def value
|
24
54
|
address.include?( ':' ) ? expand( address ).map { |ar| ar.map { |addr| data[ addr ] } } : data[ address ]
|
25
55
|
end
|
26
56
|
|
57
|
+
#
|
58
|
+
# Set the value at this Element's address
|
59
|
+
#
|
60
|
+
# @param [Object, Array<Object>] val the Object or Array of Objects to write into the data
|
61
|
+
#
|
62
|
+
|
27
63
|
def value=( val )
|
28
64
|
if address.include? ':'
|
29
65
|
if multi_array?( val )
|
@@ -36,30 +72,55 @@ module RubyExcel
|
|
36
72
|
end
|
37
73
|
self
|
38
74
|
end
|
75
|
+
|
76
|
+
#
|
77
|
+
# The data at address as a TSV String
|
78
|
+
#
|
39
79
|
|
40
80
|
def to_s
|
41
81
|
value.is_a?( Array ) ? value.map { |ar| ar.join "\t" }.join($/) : value.to_s
|
42
82
|
end
|
43
83
|
|
84
|
+
#
|
85
|
+
# View the object for debugging
|
86
|
+
#
|
87
|
+
|
44
88
|
def inspect
|
45
|
-
"#{ self.class }:0x#{ '%x' % (object_id << 1) }: #{ address }"
|
89
|
+
"#{ self.class }:0x#{ '%x' % ( object_id << 1 ) }: #{ address }"
|
46
90
|
end
|
47
91
|
|
48
|
-
|
92
|
+
#
|
93
|
+
# Yields each value in the data referenced by the address
|
94
|
+
#
|
49
95
|
|
50
96
|
def each
|
97
|
+
return to_enum( :each ) unless block_given?
|
51
98
|
expand( address ).flatten.each { |addr| yield data[ addr ] }
|
52
99
|
end
|
53
100
|
|
101
|
+
#
|
102
|
+
# Yields each Element referenced by the address
|
103
|
+
#
|
104
|
+
|
54
105
|
def each_cell
|
106
|
+
return to_enum( :each_cell ) unless block_given?
|
55
107
|
expand( address ).flatten.each { |addr| yield Element.new( sheet, addr ) }
|
56
108
|
end
|
57
109
|
|
110
|
+
#
|
111
|
+
# Checks whether the data referenced by the address is empty
|
112
|
+
#
|
113
|
+
|
58
114
|
def empty?
|
59
115
|
all? { |v| v.to_s.empty? }
|
60
116
|
end
|
61
117
|
|
118
|
+
#
|
119
|
+
# Replaces each value with the result of the block
|
120
|
+
#
|
121
|
+
|
62
122
|
def map!
|
123
|
+
return to_enum( :map! ) unless block_given?
|
63
124
|
expand( address ).flatten.each { |addr| data[ addr ] = yield data[ addr ] }
|
64
125
|
end
|
65
126
|
|