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 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('data')
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.0'
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
- @content = content
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
@@ -68,6 +68,8 @@ Format options (bold, italic, colors) are forwarded to cells.
68
68
  }
69
69
  }
70
70
  end #to_xml
71
-
71
+ def inspect
72
+ "#<Excel::Row:#{object_id} #{columns.size} Columns>"
73
+ end
72
74
  end #class Row
73
75
  end #module Excel
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
 
@@ -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
- @worksheets.each{|worksheet|
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
  }
@@ -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
- @columns = []
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
- @log.fatal("Worksheet: Fixme Columns definition")
44
- @columns.each{|column|
45
- row << insertion[column]
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
- #~ xmlbuilder[ns.call].Column( ns.call('Width') => 100)
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
@@ -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.0', Excel::VERSION)
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.columns << 1
286
- ws.columns << 2
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.columns << 1
378
- ws.columns << 2
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: 27
4
+ hash: 25
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 0
10
- version: 0.1.0
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: 2010-09-15 00:00:00 +02:00
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