rubyexcel 0.0.5 → 0.0.6
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/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
|
|