rubyexcel 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -252,7 +252,7 @@ module RubyExcel
252
252
  #
253
253
  # Find a value in this Row by its header
254
254
  #
255
- # @param [String]header the header to search for
255
+ # @param [String] header the header to search for
256
256
  # @return [Object] the value at the address
257
257
  #
258
258
 
@@ -260,6 +260,18 @@ module RubyExcel
260
260
  self[ getref( header ) ]
261
261
  end
262
262
  alias val value_by_header
263
+
264
+ #
265
+ # Set a value in this Row by its header
266
+ #
267
+ # @param [String] header the header to search for
268
+ # @param [Object] val the value to write
269
+ #
270
+
271
+ def set_value_by_header( header, val )
272
+ self[ getref( header ) ] = val
273
+ end
274
+ alias set_val set_value_by_header
263
275
 
264
276
  private
265
277
 
@@ -534,7 +534,7 @@ module RubyExcel
534
534
  #
535
535
 
536
536
  def to_html
537
- "<table>\n" + data.map { |row| '<tr>' + row.map { |v| '<td>' + CGI.escapeHTML(v.to_s) }.join() + "\n" }.join() + '</table>'
537
+ %Q|<table border=1>\n<caption>#@name</caption>\n| + data.map { |row| '<tr>' + row.map { |v| '<td>' + CGI.escapeHTML(v.to_s) }.join }.join("\n") + "\n</table>"
538
538
  end
539
539
 
540
540
  #
data/lib/rubyexcel.rb CHANGED
@@ -113,6 +113,15 @@ module RubyExcel
113
113
  wb
114
114
  end
115
115
 
116
+ #
117
+ # Yields each Sheet.
118
+ #
119
+
120
+ def each
121
+ return to_enum( :each ) unless block_given?
122
+ @sheets.each { |s| yield s }
123
+ end
124
+
116
125
  #
117
126
  # Check whether the workbook has Sheets
118
127
  #
@@ -136,14 +145,23 @@ module RubyExcel
136
145
  #
137
146
  # Select a Sheet or iterate through them
138
147
  #
139
- # @param [Fixnum, String, nil] ref the reference to select a Sheet by
148
+ # @param [Fixnum, String, Regexp, nil] ref the reference to select a Sheet by
140
149
  # @return [RubyExcel::Sheet] if a search term was given
141
150
  # @return [Enumerator] if nil or no argument given
151
+ # @yield [RubyExcel::Sheet] yields each sheet, if there is no argument and a block is given
142
152
  #
143
153
 
144
154
  def sheets( ref=nil )
145
- return to_enum (:each) if ref.nil?
146
- ref.is_a?( Fixnum ) ? @sheets[ ref - 1 ] : @sheets.find { |s| s.name =~ /^#{ ref }$/i }
155
+ if ref.nil?
156
+ return to_enum (:each) unless block_given?
157
+ each { |s| yield s }
158
+ else
159
+ case ref
160
+ when Fixnum ; @sheets[ ref - 1 ]
161
+ when String ; @sheets.find { |s| s.name =~ /^#{ ref }$/i }
162
+ when Regexp ; @sheets.find { |s| s.name =~ ref }
163
+ end
164
+ end
147
165
  end
148
166
 
149
167
  # {Workbook#sort!}
@@ -175,12 +193,11 @@ module RubyExcel
175
193
  end
176
194
 
177
195
  #
178
- # Yields each Sheet.
196
+ # The Workbook as a group of HTML Tables
179
197
  #
180
198
 
181
- def each
182
- return to_enum( :each ) unless block_given?
183
- @sheets.each { |s| yield s }
199
+ def to_html
200
+ map(&:to_html).join('</br>')
184
201
  end
185
202
 
186
203
  end # Workbook
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.4
4
+ version: 0.1.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-05-09 00:00:00.000000000 Z
12
+ date: 2013-05-10 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: A tabular data structure in Ruby, with header-based helper methods and
15
15
  some of Excel's API style. Designed for Windows + Excel.
@@ -26,7 +26,6 @@ files:
26
26
  - lib/rubyexcel/section.rb
27
27
  - lib/rubyexcel/sheet.rb
28
28
  - lib/rubyexcel.rb
29
- - lib/README.md
30
29
  homepage: https://github.com/VirtuosoJoel
31
30
  licenses: []
32
31
  post_install_message:
data/lib/README.md DELETED
@@ -1,630 +0,0 @@
1
- RubyExcel
2
- =========
3
-
4
- Designed for Ruby on Windows with MS Excel
5
-
6
- Introduction
7
- ------------
8
-
9
- A Data-analysis tool for Ruby, with an Excel-style API.
10
-
11
- You can find the gem [here](https://rubygems.org/gems/rubyexcel "Rubygems").
12
-
13
- Main documentation is [here](http://rubydoc.info/gems/rubyexcel "Rubydoc")
14
-
15
- For any requests, comments, etc. I keep an eye on [this forum](http://www.ruby-forum.com/forum/ruby "Ruby Mailing List").
16
- If you put "RubyExcel" in the subject title I should see it.
17
-
18
- Please feel free to log any bugs you find [here](https://github.com/VirtuosoJoel/RubyExcel/issues "Bug Tracker").
19
-
20
- Details
21
- -----
22
-
23
- Key design features taken from Excel:
24
-
25
- * 1-based indexing.
26
- * Referencing objects like Excel's API ( Workbook, Sheet, Row, Column, Cell, Range ).
27
- * Useful data-handling functions ( e.g. Filter, Match, Sumif, Vlookup ).
28
-
29
- Typical usage:
30
-
31
- 1. Extract a HTML Table or CSV File into 2D Array ( normally with Nokogiri / Mechanize ).
32
- 2. Organise and interpret data with RubyExcel.
33
- 3. Output results into a file.
34
-
35
- About
36
- -----
37
-
38
- This gem is designed as a way to conveniently edit table data before outputting it to Excel (XLSX) or TSV format (which Excel can interpret).
39
- It attempts to take as much as possible from Excel's API while providing some of the best bits of Ruby ( e.g. Enumerators, Blocks, Regexp ).
40
- An important feature is allowing reference to Columns via their Headers for convenience and enhanced code readability.
41
- As this works directly on the data, processing is faster than using Excel itself.
42
-
43
- This was written out of the frustration of editing tabular data using Ruby's multidimensional arrays,
44
- without affecting headers and while maintaining code readability.
45
- Its API is designed to simplify moving code across from VBA into Ruby format when processing spreadsheet data.
46
- The combination of Ruby, WIN32OLE Excel, and analysing table data is probably quite rare; but I thought I'd share what I came up with.
47
-
48
- Examples
49
- ========
50
-
51
- Expected Data Layout (2D Array)
52
- --------
53
-
54
- ```ruby
55
- data = [
56
- [ 'Part', 'Ref1', 'Ref2', 'Qty', 'Cost' ],
57
- [ 'Type1', 'QT1', '231', 1, 35.15 ],
58
- [ 'Type2', 'QT3', '123', 1, 40 ],
59
- [ 'Type3', 'XT1', '321', 3, 0.1 ],
60
- [ 'Type1', 'XY2', '132', 1, 30.00 ],
61
- [ 'Type4', 'XT3', '312', 2, 3 ],
62
- [ 'Type2', 'QY2', '213', 1, 99.99 ],
63
- [ 'Type1', 'QT4', '123', 2, 104 ]
64
- ]
65
- ```
66
- The number of header rows defaults to 1
67
-
68
- Loading the data into a Sheet
69
- --------
70
-
71
- ```ruby
72
- require 'rubyexcel'
73
-
74
- wb = RubyExcel::Workbook.new
75
- s = wb.add( 'Sheet1' )
76
- s.load( data )
77
-
78
- Or:
79
-
80
- wb = RubyExcel::Workbook.new
81
- s = wb.add( 'Sheet1' )
82
- s.load( RubyExcel.sample_data )
83
-
84
- Or:
85
-
86
- wb = RubyExcel::Workbook.new
87
- s = wb.load( RubyExcel.sample_data )
88
-
89
- Or:
90
-
91
- s = RubyExcel.sample_sheet
92
- wb = s.parent
93
- ```
94
-
95
- Using the Mechanize gem to get data
96
- --------
97
-
98
- This example is for context, there are many potential data sources
99
-
100
- ```ruby
101
- s = RubyExcel::Workbook.new.load( CSV.parse( Mechanize.new.get('http://example.com/myfile.csv').content ) )
102
- ```
103
-
104
- Reference a cell's value
105
- --------
106
-
107
- ```ruby
108
- s['A7']
109
- s.A7
110
- s.cell(7,1).value
111
- s.range('A7').value
112
- s.row(7)['A']
113
- s.row(7)[1]
114
- s.column('A')[7]
115
- s.column('A')['7']
116
- ```
117
-
118
- Reference a group of cells
119
- --------
120
-
121
- ```ruby
122
- s['A1:B3'] #=> Array
123
- s.range( 'A1:B3' ) #=> Element
124
- s.range( 'A:A' ) #=> Element (Column)
125
- s.range( '1:2' ) #=> Element (Rows)
126
- s.range( 'A1', 'B3' ) #=> Element
127
- s.range( s.cell( 1, 1 ), s.cell( 3, 2 ) ) #=> Element
128
- s.row( 1 ) #=> Row
129
- s.column( 'A' ) #=> Column
130
- s.column( 1 ) #=> Column
131
- ```
132
-
133
- Common Operations
134
- --------
135
-
136
- ```ruby
137
- #Some data to play with
138
- s = RubyExcel.sample_sheet
139
-
140
- #Have a look at the data
141
- puts s
142
-
143
- #Append a Column by adding a header
144
- s << 'Number'
145
-
146
- #Iterate through the rest of the rows while appending data
147
- x = 1
148
- s.rows(2) { |row| row << x; x+=1 }
149
-
150
- #Filter to specific part numbers
151
- s.filter!( 'Part', &/Type[1-3]/ )
152
-
153
- #Sort by Part Number
154
- s.sort_by!( 'Part' )
155
-
156
- #Add the Number to the Cost in each row.
157
- s.rows(2) { |row| row.cell_h('Cost').value += row.cell_h('Number').value }
158
-
159
- #Split the data into multiple sheets by part number
160
- wb = s.split( 'Part' )
161
-
162
- #Open a sheet in an Excel Workbook
163
- #Output a sheet as a TSV file
164
- File.write( 'Output.txt', wb.sheets(1).to_s )
165
-
166
- #Output a sheet as an HTML page
167
- File.write( 'Output.htm', wb.sheets(2).to_html )
168
-
169
- #Open a sheet in an Excel Workbook
170
- wb.sheets( 'Type3' ).to_excel
171
-
172
- ```
173
-
174
- Workbook
175
- --------
176
-
177
- ```ruby
178
- #Create a workbook
179
- wb = RubyExcel::Workbook.new
180
-
181
- #Add sheets to the workbook
182
- sheet1, sheet2 = wb.add('Sheet1'), wb.add
183
-
184
- #Delete all sheets from a workbook
185
- wb.clear_all
186
-
187
- #Delete a specific sheet
188
- wb.delete( 1 )
189
- wb.delete( 'Sheet1' )
190
- wb.delete( sheet1 )
191
- wb.delete( /sheet1/i )
192
-
193
- #Shortcut to create a sheet with a default name and fill it with data
194
- wb.load( data )
195
-
196
- #Select a sheet
197
- wb.sheets(1) #=> RubyExcel::Sheet
198
- wb.sheets('Sheet1') #=> RubyExcel::Sheet
199
-
200
- #Iterate through all sheets
201
- wb.sheets #=> Enumerator
202
- wb.each #=> Enumerator
203
-
204
- #Sort the sheets
205
- wb.sort! { |x,y| x.name <=> y.name }
206
- wb.sort_by! &:name
207
- ```
208
-
209
- Sheet
210
- --------
211
-
212
- ```ruby
213
- #Create a sheet
214
- s = wb.add #Name defaults to 'Sheet' + total number of sheets
215
- s = wb.add( 'Sheet1' )
216
-
217
- #Access the sheet name
218
- s.name #=> 'Sheet1'
219
- s.name = 'Sheet1'
220
-
221
- #Access the parent workbook
222
- s.workbook
223
- s.parent
224
-
225
- #Access the headers
226
- s.header_rows #=> 1
227
- s.headers #=> 1
228
- s.headers = 1
229
- s.header_rows = 1
230
-
231
- #Specify the number of header rows when loading data
232
- s.load( data, 1 )
233
-
234
- #Append data (at the bottom of the sheet)
235
- s << data
236
- s << s
237
- s += data
238
- s += s
239
-
240
- #Remove identical rows in another data set (skipping any headers)
241
- s -= data
242
- s -= s
243
-
244
- #Select a column by its header
245
- s.column_by_header( 'Part' )
246
- s.ch( 'Part' )
247
- #=> Column
248
-
249
- #Iterate through rows or columns
250
- s.rows { |r| puts r } #All rows
251
- s.rows( 2 ) { |r| puts r } #From the 2nd to the last row
252
- s.rows( 1, 3 ) { |r| puts r } #Rows 1 to 3
253
- s.columns { |c| puts c } #All columns
254
- s.columns( 'B' ) { |c| puts c } #From the 2nd to the last column
255
- s.columns( 2 ) { |c| puts c } #From the 2nd to the last column
256
- s.columns( 'B', 'D' ) { |c| puts c } #Columns 2 to 4
257
- s.columns( 2, 4 ) { |c| puts c } #Columns 2 to 4
258
-
259
- #Remove all empty rows & columns
260
- s.compact!
261
-
262
- #Delete the current sheet from the workbook
263
- s.delete
264
-
265
- #Delete rows or columns "if( condition )" (iterates in reverse to preserve references during loop)
266
- s.delete_rows_if { |r| r.empty? }
267
- s.delete_columns_if { |c| c.empty? }
268
-
269
- #Filter the data given a column and a block to test values against.
270
- #Note: Returns a copy of the sheet when used without "!".
271
- #Note: This gem carries a Regexp to_proc method for Regex shorthand (shown below).
272
- s.filter!( 'Part' ) { |value| value =~ /Type[13]/ }
273
- s.filter!( 'Part', &/Type[13]/ )
274
-
275
- #Filter the data to a specific set of columns by their headers.
276
- #Note: Returns a copy of the sheet when used without "!".
277
- s.get_columns!( 'Cost', 'Part', 'Qty' )
278
- s.gc!( 'Cost', 'Part', 'Qty' )
279
-
280
- #Insert blank rows or columns ( before, number to insert )
281
- s.insert_rows( 2, 2 ) #Inserts 2 empty rows before row 2
282
- s.insert_columns( 'B', 1 ) #Inserts 2 empty columns before column 2
283
- s.insert_columns( 2, 1 ) #Inserts 2 empty columns before column 2
284
-
285
- #Find the first row which matches a value within a column (selected by header)
286
- #Note: Can now accept a Column object in place of a header.
287
- s.match( 'Qty' ) { |value| value == 1 } #=> 2
288
- s.match( 'Part', &/Type2/ ) #=> 3
289
-
290
- #Find the current end of the data range
291
- s.maxrow #=> 8
292
- s.rows.count #=> 8
293
- s.maxcol #=> 5
294
- s.columns.count #=> 5
295
-
296
- #Partition the sheet into two, given a header and a block (like Filter)
297
- #Note: this keeps the headers intact in both output sheets
298
- type_1_and_3, other = s.partition( 'Part' ) { |value| value =~ /Type[13]/ }
299
- type_1_and_3, other = s.partition( 'Part', &/Type[13]/ )
300
-
301
- #Reverse the data by rows or columns (ignores headers)
302
- s.reverse_rows!
303
- s.reverse_columns!
304
-
305
- #Sort the rows by header(s) (ignores header rows)
306
- s.sort_by!( 'Part' )
307
- s.sort_by!( 'Qty', 'Part' )
308
-
309
- #Split a Sheet into a Workbook of Sheets by a column (selected by header)
310
- wb = s.split( 'Part' )
311
- #=> <Workbook: [Sheet:Type1, Sheet:Type2, Sheet:Type3, Sheet:Type4]>
312
-
313
- #Sum all elements in a column by criteria in another column (selected by header)
314
- #Parameters: Header to pass to the block, Header to sum, Block.
315
- #Note: Now also accepts Column objects in place of headers.
316
- s.sumif( 'Part', 'Cost' ) { |part| part == 'Type1' } #=> 169.15
317
- s.sumif( 'Part', 'Cost', &/Type1/ ) #=> 169.15
318
-
319
- #Summarise a column by header into a Hash.
320
- s.summarise( 'Part' )
321
- #=> {"Type1"=>3, "Type2"=>2, "Type3"=>1, "Type4"=>1}
322
-
323
- #Convert the data into various formats:
324
- s.to_a #=> 2D Array
325
- s.to_excel #=> WIN32OLE Excel Workbook (Contains only the current sheet)
326
- s.to_html #=> String (HTML table)
327
- s.to_s #=> String (TSV)
328
-
329
- #Remove all rows with duplicate values in the given column (selected by header or Column object)
330
- s.uniq! 'Part'
331
-
332
- #Find a value in one column by searching another one (selected by headers or Column objects)
333
- s.vlookup( 'Part', 'Ref1', &/Type4/ ) #=> "XT3"
334
- ```
335
-
336
- Row / Column (Section)
337
- --------
338
-
339
- ```ruby
340
- #Reference a Row or Column
341
- row = s.row(2)
342
- col = s.column('B')
343
-
344
- =begin
345
- Append a value
346
- Note: Only extends the data boundaries when at the first row or column.
347
- This allows looping through an entire row or column to append single values,
348
- without worrying about using the correct index.
349
- =end
350
- s.row(1) << 'New'
351
- s.rows(2) { |r| r << 'Column' }
352
- s.column(1) << 'New'
353
- s.columns(2) { |c| c << 'Row' }
354
-
355
- #Access a cell by column header (Row only)
356
- s.row(2).cell_by_header( 'Part' ) #=> Element A2
357
- s.row(2).cell_h( 'Cost' ) #=> Element E2
358
-
359
- #Delete the data referenced by self.
360
- row.delete
361
- col.delete
362
-
363
- #Find the address of a cell matching a block
364
- row.find { |value| value == 'QT1' }
365
- row.find &/QT1/
366
- col.find { |value| value == 'QT1' }
367
- col.find &/QT1/
368
-
369
- #Summarise the current row or column into a Hash.
370
- s.column(1).summarise
371
- #=> {"Type1"=>3, "Type2"=>2, "Type3"=>1, "Type4"=>1}
372
-
373
- #Loop through all values
374
- row.each { |val| puts val }
375
- col.each { |val| puts val }
376
-
377
- #Loop through all values without including headers
378
- col.each_without_headers { |val| puts val }
379
- col.each_wh { |val| puts val }
380
-
381
- #Loop through each cell
382
- row.each_cell { |ce| puts "#{ ce.address }: #{ ce.value }" }
383
- col.each_cell { |ce| puts "#{ ce.address }: #{ ce.value }" }
384
-
385
- #Loop through each cell without including headers
386
- col.each_cell_without_headers { |ce| puts "#{ ce.address }: #{ ce.value }" }
387
- col.each_cell_wh { |ce| puts "#{ ce.address }: #{ ce.value }" }
388
-
389
- #Overwrite each value based on its current value
390
- row.map! { |val| val.to_s + 'a' }
391
- col.map! { |val| val.to_s + 'a' }
392
-
393
- #Get the value of a cell in the current row by its header
394
- row.value_by_header( 'Part' ) #=> 'Type1'
395
- row.val( 'Part' ) #=> 'Type1'
396
- ```
397
-
398
- Cell / Range (Element)
399
- --------
400
-
401
- ```ruby
402
- #Reference a Cell or Range
403
- cell = s.cell( 2, 2 )
404
- range = s.range('B2:C3')
405
-
406
- #Get the address and indices of the Element (Indices return that of the first cell for multi-cell Ranges)
407
- cell.address
408
- cell.row
409
- cell.column
410
- range.address
411
- range.row
412
- range.column
413
-
414
- #Get and set the value(s)
415
- cell.value #=> "QT1"
416
- cell.value = 'QT1'
417
- range.value #=> [["QT1", "231"], ["QT3", "123"]]
418
- range.value = "a"
419
- range.value #=> [["a", "a"], ["a", "a"]]
420
- range.value = [["QT1", "231"], ["QT3", "123"]]
421
- range.value #=> [["QT1", "231"], ["QT3", "123"]]
422
-
423
- #Loop through a range
424
- range.each { |val| puts val }
425
-
426
- #Loop through each cell within a range
427
- range.each_cell { |ce| puts "#{ ce.address }: #{ ce.value }" }
428
-
429
- ```
430
-
431
- Address Tools (Included in Sheet, Section, and Element)
432
- --------
433
-
434
- ```ruby
435
- #Get the column index from an address string
436
- s.address_to_col_index( 'A2' ) #=> 1
437
-
438
- #Translate an address to indices
439
- s.address_to_indices( 'A2' ) #=> [ 2, 1 ]
440
-
441
- #Translate letter(s) to a column index
442
- s.col_index( 'A' ) #=> 1
443
-
444
- #Translate a number to column letter(s)
445
- s.col_letter( 1 ) #=> "A"
446
-
447
- #Extract the column letter(s) or row number from an address
448
- s.column_id( 'A2' ) #=> "A"
449
- s.row_id( 'A2' ) #=> 2
450
-
451
- #Expand a Range address
452
- s.expand( 'A1:B2' ) #=> [["A1", "B1"], ["A2","B2"]]
453
- s.expand( 'A1' ) #=> [["A1"]]
454
-
455
- #Translate indices to an address
456
- s.indices_to_address( 2, 1 ) #=> "A2"
457
-
458
- #Offset an address by rows and columns
459
- s.offset( 'A2', 1, 2 ) #=> "C3"
460
- s.offset( 'A2', 2, 0 ) #=> "A4"
461
- s.offset( 'A2', -1, 0 ) #=> "A1"
462
-
463
- ```
464
-
465
- Importing a Hash
466
- --------
467
-
468
- ```ruby
469
- #Import a nested Hash (useful if you're summarising data before handing it to RubyExcel)
470
-
471
- #Here's an example Hash (built into the gem as RubyExcel.sample_hash)
472
- h = {
473
- Part1: {
474
- Type1: {
475
- SubType1: 1, SubType2: 2, SubType3: 3
476
- },
477
- Type2: {
478
- SubType1: 4, SubType2: 5, SubType3: 6
479
- }
480
- },
481
- Part2: {
482
- Type1: {
483
- SubType1: 1, SubType2: 2, SubType3: 3
484
- },
485
- Type2: {
486
- SubType1: 4, SubType2: 5, SubType3: 6
487
- }
488
- }
489
- }
490
-
491
- #Import the Hash to a Sheet
492
- s.load( h )
493
- #Or append the Hash to a Sheet
494
- s << h
495
-
496
- #Convert the symbols to strings (Not essential, but Excel can't handle Symbols in output)
497
- s.rows { |r| r.map! { |v| v.is_a?(Symbol) ? v.to_s : v } }
498
-
499
- #Have a look at the results
500
- require 'pp'
501
- pp s.to_a
502
- [["Part1", "Type1", "SubType1", 1],
503
- ["Part1", "Type1", "SubType2", 2],
504
- ["Part1", "Type1", "SubType3", 3],
505
- ["Part1", "Type2", "SubType1", 4],
506
- ["Part1", "Type2", "SubType2", 5],
507
- ["Part1", "Type2", "SubType3", 6],
508
- ["Part2", "Type1", "SubType1", 1],
509
- ["Part2", "Type1", "SubType2", 2],
510
- ["Part2", "Type1", "SubType3", 3],
511
- ["Part2", "Type2", "SubType1", 4],
512
- ["Part2", "Type2", "SubType2", 5],
513
- ["Part2", "Type2", "SubType3", 6]]
514
-
515
- ```
516
-
517
- Excel Tools ( requires win32ole and Excel )
518
- --------
519
-
520
- Make sure all your data types are compatible with Excel first!
521
-
522
- ```ruby
523
- #Sample RubyExcel::Workbook to work with
524
- rubywb = RubyExcel.sample_sheet.parent
525
-
526
- #Get a new Excel instance
527
- excel = rubywb.get_excel
528
-
529
- #Get a new Excel Workbook
530
- excelwb = rubywb.get_workbook( excel )
531
- excelwb = rubywb.get_workbook
532
-
533
- #Drop data into an Excel Sheet
534
- rubywb.dump_to_sheet( rubywb.sheets(1).to_a )
535
- rubywb.dump_to_sheet( rubywb.sheets(1).to_a, excelwb.sheets(1) )
536
-
537
- #Autofit and left-align a WIN32OLE Excel Sheet
538
- rubywb.make_sheet_pretty( excelwb.sheets(1) )
539
-
540
- #Output the RubyExcel::Workbook into a new Excel Workbook
541
- rubywb.to_excel
542
-
543
- #Output the RubyExcel::Sheet into a new Excel Workbook
544
- rubywb.sheets(1).to_excel
545
-
546
- #Output the RubyExcel::Workbook into an Excel Workbook and save the file
547
- #Note: The default directory is "Documents" or "My Documents" to support Ocra + InnoSetup installs.
548
- #Note: There is an optional second argument which if set to true doesn't make Excel visible.
549
- # This is a useful accelerator when running as an automated process.
550
- # If you set the process to be invisible, don't forget to close Excel after you're finished with it!
551
- rubywb.save_excel
552
- rubywb.save_excel( 'Output.xlsx' )
553
- rubywb.save_excel( 'c:/example/Output.xlsx' )
554
-
555
- #Add borders to a given Excel Range
556
- #1st Argument: WIN32OLE Range
557
- #2nd Argument (default 1), weight of borders (0 to 4)
558
- #3rd Argument (default false), include inner borders
559
- RubyExcel.borders( excelwb.sheets(1).usedrange ) #Give used range outer borders
560
- RubyExcel.borders( excelwb.sheets(1).usedrange, 2, true ) #Give used range inner and outer borders, medium weight
561
- RubyExcel.borders( excelwb.sheets(1).usedrange, 0, false ) #Clear outer borders from used range
562
-
563
- #You can even enter formula strings and Excel will evaluate them in the output.
564
- s = rubywb.sheets(1)
565
- s.row(1) << 'Formula'
566
- s.rows(2) { |row| row << "=SUM(D#{ row.idx }:E#{ row.idx })" }
567
- s.to_excel
568
-
569
- ```
570
-
571
- Comparison of operations with and without RubyExcel gem
572
- --------
573
-
574
- Without RubyExcel (one way to to it):
575
-
576
- ```ruby
577
- #Filter to only 'Part' of 'Type1' and 'Type3' while keeping the header row
578
- idx = data[0].index( 'Part' )
579
- data = [ data[0] ] + data[1..-1].select { |row| row[ idx ] =~ /Type[13]/ }
580
-
581
- #Keep only the columns 'Cost' and 'Ref2' in that order
582
- max_size = data.max_by(&:length).length #Standardise the row size to transpose into columns
583
- data.map! { |row| row.length == max_size ? row : row + Array.new( max_size - row.length, nil) }
584
- headers = [ 'Cost', 'Ref2' ]
585
- data = data.transpose.select { |header,_| headers.index(header) }.sort_by { |header,_| headers.index(header) }.transpose
586
-
587
- #Get the combined 'Cost' of every 'Part' of 'Type1' and 'Type3'
588
- find_idx, sum_idx = data[0].index('Part'), data[0].index('Cost')
589
- data[1..-1].inject(0) { |sum, row| row[find_idx] =~ /Type[13]/ ? sum + row[sum_idx] : sum }
590
-
591
- #Write the data to a TSV file
592
- output = data.map { |row| row.map { |el| "#{el}".strip.gsub( /\s/, ' ' ) }.join "\t" }.join $/
593
- File.write( 'output.txt', output )
594
-
595
- #Drop the data into an Excel sheet ( using Excel and win32ole )
596
- excel = WIN32OLE::new( 'excel.application' )
597
- excel.visible = true
598
- wb = excel.workbooks.add
599
- sheet = wb.sheets(1)
600
- sheet.range( sheet.cells( 1, 1 ), sheet.cells( data.length, data[0].length ) ).value = data
601
- wb.saveas( Dir.pwd.gsub('/','\\') + '\\Output.xlsx' )
602
- ```
603
-
604
- With RubyExcel:
605
-
606
- ```ruby
607
- #Filter to only 'Part' of 'Type1' and 'Type3' while keeping the header row
608
- s.filter!( 'Part', &/Type[13]/ )
609
-
610
- #Keep only the columns 'Cost' and 'Ref2' in that order
611
- s.get_columns!( 'Cost', 'Ref2' )
612
-
613
- #Get the combined 'Cost' of every 'Part' of 'Type1' and 'Type3'
614
- s.sumif( 'Part', 'Cost', &/Type[13]/ )
615
-
616
- #Write the data to a TSV file
617
- File.write( 'output.txt', s.to_s )
618
-
619
- #Write the data to an XLSX file ( requires Excel and win32ole )
620
- s.parent.save_excel( 'Output.xlsx' )
621
- ```
622
-
623
- Todo List
624
- =========
625
-
626
- - Write TestCases for most methods (Hopefully that'll stop me releasing broken gem versions)
627
-
628
- - Find bugs and extirpate them.
629
-
630
- - Optimise slow operations