rubyexcel 0.1.1 → 0.1.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/lib/README.md CHANGED
@@ -93,11 +93,10 @@ wb = s.parent
93
93
  ```
94
94
 
95
95
  Using the Mechanize gem to get data
96
+ --------
96
97
 
97
98
  This example is for context, there are many potential data sources
98
99
 
99
- --------
100
-
101
100
  ```ruby
102
101
  s = RubyExcel::Workbook.new.load( CSV.parse( Mechanize.new.get('http://example.com/myfile.csv').content ) )
103
102
  ```
@@ -134,8 +133,6 @@ s.column( 1 ) #=> Column
134
133
  Some Examples
135
134
  ========
136
135
 
137
- This list may be removed in favour of the gem's documentation on rubydoc.
138
-
139
136
  Common Operations
140
137
  --------
141
138
 
@@ -143,10 +140,16 @@ Common Operations
143
140
  #Append a Column by adding a header
144
141
  s << 'Numbers'
145
142
  x = 1
143
+
146
144
  #Iterate through the rest of the rows while appending data
147
145
  s.rows(2) { |row| row << x; x+=1 }
148
146
 
147
+ #
148
+
149
+ #Split the data into multiple sheets by part number
150
+ wb = s.split( 'Part' )
149
151
 
152
+ #Will add more examples here later.
150
153
 
151
154
  ```
152
155
 
@@ -273,7 +276,7 @@ s.maxcol #=> 5
273
276
  s.columns.count #=> 5
274
277
 
275
278
  #Partition the sheet into two, given a header and a block (like Filter)
276
- #Note: this keeps the headers intact in both outputs sheets
279
+ #Note: this keeps the headers intact in both output sheets
277
280
  type_1_and_3, other = s.partition( 'Part' ) { |value| value =~ /Type[13]/ }
278
281
  type_1_and_3, other = s.partition( 'Part', &/Type[13]/ )
279
282
 
@@ -285,6 +288,10 @@ s.reverse_columns!
285
288
  s.sort! { |r1,r2| r1['A'] <=> r2['A'] }
286
289
  s.sort_by! { |r| r['A'] }
287
290
 
291
+ #Split a Sheet into a Workbook of Sheets by a column (selected by header)
292
+ wb = s.split( 'Part' )
293
+ #=> <Workbook: [Sheet:Type1, Sheet:Type2, Sheet:Type3, Sheet:Type4]>
294
+
288
295
  #Sum all elements in a column by criteria in another column (selected by header)
289
296
  #Parameters: Header to pass to the block, Header to sum, Block.
290
297
  #Note: Now also accepts Column objects in place of headers.
@@ -35,6 +35,26 @@ require_relative 'address.rb'
35
35
  @data = input_data.dup
36
36
  calc_dimensions
37
37
  end
38
+
39
+ #
40
+ # Append an object to Data
41
+ #
42
+ # @param [Object] other the data to append
43
+ # @return [self]
44
+ #
45
+
46
+ def <<( other )
47
+ case other
48
+ when Array ; multi_array?( other ) ? @data += other : @data << other
49
+ when Hash ; @data += _convert_hash( other )
50
+ when Sheet ; empty? ? @data = other.data.all.dup : @data += other.data.dup.no_headers
51
+ when Row ; @data << other.to_a.dup
52
+ when Column ; @data.map!.with_index { |row, i| row << other[ i+1 ] }
53
+ else ; @data[0] << other
54
+ end
55
+ calc_dimensions
56
+ self
57
+ end
38
58
 
39
59
  # @overload advanced_filter!( header, comparison_operator, search_criteria, ... )
40
60
  # Filter on multiple criteria
@@ -239,7 +259,8 @@ require_relative 'address.rb'
239
259
  #
240
260
 
241
261
  def headers
242
- sheet.header_rows > 0 ? @data[ 0..sheet.header_rows-1 ] : nil
262
+ return nil if sheet.header_rows.nil? || sheet.header_rows.zero?
263
+ @data[ 0..sheet.header_rows-1 ]
243
264
  end
244
265
 
245
266
  #
@@ -285,6 +306,7 @@ require_relative 'address.rb'
285
306
  #
286
307
 
287
308
  def no_headers
309
+ return @data unless sheet.header_rows
288
310
  @data[ sheet.header_rows..-1 ]
289
311
  end
290
312
 
@@ -399,6 +421,14 @@ require_relative 'address.rb'
399
421
  @data = @data.map { |ar| ar.length == cols ? ar : ar + Array.new( cols - ar.length, nil) }
400
422
  end
401
423
 
424
+ def _convert_hash(h)
425
+ _hash_to_a(h).each_slice(2).map { |a1,a2| a1 << a2.last }
426
+ end
427
+
428
+ def _hash_to_a(h)
429
+ h.map { |k,v| v.is_a?(Hash) ? _hash_to_a(v).map { |val| ([ k ] + [ val ]).flatten(1) } : [ k, v ] }.flatten(1)
430
+ end
431
+
402
432
  end
403
433
 
404
434
  end
@@ -142,6 +142,15 @@ module RubyExcel
142
142
  return to_enum( :map! ) unless block_given?
143
143
  each_address { |addr| data[addr] = ( yield data[addr] ) }
144
144
  end
145
+
146
+ #
147
+ # Replaces each value with the result of the block, skipping headers
148
+ #
149
+
150
+ def map_without_headers!
151
+ return to_enum( :map_without_headers! ) unless block_given?
152
+ each_address_without_headers { |addr| data[addr] = ( yield data[addr] ) }
153
+ end
145
154
 
146
155
  #
147
156
  # Read a value by address
data/lib/rubyexcel.rb CHANGED
@@ -285,21 +285,16 @@ module RubyExcel
285
285
  end
286
286
 
287
287
  #
288
- # Append data to the Sheet
288
+ # Append an object to the Sheet
289
289
  #
290
- # @param [Array<Array>, Hash<Hash>, RubyExcel::Sheet] other the data to append
290
+ # @param [Object] other the object to append
291
291
  # @return [self]
292
292
  # @note When adding another Sheet it won't import the headers unless this Sheet is empty.
293
- # @note Anything other than an an Array, Hash, or Sheet will be appended to the first row
293
+ # @note Anything other than an an Array, Hash, Row, Column or Sheet will be appended to the first row
294
294
  #
295
295
 
296
296
  def <<( other )
297
- case other
298
- when Array ; load( data.all + other, header_rows )
299
- when Hash ; load( data.all + _convert_hash( other ), header_rows )
300
- when Sheet ; empty? ? load( other.to_a, other.header_rows ) : load( data.all + other.data.no_headers, header_rows )
301
- else ; row(1) << other
302
- end
297
+ data << other
303
298
  self
304
299
  end
305
300
 
@@ -675,16 +670,37 @@ module RubyExcel
675
670
 
676
671
  # {Sheet#sort_by!}
677
672
 
678
- def sort_by( &block )
679
- dup.sort_by!( &block )
673
+ def sort_by( header )
674
+ dup.sort_by!( header )
680
675
  end
681
676
 
682
677
  #
683
- # Sort the data by the block value (avoiding headers)
678
+ # Sort the data by a column, selected by header
679
+ #
680
+ # @param [String] header the header to sort the Sheet by
684
681
  #
685
682
 
686
- def sort_by!( &block )
687
- data.sort_by!( &block ); self
683
+ def sort_by!( header )
684
+ idx = data.index_by_header( header ) - 1
685
+ sort_method = lambda { |array| array[idx] }
686
+ data.sort_by!( &sort_method )
687
+ self
688
+ end
689
+
690
+ #
691
+ # Break the Sheet into a Workbook with multiple Sheets, split by the values under a header.
692
+ #
693
+ # @param [String] header the header to split by
694
+ # @return [RubyExcel::Workbook] a new workbook containing the split Sheets (each with headers)
695
+ #
696
+
697
+ def split( header )
698
+ wb = Workbook.new
699
+ ch( header ).each_wh.to_a.uniq.each { |name| wb.add( name ).load( data.headers ) }
700
+ rows( header_rows+1 ) do |row|
701
+ wb.sheets( row.val( header ) ) << row
702
+ end
703
+ wb
688
704
  end
689
705
 
690
706
  #
@@ -775,16 +791,6 @@ module RubyExcel
775
791
  return_col[ row_id( find_col.find( &block ) ) ] rescue nil
776
792
  end
777
793
 
778
- private
779
-
780
- def _hash_to_a(h)
781
- h.map { |k,v| v.is_a?(Hash) ? _hash_to_a(v).map { |val| ([ k ] + [ val ]).flatten(1) } : [ k, v ] }.flatten(1)
782
- end
783
-
784
- def _convert_hash(h)
785
- _hash_to_a(h).each_slice(2).map { |a1,a2| a1 << a2.last }
786
- end
787
-
788
794
  end # Sheet
789
795
 
790
796
  end # RubyExcel
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubyexcel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,9 +9,10 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-05-02 00:00:00.000000000 Z
12
+ date: 2013-05-03 00:00:00.000000000 Z
13
13
  dependencies: []
14
- description: A tabular data structure, mixing Ruby with some of Excel's API style.
14
+ description: A tabular data structure in Ruby, with header-based helper methods and
15
+ some of Excel's API style.
15
16
  email: VirtuosoJoel@gmail.com
16
17
  executables: []
17
18
  extensions: []