rexcel 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/examples/example.rb +28 -6
- data/examples/example_format.rb +1 -0
- data/examples/example_sequel.rb +52 -0
- data/lib/rexcel.rb +13 -63
- data/lib/rexcel/cell.rb +34 -1
- data/lib/rexcel/row.rb +77 -55
- data/lib/rexcel/workbook.rb +141 -43
- data/lib/rexcel/worksheet.rb +120 -76
- data/readme.rdoc +66 -0
- data/unittest/expected/Test_Workbook_to_csv-test_filename.csv +4 -0
- data/unittest/expected/Test_Workbook_to_csv-test_filename_encoding.csv +4 -0
- data/unittest/expected/Test_Worksheet_to_csv-test_filename.csv +4 -0
- data/unittest/expected/Test_Worksheet_to_csv-test_filename_encoding.csv +4 -0
- data/unittest/rexcel_test_helper.rb +91 -0
- data/unittest/test_rexcel.rb +12 -582
- data/unittest/test_rexcel_cell.rb +126 -0
- data/unittest/test_rexcel_row.rb +103 -0
- data/unittest/test_rexcel_workbook.rb +293 -0
- data/unittest/test_rexcel_worksheet.rb +154 -0
- metadata +66 -79
data/examples/example.rb
CHANGED
@@ -1,16 +1,37 @@
|
|
1
1
|
#encoding: cp1252
|
2
|
+
=begin rdoc
|
3
|
+
Create an excel file.
|
4
|
+
|
5
|
+
Creates
|
6
|
+
* test.xml
|
7
|
+
* test_xml.xls
|
8
|
+
* test.xls
|
9
|
+
* test.xlsx
|
10
|
+
=end
|
2
11
|
$:.unshift('../lib') if $0 == __FILE__
|
3
12
|
require 'rexcel'
|
4
13
|
Excel::LOGGER.level = Log4r::DEBUG
|
5
14
|
|
6
15
|
wb = Excel::Workbook.new()
|
7
16
|
|
8
|
-
|
9
|
-
wb << [
|
10
|
-
wb << ['
|
11
|
-
wb <<
|
12
|
-
|
13
|
-
|
17
|
+
#Sheet one with numbers, letters and umlauts.
|
18
|
+
wb << ['Integer', 1,2,3,4,5,6,7]
|
19
|
+
wb << ['Float', 1.1,2.2,3.3,4.4,5.5,6.6,7.7]
|
20
|
+
wb << %w{Letters a b c d e f}
|
21
|
+
begin
|
22
|
+
wb << [:Symbols, :a, :b, :c, :d, :e, :f]
|
23
|
+
rescue
|
24
|
+
puts "Warning: Adding symbols have problems"
|
25
|
+
puts "Please report the problem with the following informations:"
|
26
|
+
puts "ruby #{RUBY_VERSION}"
|
27
|
+
puts "#{Excel::Excel.instance.xl.Name} #{Excel::Excel.instance.xl.version}"
|
28
|
+
puts Excel::Excel.instance.xl.OperatingSystem
|
29
|
+
puts "Thanks"
|
30
|
+
end
|
31
|
+
wb << ['Umlauts', '�', '�', '�', '�', '�', '�', '�']
|
32
|
+
wb << ['Umlauts/UTF8', '�', '�', '�', '�', '�', '�', '�'].map{|x| x.encode('utf-8')}
|
33
|
+
|
34
|
+
#Sheet 2: Some text formatting.
|
14
35
|
wb << ws = Excel::Worksheet.new('Formats')
|
15
36
|
ws << row = Excel::Row.new
|
16
37
|
row << cell = Excel::Cell.new(1)
|
@@ -27,6 +48,7 @@ row << cell = Excel::Cell.new('grau text', :style => style)
|
|
27
48
|
|
28
49
|
|
29
50
|
wb.save('test.xml')
|
51
|
+
#Create xls based on xml.
|
30
52
|
wb.save('test_xml.xls', 'test.xml')
|
31
53
|
wb.save('test.xls')
|
32
54
|
wb.save('test.xlsx')
|
data/examples/example_format.rb
CHANGED
@@ -0,0 +1,52 @@
|
|
1
|
+
#encoding: cp1252
|
2
|
+
=begin rdoc
|
3
|
+
Create a sqlite-DB and copy the data from table to Excel.
|
4
|
+
|
5
|
+
This test needs a SQLITE-Installation
|
6
|
+
=end
|
7
|
+
$:.unshift('../lib') if $0 == __FILE__
|
8
|
+
require 'rexcel'
|
9
|
+
Excel::LOGGER.level = Log4r::DEBUG
|
10
|
+
|
11
|
+
require 'sequel'
|
12
|
+
|
13
|
+
begin
|
14
|
+
DB = Sequel.sqlite()
|
15
|
+
rescue Sequel::AdapterNotFound
|
16
|
+
puts "No sqlite found - test not possible"
|
17
|
+
exit
|
18
|
+
end
|
19
|
+
#
|
20
|
+
#Fill DB with data
|
21
|
+
#
|
22
|
+
DB.create_table :testtable do
|
23
|
+
column :column_1, :integer
|
24
|
+
column :column_2, :integer
|
25
|
+
column :column_3, :integer
|
26
|
+
end
|
27
|
+
1.upto(100){|i|
|
28
|
+
DB[:testtable].insert( i, i * 2, i ** 2 )
|
29
|
+
}
|
30
|
+
|
31
|
+
|
32
|
+
#
|
33
|
+
#Create Excel from DB
|
34
|
+
#
|
35
|
+
WB = Excel::Workbook.new()
|
36
|
+
WB << WS = Excel::Worksheet.new('Formats')
|
37
|
+
WB << style = Excel::Style.new(:column, :color => 14)
|
38
|
+
|
39
|
+
DB[:testtable].columns.each{|col|
|
40
|
+
WS << Excel::Column.new(col, :style => style)
|
41
|
+
}
|
42
|
+
x = WS.add_title_row
|
43
|
+
p x
|
44
|
+
DB[:testtable].all{| dataset|
|
45
|
+
WS << dataset
|
46
|
+
}
|
47
|
+
|
48
|
+
|
49
|
+
WB.save('test_sequel.xml')
|
50
|
+
WB.save('test_sequel_xml.xls', 'test_sequel.xml')
|
51
|
+
#~ WB.save('test_sequel.xls')
|
52
|
+
#~ WB.save('test_sequel.xlsx')
|
data/lib/rexcel.rb
CHANGED
@@ -3,65 +3,10 @@
|
|
3
3
|
:title:Create Excel-documents with ruby
|
4
4
|
Build Excel documents via win32ole.
|
5
5
|
|
6
|
-
==Example 1 (Simple Spreadsheet):
|
7
|
-
require 'excel'
|
8
|
-
|
9
|
-
wb = Excel::Workbook.new()
|
10
|
-
|
11
|
-
wb << [1,2,3,4,5,6,7]
|
12
|
-
wb << [:a, :b, :c, :d, :e, :f]
|
13
|
-
|
14
|
-
#Save as excel spreadsheets
|
15
|
-
wb.save('test.xls') #excel97_2003_format
|
16
|
-
wb.save('test.xlsx') #Excel 2007
|
17
|
-
|
18
|
-
wb.save('test.xml') #Microsoft Office Word 2003 XML Format
|
19
|
-
wb.save('test.xls', 'test.xml')#Build xls from xlm
|
20
|
-
|
21
|
-
==Example 2 (Access to Worksheets, Rows and Cells):
|
22
|
-
require 'excel'
|
23
|
-
|
24
|
-
wb = Excel::Workbook.new()
|
25
|
-
|
26
|
-
wb << ws = Excel::Worksheet.new('My Spreadsheet')
|
27
|
-
ws << row = Excel::Row.new()
|
28
|
-
row << Excel::Cell.new(1)
|
29
|
-
row << Excel::Cell.new(2)
|
30
|
-
row << Excel::Cell.new(4)
|
31
|
-
|
32
|
-
#Save as excel spreadsheets
|
33
|
-
wb.save('test.xls') #excel97_2003_format
|
34
|
-
wb.save('test.xlsx') #Excel 2007
|
35
|
-
|
36
|
-
wb.save('test.xml') #Microsoft Office Word 2003 XML Format
|
37
|
-
wb.save('test.xls', 'test.xml')#Build xls from xlm
|
38
|
-
|
39
|
-
==Example 3 (With Format options):
|
40
|
-
require 'excel'
|
41
|
-
|
42
|
-
wb = Excel::Workbook.new()
|
43
|
-
wb << style = Excel::Style.new('fett', :bold => true)
|
44
|
-
|
45
|
-
wb << ws = Excel::Worksheet.new('My Spreadsheet')
|
46
|
-
ws << row = Excel::Row.new()
|
47
|
-
row << Excel::Cell.new(1)
|
48
|
-
row << Excel::Cell.new(2)
|
49
|
-
row << Excel::Cell.new(999, :style => style)
|
50
|
-
|
51
|
-
#Save as excel spreadsheets
|
52
|
-
wb.save('test.xls') #excel97_2003_format
|
53
|
-
wb.save('test.xlsx') #Excel 2007
|
54
|
-
|
55
|
-
wb.save('test.xml') #Microsoft Office Word 2003 XML Format
|
56
|
-
wb.save('test.xls', 'test.xml')#Build xls from xlm
|
57
|
-
|
58
|
-
|
59
|
-
'Big' spreadsheets needs a long time to be build.
|
60
|
-
(20000 lines need 2 hours)
|
61
|
-
|
62
|
-
When you build the xml, and then the xls from xlm, the wor is done in seconds.
|
63
|
-
|
64
6
|
|
7
|
+
This gem was tested with
|
8
|
+
* Windows XP + MS Excel 2007 (Version 12)
|
9
|
+
* Windows 7 + MS Excel 2007 (Version 12)
|
65
10
|
=end
|
66
11
|
require 'win32ole'
|
67
12
|
require 'log4r'
|
@@ -71,7 +16,7 @@ require 'singleton'
|
|
71
16
|
Frame for Excel-tools.
|
72
17
|
=end
|
73
18
|
module Excel
|
74
|
-
VERSION = '0.1.
|
19
|
+
VERSION = '0.1.2'
|
75
20
|
|
76
21
|
LOGGER = Log4r::Logger.new( name )#, Log4r::DEBUG, :trunc => true )
|
77
22
|
LOGGER.outputters << Log4r::StdoutOutputter.new('std', :level => Log4r::WARN )
|
@@ -125,11 +70,16 @@ Exceptionclass for empty Workbook, Worksheet, Row
|
|
125
70
|
end #module Excel
|
126
71
|
|
127
72
|
=begin
|
128
|
-
|
73
|
+
Close excel instance
|
74
|
+
|
75
|
+
The double at_exit is needed.
|
76
|
+
Else you get problems in unit test
|
129
77
|
=end
|
130
|
-
|
131
|
-
|
132
|
-
|
78
|
+
at_exit {
|
79
|
+
at_exit {
|
80
|
+
Excel::Excel.instance.close
|
81
|
+
}
|
82
|
+
}
|
133
83
|
|
134
84
|
|
135
85
|
require 'rexcel/workbook'
|
data/lib/rexcel/cell.rb
CHANGED
@@ -32,7 +32,10 @@ Options:
|
|
32
32
|
case key
|
33
33
|
when :log
|
34
34
|
when :string
|
35
|
-
|
35
|
+
if value
|
36
|
+
@type = 'String'
|
37
|
+
content = content.to_s
|
38
|
+
end
|
36
39
|
when :style
|
37
40
|
@style = value
|
38
41
|
raise ArgumentError, "Style is no Excel::Style" unless @style.is_a?(Style)
|
@@ -128,6 +131,36 @@ Receives a OLE-cell and optional a row.
|
|
128
131
|
cell
|
129
132
|
end #to_xls
|
130
133
|
|
134
|
+
=begin rdoc
|
135
|
+
Fill an CSV-Field.
|
136
|
+
|
137
|
+
The output is set depending on cell content.
|
138
|
+
The csv-value is optimized to be used by Excel.
|
139
|
+
|
140
|
+
Examples for conversion:
|
141
|
+
* 1.1 -> ='1.1' (1.1 would become 1st January)
|
142
|
+
|
143
|
+
=end
|
144
|
+
def to_csv()
|
145
|
+
cellcontent = @content
|
146
|
+
case @type
|
147
|
+
when 'String' #Suppress automatic conversion from Excel
|
148
|
+
cellcontent = "\"#{@content}\"" if @content =~ /^\A[\s\d]/
|
149
|
+
when 'Number'
|
150
|
+
#~ cellcontent = "%.2f" % cellcontent if cellcontent.is_a?(Float)
|
151
|
+
#http://www.creativyst.com/Doc/Articles/CSV/CSV01.htm#CSVAndExcel
|
152
|
+
cellcontent = "=\"#{cellcontent}\"" if cellcontent.is_a?(Float)
|
153
|
+
when 'DateTime'
|
154
|
+
@log.warn("Cell type DateTime not tested")
|
155
|
+
#avoid interpretation in excel, e.g. dates. does not work with numbers.
|
156
|
+
cellcontent = " #{cellcontent}"
|
157
|
+
when nil #no conversion
|
158
|
+
cellcontent = @content
|
159
|
+
else
|
160
|
+
raise ArgumentError, "#{self.class}##{__method__}: Undefined CSV type #{@type}"
|
161
|
+
end
|
162
|
+
cellcontent
|
163
|
+
end #to_csv
|
131
164
|
|
132
165
|
end #class Cell
|
133
166
|
end #module Excel
|
data/lib/rexcel/row.rb
CHANGED
@@ -2,50 +2,50 @@ module Excel
|
|
2
2
|
=begin rdoc
|
3
3
|
A Row in the spreadsheet.
|
4
4
|
=end
|
5
|
-
class Row
|
5
|
+
class Row
|
6
6
|
=begin rdoc
|
7
7
|
Define a new row.
|
8
8
|
=end
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
9
|
+
def initialize( options = {})
|
10
|
+
@log = options[:log] || LOGGER
|
11
|
+
@columns = []
|
12
|
+
options.each{|key,value|
|
13
|
+
case key
|
14
|
+
when :log
|
15
|
+
when :style
|
16
|
+
@style = value
|
17
|
+
raise ArgumentError, "Style is no Excel::Style" unless @style.is_a?(Style)
|
18
|
+
else
|
19
|
+
@log.warn("Excel::Row: undefined option #{option}")
|
20
|
+
end
|
21
|
+
}
|
22
|
+
end
|
23
|
+
#Array with columns of this row
|
24
|
+
attr_reader :columns
|
25
|
+
#Style for the row. Is inherited to cells.
|
26
|
+
attr_reader :style
|
27
27
|
=begin rdoc
|
28
28
|
Add content to the Row.
|
29
29
|
=end
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
30
|
+
def << (insertion)
|
31
|
+
case insertion
|
32
|
+
when Cell
|
33
|
+
@columns << insertion
|
34
|
+
when Array
|
35
|
+
insertion.each{|value|
|
36
|
+
@columns << Cell.new(value)
|
37
|
+
}
|
38
|
+
when Hash
|
39
|
+
@log.error("Excel::Row: Hashs not supported")
|
40
|
+
raise ArgumentError, "Excel::Row#<<: Hashs not supported"
|
41
|
+
#fixme: if connectuion to worksheet, use columns.
|
42
|
+
when Row, Worksheet, Workbook
|
43
|
+
raise ArgumentError, "Excel::Row#<<: #{insertion.class} not supported"
|
44
|
+
else
|
45
|
+
@columns << Cell.new(insertion)
|
46
|
+
end
|
47
|
+
self #for usage like " << (Excel::Row.new() << 'a')"
|
48
|
+
end
|
49
49
|
=begin rdoc
|
50
50
|
Build the xml a work sheet row,
|
51
51
|
|
@@ -53,23 +53,45 @@ ns must be a method-object to implement the namespace definitions.
|
|
53
53
|
|
54
54
|
Format options (bold, italic, colors) are forwarded to cells.
|
55
55
|
=end
|
56
|
-
|
57
|
-
|
56
|
+
def to_xml(xmlbuilder, ns)
|
57
|
+
raise EmptyError, "Row without content" if @columns.empty?
|
58
|
+
|
59
|
+
#Build options
|
60
|
+
row_options = {}
|
61
|
+
if @style
|
62
|
+
row_options[ns.call('StyleID')] = @style.style_id
|
63
|
+
end
|
64
|
+
|
65
|
+
xmlbuilder[ns.call].Row( row_options ){
|
66
|
+
@columns.each{|column|
|
67
|
+
column.to_xml(xmlbuilder, ns, self)
|
68
|
+
}
|
69
|
+
}
|
70
|
+
end #to_xml
|
71
|
+
=begin rdoc
|
72
|
+
Build the row for csv.
|
73
|
+
|
74
|
+
Details on options see Rexcel::Worksheet#to_csv
|
75
|
+
=end
|
76
|
+
def to_csv(options = {})
|
77
|
+
|
78
|
+
@log.debug("Prepare csv-row")
|
79
|
+
#Set options defaults
|
80
|
+
options[:sep] ||= ";"
|
81
|
+
|
82
|
+
csv_row = []
|
83
|
+
self.columns.each_with_index{|col, colnum|
|
84
|
+
@log.debug("Prepare cell #{colnum} for csv-output") if @log.debug?
|
85
|
+
csv_row << col.to_csv()
|
86
|
+
raise ArgumentError, "Cell separator <#{options[:sep]}> is part of the data #{csv_row.last.inspect}" if csv_row.last.to_s.include?(options[:sep])
|
87
|
+
|
88
|
+
}#columns in row
|
89
|
+
|
90
|
+
csv_row.join(options[:sep])
|
91
|
+
end #build_excel_csv
|
58
92
|
|
59
|
-
|
60
|
-
|
61
|
-
if @style
|
62
|
-
row_options[ns.call('StyleID')] = @style.style_id
|
93
|
+
def inspect
|
94
|
+
"#<Excel::Row:#{object_id} #{columns.size} Columns>"
|
63
95
|
end
|
64
|
-
|
65
|
-
xmlbuilder[ns.call].Row( row_options ){
|
66
|
-
@columns.each{|column|
|
67
|
-
column.to_xml(xmlbuilder, ns, self)
|
68
|
-
}
|
69
|
-
}
|
70
|
-
end #to_xml
|
71
|
-
def inspect
|
72
|
-
"#<Excel::Row:#{object_id} #{columns.size} Columns>"
|
73
|
-
end
|
74
|
-
end #class Row
|
96
|
+
end #class Row
|
75
97
|
end #module Excel
|
data/lib/rexcel/workbook.rb
CHANGED
@@ -68,69 +68,144 @@ If no actual worksheet is available, a new worksheet i created.
|
|
68
68
|
=begin rdoc
|
69
69
|
Build the workbook via OLE.
|
70
70
|
|
71
|
-
|
71
|
+
The excel may be build in two ways.
|
72
72
|
|
73
|
+
* from internal data (previous with Workbook#<< added data)
|
74
|
+
* from a xml file
|
75
|
+
|
76
|
+
==Internal data
|
73
77
|
If no xml-source is available, the internal data are taken to
|
74
78
|
build the xls.
|
79
|
+
|
75
80
|
This may take some time...
|
76
81
|
|
82
|
+
==Source-reference
|
83
|
+
If a reference to a source is available,
|
84
|
+
this reference is used to build the Excel Workbook.
|
85
|
+
|
86
|
+
This source reference may be
|
87
|
+
* xml
|
88
|
+
* csv
|
89
|
+
|
90
|
+
You may first save the data as xml and then
|
91
|
+
use the xml to build a xls(x).
|
92
|
+
|
77
93
|
For big files, it is recommended to use the way via xml.
|
78
94
|
|
79
95
|
=end
|
80
|
-
def prepare_xls(
|
96
|
+
def prepare_xls(source_reference = nil)
|
81
97
|
|
82
98
|
wb = nil
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
99
|
+
case source_reference
|
100
|
+
when /xml$/
|
101
|
+
if File.exist?(source_reference)
|
102
|
+
@log.info("Use existing #{source_reference}")
|
103
|
+
wb = Excel.instance.xl.Workbooks.OpenXML(File.expand_path(source_reference))
|
104
|
+
else
|
105
|
+
@log.fatal("#{__method__} #{source_reference} missing")
|
106
|
+
raise ArgumentError, 'Source data missing'
|
107
|
+
end
|
108
|
+
when /csv$/
|
109
|
+
if File.exist?(source_reference)
|
110
|
+
@log.info("Use existing #{source_reference}")
|
111
|
+
wb = Excel.instance.xl.Workbooks.Open(File.expand_path(source_reference))
|
112
|
+
else
|
113
|
+
@log.fatal("#{__method__} #{source_reference} missing")
|
114
|
+
raise ArgumentError, 'Source data missing'
|
115
|
+
end
|
116
|
+
|
117
|
+
when nil
|
118
|
+
@log.info("Create xls-Workbook")
|
119
|
+
wb = Excel.instance.xl.Workbooks.Add #Includes 3 worksheets
|
120
|
+
#Delete unused sheets.
|
121
|
+
wb.ActiveSheet.delete
|
122
|
+
wb.ActiveSheet.delete
|
123
|
+
|
124
|
+
@log.info("Add styles to document") unless @styles.empty?
|
125
|
+
@styles.each{|name, style|
|
126
|
+
@log.debug("Add style #{name} to document")
|
127
|
+
style.to_xls(wb)
|
128
|
+
}
|
129
|
+
|
130
|
+
first = true
|
131
|
+
#wb.Worksheets.Add appends new worksheets at begin -> reverse for creation to get right sequence.
|
132
|
+
@worksheets.reverse.each{|worksheet|
|
133
|
+
if first
|
134
|
+
worksheet.to_xls(wb.ActiveSheet)
|
135
|
+
first = false
|
136
|
+
else
|
137
|
+
worksheet.to_xls(wb.Worksheets.Add)
|
138
|
+
end
|
139
|
+
}
|
140
|
+
end #case source_reference
|
116
141
|
wb
|
117
142
|
end
|
118
143
|
|
119
144
|
=begin rdoc
|
120
145
|
Save the workbook.
|
121
146
|
|
122
|
-
|
123
|
-
* xls
|
124
|
-
* xlsx
|
125
|
-
* xlm (Microsoft Office Word 2003 XML Format)
|
147
|
+
The filename must end with
|
148
|
+
* .xls
|
149
|
+
* .xlsx
|
150
|
+
* .xlm (Microsoft Office Word 2003 XML Format)
|
151
|
+
* .csv
|
152
|
+
|
153
|
+
Examples:
|
154
|
+
WB = Excel::Workbook.new()
|
155
|
+
# fill WB
|
156
|
+
WB.save('testfile.xls')
|
157
|
+
WB.save('testfile.xlsx')
|
158
|
+
WB.save('testfile.xml')
|
126
159
|
|
127
|
-
|
160
|
+
|
161
|
+
==Save with reference to xml file
|
162
|
+
You may create the Excel file based on a xml file.
|
128
163
|
|
129
164
|
The way Ruby Workbook -> xml -> xls[x] is faster then the
|
130
165
|
direct xls[x] generation.
|
166
|
+
|
167
|
+
Example:
|
168
|
+
WB = Excel::Workbook.new()
|
169
|
+
# fill WB
|
170
|
+
WB.save('testfile.xml')
|
171
|
+
WB.save('testfile_xml.xls', 'testfile.xml')
|
172
|
+
|
173
|
+
==Save with reference to csv file
|
174
|
+
You may create the Excel file based on a csv file.
|
175
|
+
|
176
|
+
* This method is only possible for workbooks with only one worksheets.
|
177
|
+
* Attention! You may get problems with field conversion.
|
178
|
+
* Therefor the way Ruby Workbook -> xml -> xls[x] is recommended.
|
179
|
+
|
180
|
+
Example:
|
181
|
+
|
182
|
+
WB = Excel::Workbook.new()
|
183
|
+
# fill WB
|
184
|
+
WB.save('testfile.csv')
|
185
|
+
WB.save('testfile_xml.xls', 'testfile.csv')
|
186
|
+
|
187
|
+
==Save with implicit reference files
|
188
|
+
Instead the explicit usage of xml/csv-file, the save command
|
189
|
+
can do it implicit
|
190
|
+
|
191
|
+
Example:
|
192
|
+
WB = Excel::Workbook.new()
|
193
|
+
# fill WB
|
194
|
+
WB.save('testfile_xml.xls', :via_xml)
|
195
|
+
WB.save('testfile_xml.xls', :via_csv)
|
196
|
+
|
131
197
|
=end
|
132
|
-
def save(path,
|
198
|
+
def save(path, source_reference = nil)
|
133
199
|
|
200
|
+
case source_reference
|
201
|
+
when :via_xml
|
202
|
+
source_reference = path.sub(/\.[^\.]+/, '.xml')
|
203
|
+
save(source_reference)
|
204
|
+
when :via_csv
|
205
|
+
source_reference = path.sub(/\.[^\.]+/, '.csv')
|
206
|
+
save(source_reference)
|
207
|
+
end
|
208
|
+
|
134
209
|
@log.info("Save #{path}")
|
135
210
|
expath = File.expand_path(path) #Excel needs absolute path
|
136
211
|
expath.gsub!(/\//, '\\')# Save the workbook. / must be \
|
@@ -138,12 +213,12 @@ direct xls[x] generation.
|
|
138
213
|
#different formats, see http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.xlfileformat.aspx
|
139
214
|
case path
|
140
215
|
when /xlsx$/
|
141
|
-
wb = prepare_xls(
|
216
|
+
wb = prepare_xls(source_reference)
|
142
217
|
@log.info("Save #{path}")
|
143
218
|
wb.SaveAs(expath, 51)
|
144
219
|
wb.Close
|
145
220
|
when /xls$/
|
146
|
-
wb = prepare_xls(
|
221
|
+
wb = prepare_xls(source_reference)
|
147
222
|
@log.info("Save #{path}")
|
148
223
|
wb.SaveAs(expath, -4143 ) #excel97_2003_format
|
149
224
|
wb.Close
|
@@ -160,6 +235,10 @@ The namespace must be used before its definition (Tag Workbook)
|
|
160
235
|
File.open(path, 'w'){|f|
|
161
236
|
f << build_excel_xml(ns)
|
162
237
|
}
|
238
|
+
when /csv$/
|
239
|
+
File.open(path, 'w'){|f|
|
240
|
+
f << build_excel_csv()
|
241
|
+
}
|
163
242
|
else
|
164
243
|
@log.fatal("Wrong filename, no xls/xlsx (#{path})")
|
165
244
|
raise ArgumentError, "Wrong filename, no xls/xlsx (#{path})"
|
@@ -224,6 +303,25 @@ Descriptions and examples:
|
|
224
303
|
).strip.gsub(/<(\/?)Workbook/, '<\1%s:Workbook' % namespace )
|
225
304
|
|
226
305
|
end #build_excel_xml
|
306
|
+
=begin rdoc
|
307
|
+
Build the csv for Excel.
|
308
|
+
|
309
|
+
Details on options see Rexcel::Worksheet#to_csv and Rexcel::Cell#to_csv.
|
310
|
+
=end
|
311
|
+
def build_excel_csv(options = {})
|
312
|
+
|
313
|
+
csv = []
|
314
|
+
count = 0 #counter for filled worksheets
|
315
|
+
@log.debug("Prepare csv")
|
316
|
+
@worksheets.each{|worksheet|
|
317
|
+
next if worksheet.rows.empty?
|
318
|
+
csv << worksheet.to_csv(options)
|
319
|
+
count += 1
|
320
|
+
} #Worksheets
|
321
|
+
|
322
|
+
raise ArgumentError, "csv not possible for multiple worksheets" if count > 1
|
323
|
+
csv.join()
|
324
|
+
end #build_excel_csv
|
227
325
|
|
228
326
|
end #class Workbook
|
229
327
|
end #module Excel
|