rexcel 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/examples/example.rb +4 -1
- data/lib/rexcel.rb +2 -1
- data/lib/rexcel/cell.rb +5 -2
- data/lib/rexcel/column.rb +77 -0
- data/lib/rexcel/row.rb +3 -1
- data/lib/rexcel/style.rb +4 -0
- data/lib/rexcel/workbook.rb +2 -2
- data/lib/rexcel/worksheet.rb +25 -7
- data/unittest/test_rexcel.rb +76 -16
- metadata +5 -4
data/examples/example.rb
CHANGED
@@ -1,11 +1,14 @@
|
|
1
|
+
#encoding: cp1252
|
1
2
|
$:.unshift('../lib') if $0 == __FILE__
|
2
3
|
require 'rexcel'
|
3
4
|
Excel::LOGGER.level = Log4r::DEBUG
|
4
5
|
|
5
|
-
wb = Excel::Workbook.new(
|
6
|
+
wb = Excel::Workbook.new()
|
6
7
|
|
7
8
|
wb << [1,2,3,4,5,6,7]
|
8
9
|
wb << [:a, :b, :c, :d, :e, :f]
|
10
|
+
wb << ['�', '�', '�', '�', '�', '�', '�']
|
11
|
+
wb << ['�', '�', '�', '�', '�', '�', '�'].map{|x| x.encode('utf-8')}
|
9
12
|
|
10
13
|
|
11
14
|
wb << ws = Excel::Worksheet.new('Formats')
|
data/lib/rexcel.rb
CHANGED
@@ -71,7 +71,7 @@ require 'singleton'
|
|
71
71
|
Frame for Excel-tools.
|
72
72
|
=end
|
73
73
|
module Excel
|
74
|
-
VERSION = '0.1.
|
74
|
+
VERSION = '0.1.1'
|
75
75
|
|
76
76
|
LOGGER = Log4r::Logger.new( name )#, Log4r::DEBUG, :trunc => true )
|
77
77
|
LOGGER.outputters << Log4r::StdoutOutputter.new('std', :level => Log4r::WARN )
|
@@ -136,6 +136,7 @@ require 'rexcel/workbook'
|
|
136
136
|
require 'rexcel/worksheet'
|
137
137
|
require 'rexcel/row'
|
138
138
|
require 'rexcel/cell'
|
139
|
+
require 'rexcel/column'
|
139
140
|
require 'rexcel/style'
|
140
141
|
|
141
142
|
=begin
|
data/lib/rexcel/cell.rb
CHANGED
@@ -40,10 +40,13 @@ Options:
|
|
40
40
|
@log.warn("Excel::Cell: undefined option #{options}")
|
41
41
|
end
|
42
42
|
}
|
43
|
-
|
43
|
+
#Convert data to utf-8
|
44
|
+
#Without this, you get problems, when you mix encodings.
|
45
|
+
#~ @content = content
|
46
|
+
@content = content.respond_to?(:encode) ? content.encode('utf-8') : content
|
44
47
|
@type = get_excel_type() unless @type
|
45
48
|
end
|
46
|
-
#Content of the cell
|
49
|
+
#Content of the cell. Strings are converted to utf-8.
|
47
50
|
attr_reader :content
|
48
51
|
#Target type for Excel
|
49
52
|
attr_reader :type
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Excel
|
2
|
+
class Column
|
3
|
+
=begin rdoc
|
4
|
+
Define identifier and optional other values.
|
5
|
+
|
6
|
+
*title: Used for title line. Default: ID
|
7
|
+
=end
|
8
|
+
def initialize( id, options = {})
|
9
|
+
@id = id
|
10
|
+
@title = id
|
11
|
+
options.each{|key, value|
|
12
|
+
case key
|
13
|
+
when :title; @title = value.respond_to?(:encode) ? value.encode('utf-8') : value
|
14
|
+
when :width
|
15
|
+
if value.is_a?(Numeric)
|
16
|
+
@width = value
|
17
|
+
elsif value.respond_to?(:to_i)
|
18
|
+
@width = value.to_i
|
19
|
+
else
|
20
|
+
raise ArgumentError, "Width is no Numeric"
|
21
|
+
end
|
22
|
+
raise ArgumentError, "Length zero or less" if @width <= 0
|
23
|
+
when :style
|
24
|
+
raise ArgumentError unless value.is_a?(Style)
|
25
|
+
@style = value
|
26
|
+
else
|
27
|
+
@log.error("#{self.class}: Undefined option #{key}")
|
28
|
+
end
|
29
|
+
}
|
30
|
+
end
|
31
|
+
#Identifier of column. Used for ruby internal reference
|
32
|
+
attr_reader :id
|
33
|
+
#Used for title line in Excel
|
34
|
+
attr_reader :title
|
35
|
+
|
36
|
+
=begin rdoc
|
37
|
+
Build the xml a work sheet column.
|
38
|
+
|
39
|
+
ns must be a method-object to implement the namespace definitions.
|
40
|
+
|
41
|
+
Format options (bold, italic, colors) are forwarded to cells.
|
42
|
+
=end
|
43
|
+
def to_xml(xmlbuilder, ns)
|
44
|
+
options = {}
|
45
|
+
options[ns.call('Width')] = @width if @width
|
46
|
+
options[ns.call('StyleID')] = @style.style_id if @style
|
47
|
+
|
48
|
+
xmlbuilder[ns.call].Column( options )
|
49
|
+
end
|
50
|
+
|
51
|
+
=begin rdoc
|
52
|
+
Fill an Excel Columns
|
53
|
+
Receives a OLE-cell and optional a row.
|
54
|
+
|
55
|
+
|
56
|
+
=end
|
57
|
+
def to_xls()
|
58
|
+
@log.fatal("Not implemented yet")
|
59
|
+
end
|
60
|
+
|
61
|
+
end #class Column
|
62
|
+
end #module Excel
|
63
|
+
|
64
|
+
__END__
|
65
|
+
Fixmes:
|
66
|
+
|
67
|
+
Options:
|
68
|
+
*title
|
69
|
+
*width
|
70
|
+
*color?
|
71
|
+
|
72
|
+
to do:
|
73
|
+
|
74
|
+
Column.to_xls
|
75
|
+
Column.to_xml
|
76
|
+
|
77
|
+
Worksheet#titleline
|
data/lib/rexcel/row.rb
CHANGED
data/lib/rexcel/style.rb
CHANGED
@@ -91,7 +91,11 @@ Not implemented (yet)
|
|
91
91
|
* Font
|
92
92
|
=end
|
93
93
|
def initialize(name, options = {})
|
94
|
+
|
94
95
|
@name = name
|
96
|
+
#Catch, if name was forgotten and options are first parameter.
|
97
|
+
raise ArgumentError, "Style requries key" if name.is_a?(Hash)
|
98
|
+
|
95
99
|
@log = options[:log] || LOGGER
|
96
100
|
@log.debug( "Create Style #{name}")
|
97
101
|
|
data/lib/rexcel/workbook.rb
CHANGED
@@ -104,12 +104,12 @@ For big files, it is recommended to use the way via xml.
|
|
104
104
|
}
|
105
105
|
|
106
106
|
first = true
|
107
|
-
|
107
|
+
#wb.Worksheets.Add appends new worksheets at begin -> reverse for creation to get right sequence.
|
108
|
+
@worksheets.reverse.each{|worksheet|
|
108
109
|
if first
|
109
110
|
worksheet.to_xls(wb.ActiveSheet)
|
110
111
|
first = false
|
111
112
|
else
|
112
|
-
@log.error("#{__method__}: Wrong worksheet sequence")
|
113
113
|
worksheet.to_xls(wb.Worksheets.Add)
|
114
114
|
end
|
115
115
|
}
|
data/lib/rexcel/worksheet.rb
CHANGED
@@ -8,7 +8,8 @@ class Worksheet
|
|
8
8
|
def initialize( name = nil, options = {})
|
9
9
|
@log = options[:log] || LOGGER
|
10
10
|
@name = name || 'Sheet'
|
11
|
-
|
11
|
+
#Array with columns sequence. Needed to insert Hashes.
|
12
|
+
@columns = {}
|
12
13
|
@rows = []
|
13
14
|
options.each{|key,value|
|
14
15
|
case key
|
@@ -20,8 +21,6 @@ class Worksheet
|
|
20
21
|
end
|
21
22
|
#Name of the sheet
|
22
23
|
attr_reader :name
|
23
|
-
#Array with columns sequence. Needed to insert Hashes.
|
24
|
-
attr_reader :columns
|
25
24
|
#Array with rows
|
26
25
|
attr_reader :rows
|
27
26
|
=begin rdoc
|
@@ -34,15 +33,17 @@ If no actual worksheet is available, a new worksheet i created.
|
|
34
33
|
=end
|
35
34
|
def << (insertion)
|
36
35
|
case insertion
|
36
|
+
when Column
|
37
|
+
@columns[insertion.id] = insertion
|
37
38
|
when Array
|
38
39
|
@rows << row = Row.new()
|
39
40
|
row << insertion
|
40
41
|
when Hash
|
41
42
|
raise ArgumentError, "#{Worksheet}: Hash without heading data" if @columns.empty?
|
42
43
|
@rows << row = Row.new()
|
43
|
-
|
44
|
-
@columns.each{|column|
|
45
|
-
row << insertion[
|
44
|
+
#Hashes keep the order of entry. -> no internal order necessary
|
45
|
+
@columns.each{|id, column|
|
46
|
+
row << insertion[id]
|
46
47
|
}
|
47
48
|
when Row
|
48
49
|
@rows << insertion
|
@@ -51,6 +52,23 @@ If no actual worksheet is available, a new worksheet i created.
|
|
51
52
|
end
|
52
53
|
end
|
53
54
|
=begin rdoc
|
55
|
+
Add a title line from columns data.
|
56
|
+
|
57
|
+
|
58
|
+
=end
|
59
|
+
def add_title_row(columns = @columns, style = Style.new("Title_row#{object_id}", :bold => true))
|
60
|
+
#~ raise ArgumentError, "#{Worksheet}##{__method__}: No columns list found" unless columns.respond_to?(:each)
|
61
|
+
raise ArgumentError, "#{Worksheet}##{__method__}: No columns list found" unless columns.is_a?(Hash)
|
62
|
+
raise ArgumentError, "#{Worksheet}##{__method__}: Columns list empty" if columns.empty?
|
63
|
+
|
64
|
+
@rows << row = Row.new(:style => style )
|
65
|
+
#Hashes keep the order of entry. -> no internal order necessary
|
66
|
+
columns.each{|id, column|
|
67
|
+
row << Cell.new(column.title)
|
68
|
+
}
|
69
|
+
row
|
70
|
+
end
|
71
|
+
=begin rdoc
|
54
72
|
Build the xml for the work sheet.
|
55
73
|
|
56
74
|
ns must be a method-object to implement the namespace definitions.
|
@@ -61,7 +79,7 @@ ns must be a method-object to implement the namespace definitions.
|
|
61
79
|
@log.debug("Prepare XML for worksheet #{@name}")
|
62
80
|
xmlbuilder[ns.call].Worksheet(ns.call('Name') => @name){
|
63
81
|
xmlbuilder[ns.call].Table(){
|
64
|
-
|
82
|
+
@columns.each{|id,column| column.to_xml(xmlbuilder, ns) }
|
65
83
|
@rows.each{|row|
|
66
84
|
row.to_xml(xmlbuilder, ns)
|
67
85
|
} #row
|
data/unittest/test_rexcel.rb
CHANGED
@@ -94,7 +94,7 @@ end
|
|
94
94
|
|
95
95
|
class Test_excel < Test::Unit::TestCase
|
96
96
|
def test_version()
|
97
|
-
assert_equal('0.1.
|
97
|
+
assert_equal('0.1.1', Excel::VERSION)
|
98
98
|
end
|
99
99
|
end #class Test_excel < Test::Unit::TestCase
|
100
100
|
|
@@ -282,8 +282,8 @@ class Test_workbook_insertions < Test::Unit::TestCase
|
|
282
282
|
assert_instance_of(Excel::Worksheet, wb.active_worksheet)
|
283
283
|
|
284
284
|
ws = wb.active_worksheet
|
285
|
-
ws
|
286
|
-
ws
|
285
|
+
ws << Excel::Column.new( 1 )
|
286
|
+
ws << Excel::Column.new( 2 )
|
287
287
|
|
288
288
|
assert_nothing_raised{ wb << { 1 => :a, 2 => :b, 3 => :c } }
|
289
289
|
assert_equal(1, wb.worksheets.size)#no new worksheet created
|
@@ -291,6 +291,8 @@ class Test_workbook_insertions < Test::Unit::TestCase
|
|
291
291
|
<ss:Workbook xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
|
292
292
|
<ss:Worksheet ss:Name="Sheet0">
|
293
293
|
<ss:Table>
|
294
|
+
<ss:Column/>
|
295
|
+
<ss:Column/>
|
294
296
|
<ss:Row>
|
295
297
|
<ss:Cell>
|
296
298
|
<ss:Data ss:Type="String">a</ss:Data>
|
@@ -313,6 +315,73 @@ class Test_workbook_insertions < Test::Unit::TestCase
|
|
313
315
|
|
314
316
|
end #class Test_workbook
|
315
317
|
|
318
|
+
class Test_Columns < Test::Unit::TestCase
|
319
|
+
def test_init
|
320
|
+
assert_raise(ArgumentError){ Excel::Column.new()}
|
321
|
+
assert_equal(1, Excel::Column.new(1).id)
|
322
|
+
assert_equal(1, Excel::Column.new(1).title)
|
323
|
+
end
|
324
|
+
def test_width
|
325
|
+
assert_raise(ArgumentError){ Excel::Column.new(1, :width => :bold )}
|
326
|
+
assert_raise(ArgumentError){ Excel::Column.new(1, :width => 'xx100' )} #0
|
327
|
+
|
328
|
+
assert_raise(ArgumentError){ Excel::Column.new(1, :width => 0 )}
|
329
|
+
assert_raise(ArgumentError){ Excel::Column.new(1, :width => -1 )}
|
330
|
+
|
331
|
+
assert_nothing_raised{ Excel::Column.new(1, :width => '100')}
|
332
|
+
#~ assert_equal{ 100, Excel::Column.new(1, :width => '100').width}
|
333
|
+
assert_nothing_raised{ Excel::Column.new(1, :width => 1)}
|
334
|
+
end
|
335
|
+
|
336
|
+
def test_style
|
337
|
+
assert_raise(ArgumentError){ Excel::Column.new(1, :style => 1 )}
|
338
|
+
assert_raise(ArgumentError){ Excel::Column.new(1, :style => :bold )}
|
339
|
+
assert_nothing_raised{ Excel::Column.new(1, :style => Excel::Style.new(1))}
|
340
|
+
end
|
341
|
+
end #class Test_Columns < Test::Unit::TestCase
|
342
|
+
class Test_Columns_xml < Test::Unit::TestCase
|
343
|
+
def setup()
|
344
|
+
@mock = Mock_document.new
|
345
|
+
end
|
346
|
+
def test_width
|
347
|
+
col = Excel::Column.new(1,:width => '100')
|
348
|
+
assert_equal(%{<ss:Column ss:Width="100"/>},
|
349
|
+
@mock.testcase{|builder, ns_proc|
|
350
|
+
col.to_xml( builder,ns_proc)
|
351
|
+
})
|
352
|
+
end #def test_width
|
353
|
+
def test_style
|
354
|
+
col = Excel::Column.new(:test,:style => Excel::Style.new(1, :color => 5))
|
355
|
+
#Style id empty, because of the missing workbook in mock.
|
356
|
+
assert_equal(%{<ss:Column ss:StyleID=""/>},
|
357
|
+
@mock.testcase{|builder, ns_proc|
|
358
|
+
col.to_xml( builder,ns_proc)
|
359
|
+
})
|
360
|
+
end #def test_style
|
361
|
+
|
362
|
+
end #class Test_Columns_xml < Test::Unit::TestCase
|
363
|
+
|
364
|
+
class Test_Worksheet < Test::Unit::TestCase
|
365
|
+
def test_init
|
366
|
+
ws = Excel::Worksheet.new()
|
367
|
+
assert_equal('Sheet', ws.name)
|
368
|
+
assert_equal([], ws.rows)
|
369
|
+
#~ assert_equal({}, ws.columns) #only internal.
|
370
|
+
end #def test_init
|
371
|
+
def test_add_title_row
|
372
|
+
ws = Excel::Worksheet.new()
|
373
|
+
assert_raise(ArgumentError){ ws.add_title_row(:xx) } #no #each
|
374
|
+
assert_raise(ArgumentError){ ws.add_title_row([]) } #wrong type
|
375
|
+
assert_raise(ArgumentError){ ws.add_title_row({}) } #empty
|
376
|
+
|
377
|
+
assert_raise(ArgumentError){ ws.add_title_row() }#no columns defined
|
378
|
+
|
379
|
+
title_row = ws.add_title_row({ 1 => Excel::Column.new(1), 2=> Excel::Column.new(2)})
|
380
|
+
assert_instance_of(Excel::Row, title_row)
|
381
|
+
assert_equal(2, title_row.columns.size)
|
382
|
+
|
383
|
+
end
|
384
|
+
end #class Test_Worksheet
|
316
385
|
class Test_Worksheet_insertions < Test::Unit::TestCase
|
317
386
|
def setup()
|
318
387
|
@mock = Mock_document.new
|
@@ -374,13 +443,15 @@ class Test_Worksheet_insertions < Test::Unit::TestCase
|
|
374
443
|
assert_raise( ArgumentError ){ ws << { 1 => :a, 2 => :b, 3 => :c } }
|
375
444
|
assert_equal(0, ws.rows.size)
|
376
445
|
|
377
|
-
ws
|
378
|
-
ws
|
446
|
+
ws << Excel::Column.new(1)
|
447
|
+
ws << Excel::Column.new(2)
|
379
448
|
|
380
449
|
assert_nothing_raised{ ws << { 1 => :a, 2 => :b, 3 => :c } }
|
381
450
|
assert_equal(1, ws.rows.size)
|
382
451
|
assert_equal(%{<ss:Worksheet ss:Name="Sheet">
|
383
452
|
<ss:Table>
|
453
|
+
<ss:Column/>
|
454
|
+
<ss:Column/>
|
384
455
|
<ss:Row>
|
385
456
|
<ss:Cell>
|
386
457
|
<ss:Data ss:Type="String">a</ss:Data>
|
@@ -712,14 +783,3 @@ end
|
|
712
783
|
#~ }
|
713
784
|
|
714
785
|
__END__
|
715
|
-
|
716
|
-
#~ build_xml('test_save_xml.xml')
|
717
|
-
|
718
|
-
#~ mk_excel(File.join(Dir.pwd, "test_xml.xlsx"), File.join(Dir.pwd, 'test_save_xml.xml'))
|
719
|
-
xls = ExcelXML.new
|
720
|
-
#~ xls.save_xml("test_xml.xml")
|
721
|
-
File.delete("test_xml.xml") if File.exist?("test_xml.xml")
|
722
|
-
xls.mk_excel("test_xml.xlsx")
|
723
|
-
#~ xls.mk_excel("test_xml.xlsx", 'example_excel_xml.xml')
|
724
|
-
|
725
|
-
#~ mk_excel("./test2.xls", data) #Speichert in Eigene Dateien
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rexcel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 25
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 1
|
10
|
+
version: 0.1.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Knut Lickert
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date:
|
18
|
+
date: 2011-02-07 00:00:00 +01:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -81,6 +81,7 @@ files:
|
|
81
81
|
- lib/rexcel/row.rb
|
82
82
|
- lib/rexcel/cell.rb
|
83
83
|
- lib/rexcel/style.rb
|
84
|
+
- lib/rexcel/column.rb
|
84
85
|
- examples/example.rb
|
85
86
|
- examples/example_format.rb
|
86
87
|
- examples/example_color.rb
|