spreadsheet 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/GUIDE.txt +209 -0
- data/History.txt +8 -0
- data/LICENSE.txt +619 -0
- data/Manifest.txt +46 -0
- data/README.txt +54 -0
- data/Rakefile +15 -0
- data/lib/parseexcel.rb +27 -0
- data/lib/parseexcel/parseexcel.rb +75 -0
- data/lib/parseexcel/parser.rb +11 -0
- data/lib/spreadsheet.rb +79 -0
- data/lib/spreadsheet/datatypes.rb +99 -0
- data/lib/spreadsheet/encodings.rb +49 -0
- data/lib/spreadsheet/excel.rb +75 -0
- data/lib/spreadsheet/excel/error.rb +26 -0
- data/lib/spreadsheet/excel/internals.rb +322 -0
- data/lib/spreadsheet/excel/internals/biff5.rb +17 -0
- data/lib/spreadsheet/excel/internals/biff8.rb +19 -0
- data/lib/spreadsheet/excel/offset.rb +37 -0
- data/lib/spreadsheet/excel/reader.rb +798 -0
- data/lib/spreadsheet/excel/reader/biff5.rb +22 -0
- data/lib/spreadsheet/excel/reader/biff8.rb +168 -0
- data/lib/spreadsheet/excel/row.rb +67 -0
- data/lib/spreadsheet/excel/sst_entry.rb +45 -0
- data/lib/spreadsheet/excel/workbook.rb +76 -0
- data/lib/spreadsheet/excel/worksheet.rb +85 -0
- data/lib/spreadsheet/excel/writer.rb +1 -0
- data/lib/spreadsheet/excel/writer/biff8.rb +66 -0
- data/lib/spreadsheet/excel/writer/format.rb +270 -0
- data/lib/spreadsheet/excel/writer/workbook.rb +586 -0
- data/lib/spreadsheet/excel/writer/worksheet.rb +556 -0
- data/lib/spreadsheet/font.rb +86 -0
- data/lib/spreadsheet/format.rb +172 -0
- data/lib/spreadsheet/formula.rb +9 -0
- data/lib/spreadsheet/row.rb +87 -0
- data/lib/spreadsheet/workbook.rb +120 -0
- data/lib/spreadsheet/worksheet.rb +215 -0
- data/lib/spreadsheet/writer.rb +29 -0
- data/test/data/test_copy.xls +0 -0
- data/test/data/test_version_excel5.xls +0 -0
- data/test/data/test_version_excel95.xls +0 -0
- data/test/data/test_version_excel97.xls +0 -0
- data/test/excel/row.rb +29 -0
- data/test/font.rb +163 -0
- data/test/integration.rb +1021 -0
- data/test/workbook.rb +21 -0
- data/test/worksheet.rb +62 -0
- metadata +113 -0
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'spreadsheet/datatypes'
|
2
|
+
require 'spreadsheet/encodings'
|
3
|
+
|
4
|
+
module Spreadsheet
|
5
|
+
##
|
6
|
+
# Font formatting data
|
7
|
+
class Font
|
8
|
+
include Datatypes
|
9
|
+
include Encodings
|
10
|
+
attr_accessor :name
|
11
|
+
##
|
12
|
+
# You can set the following boolean Font attributes
|
13
|
+
# * #italic
|
14
|
+
# * #strikeout
|
15
|
+
# * #outline
|
16
|
+
# * #shadow
|
17
|
+
boolean :italic, :strikeout, :outline, :shadow
|
18
|
+
##
|
19
|
+
# Font color
|
20
|
+
colors :color
|
21
|
+
##
|
22
|
+
# Font weight
|
23
|
+
# Valid values: :normal, :bold or any positive Integer.
|
24
|
+
# In Excel:
|
25
|
+
# 100 <= weight <= 1000
|
26
|
+
# :bold => 700
|
27
|
+
# :normal => 400
|
28
|
+
# Default: :normal
|
29
|
+
enum :weight, :normal, :bold, Integer, :bold => :b
|
30
|
+
##
|
31
|
+
# Escapement
|
32
|
+
# Valid values: :normal, :superscript or :subscript.
|
33
|
+
# Default: :normal
|
34
|
+
enum :escapement, :normal, :superscript, :subscript,
|
35
|
+
:subscript => :sub,
|
36
|
+
:superscript => :super
|
37
|
+
# Font size
|
38
|
+
# Valid values: Any positive Integer.
|
39
|
+
# Default: 10
|
40
|
+
enum :size, 10, Numeric
|
41
|
+
# Underline type
|
42
|
+
# Valid values: :none, :single, :double, :single_accounting and
|
43
|
+
# :double_accounting.
|
44
|
+
# Default: :none
|
45
|
+
enum :underline, :none, :single, :double,
|
46
|
+
:single_accounting, :double_accounting,
|
47
|
+
:single => true
|
48
|
+
# Font Family
|
49
|
+
# Valid values: :none, :roman, :swiss, :modern, :script, :decorative
|
50
|
+
# Default: :none
|
51
|
+
enum :family, :none, :roman, :swiss, :modern, :script, :decorative
|
52
|
+
# Font Family
|
53
|
+
# Valid values: :default, :iso_latin1, :symbol, :apple_roman, :shift_jis,
|
54
|
+
# :korean_hangul, :korean_johab, :chinese_simplified,
|
55
|
+
# :chinese_traditional, :greek, :turkish, :vietnamese,
|
56
|
+
# :hebrew, :arabic, :cyrillic, :thai, :iso_latin2, :oem_latin1
|
57
|
+
# Default: :default
|
58
|
+
enum :encoding, :default, :iso_latin1, :symbol, :apple_roman, :shift_jis,
|
59
|
+
:korean_hangul, :korean_johab, :chinese_simplified,
|
60
|
+
:chinese_traditional, :greek, :turkish, :vietnamese,
|
61
|
+
:hebrew, :arabic, :cyrillic, :thai, :iso_latin2, :oem_latin1
|
62
|
+
def initialize name
|
63
|
+
self.name = name
|
64
|
+
@color = :text
|
65
|
+
end
|
66
|
+
##
|
67
|
+
# Sets #weight to :bold if(_bool_), :normal otherwise.
|
68
|
+
def bold= bool
|
69
|
+
self.weight = bool ? :bold : nil
|
70
|
+
end
|
71
|
+
def key # :nodoc:
|
72
|
+
key = @name.dup
|
73
|
+
key << '_' << size.to_s
|
74
|
+
key << '_' << weight.to_s
|
75
|
+
key << '_italic' if italic?
|
76
|
+
key << '_strikeout' if strikeout?
|
77
|
+
key << '_outline' if outline?
|
78
|
+
key << '_shadow' if shadow?
|
79
|
+
key << '_' << escapement.to_s
|
80
|
+
key << '_' << underline.to_s
|
81
|
+
key << '_' << color.to_s
|
82
|
+
key << '_' << family.to_s
|
83
|
+
key << '_' << encoding.to_s
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,172 @@
|
|
1
|
+
require 'spreadsheet/datatypes'
|
2
|
+
require 'spreadsheet/encodings'
|
3
|
+
require 'spreadsheet/font'
|
4
|
+
|
5
|
+
module Spreadsheet
|
6
|
+
##
|
7
|
+
# Formatting data
|
8
|
+
class Format
|
9
|
+
include Encodings
|
10
|
+
include Datatypes
|
11
|
+
##
|
12
|
+
# You can set the following boolean attributes:
|
13
|
+
# #cross_down:: Draws a Line from the top-left to the bottom-right
|
14
|
+
# corner of a cell.
|
15
|
+
# #cross_up:: Draws a Line from the bottom-left to the top-right
|
16
|
+
# corner of a cell.
|
17
|
+
# #hidden:: The cell is hidden.
|
18
|
+
# #locked:: The cell is locked.
|
19
|
+
# #merge_range:: The cell is in a merged range.
|
20
|
+
# #shrink:: Shrink the contents to fit the cell.
|
21
|
+
# #text_justlast:: Force the last line of a cell to be justified. This
|
22
|
+
# probably makes sense if horizontal_align = :justify
|
23
|
+
# #left:: Draw a border to the left of the cell.
|
24
|
+
# #right:: Draw a border to the right of the cell.
|
25
|
+
# #top:: Draw a border at the top of the cell.
|
26
|
+
# #bottom:: Draw a border at the bottom of the cell.
|
27
|
+
# #rotation_stacked:: Characters in the cell are stacked on top of each
|
28
|
+
# other. Excel will ignore other rotation values if
|
29
|
+
# this is set.
|
30
|
+
boolean :cross_down, :cross_up, :hidden, :locked,
|
31
|
+
:merge_range, :shrink, :text_justlast, :text_wrap, :left, :right,
|
32
|
+
:top, :bottom, :rotation_stacked
|
33
|
+
##
|
34
|
+
# Color attributes
|
35
|
+
colors :bottom_color, :top_color, :left_color, :right_color,
|
36
|
+
:bg_color, :pattern_fg_color, :pattern_bg_color,
|
37
|
+
:diagonal_color
|
38
|
+
##
|
39
|
+
# Text direction
|
40
|
+
# Valid values: :context, :left_to_right, :right_to_left
|
41
|
+
# Default: :context
|
42
|
+
enum :text_direction, :context, :left_to_right, :right_to_left,
|
43
|
+
:left_to_right => [:ltr, :l2r],
|
44
|
+
:right_to_left => [:rtl, :r2l]
|
45
|
+
alias :reading_order :text_direction
|
46
|
+
alias :reading_order= :text_direction=
|
47
|
+
##
|
48
|
+
# Indentation level
|
49
|
+
enum :indent_level, 0, Integer
|
50
|
+
alias :indent :indent_level
|
51
|
+
alias :indent= :indent_level=
|
52
|
+
##
|
53
|
+
# Horizontal alignment
|
54
|
+
# Valid values: :default, :left, :center, :right, :fill, :justify, :merge,
|
55
|
+
# :distributed
|
56
|
+
# Default: :default
|
57
|
+
enum :horizontal_align, :default, :left, :center, :right, :fill, :justify,
|
58
|
+
:merge, :distributed,
|
59
|
+
:center => :centre,
|
60
|
+
:merge => [ :center_across, :centre_across ],
|
61
|
+
:distributed => :equal_space
|
62
|
+
##
|
63
|
+
# Vertical alignment
|
64
|
+
# Valid values: :bottom, :top, :middle, :justify, :distributed
|
65
|
+
# Default: :bottom
|
66
|
+
enum :vertical_align, :bottom, :top, :middle, :justify, :distributed,
|
67
|
+
:distributed => [:vdistributed, :vequal_space, :equal_space],
|
68
|
+
:justify => :vjustify,
|
69
|
+
:middle => [:vcenter, :vcentre, :center, :centre]
|
70
|
+
attr_accessor :font, :number_format, :name, :pattern, :used_merge
|
71
|
+
##
|
72
|
+
# Text rotation
|
73
|
+
attr_reader :rotation
|
74
|
+
def initialize opts={}
|
75
|
+
@font = Font.new client("Arial", 'UTF8')
|
76
|
+
@number_format = client 'General', 'UTF8'
|
77
|
+
@rotation = 0
|
78
|
+
@bg_color = :pattern_bg
|
79
|
+
@pattern = 0
|
80
|
+
@bottom_color = :border
|
81
|
+
@top_color = :border
|
82
|
+
@left_color = :border
|
83
|
+
@right_color = :border
|
84
|
+
@diagonal_color = :border
|
85
|
+
@pattern_fg_color = :border
|
86
|
+
@pattern_bg_color = :pattern_bg
|
87
|
+
# Temp code to prevent merged formats in non-merged cells.
|
88
|
+
@used_merge = 0
|
89
|
+
opts.each do |key, val|
|
90
|
+
writer = "#{key}="
|
91
|
+
if @font.respond_to? writer
|
92
|
+
@font.send writer, val
|
93
|
+
else
|
94
|
+
self.send writer, val
|
95
|
+
end
|
96
|
+
end
|
97
|
+
yield self if block_given?
|
98
|
+
end
|
99
|
+
##
|
100
|
+
# Combined method for both horizontal and vertical alignment. Sets the
|
101
|
+
# first valid value (e.g. Format#align = :justify only sets the horizontal
|
102
|
+
# alignment. Use one of the aliases prefixed with :v if you need to
|
103
|
+
# disambiguate.)
|
104
|
+
#
|
105
|
+
# This is essentially a backward-compatibility method and may be removed at
|
106
|
+
# some point in the future.
|
107
|
+
def align= location
|
108
|
+
self.horizontal_align = location
|
109
|
+
rescue ArgumentError
|
110
|
+
self.vertical_align = location rescue ArgumentError
|
111
|
+
end
|
112
|
+
##
|
113
|
+
# Returns an Array containing the status of the four borders:
|
114
|
+
# bottom, top, right, left
|
115
|
+
def border
|
116
|
+
[bottom,top,right,left]
|
117
|
+
end
|
118
|
+
##
|
119
|
+
# Activate or deactivate all four borders (left, right, top, bottom)
|
120
|
+
def border=(boolean)
|
121
|
+
[:bottom=, :top=, :right=, :left=].each do |writer| send writer, boolean end
|
122
|
+
end
|
123
|
+
##
|
124
|
+
# Returns an Array containing the colors of the four borders:
|
125
|
+
# bottom, top, right, left
|
126
|
+
def border_color
|
127
|
+
[@bottom_color,@top_color,@left_color,@right_color]
|
128
|
+
end
|
129
|
+
##
|
130
|
+
# Set all four border colors to _color_ (left, right, top, bottom)
|
131
|
+
def border_color=(color)
|
132
|
+
[:bottom_color=, :top_color=, :right_color=, :left_color=].each do |writer|
|
133
|
+
send writer, color end
|
134
|
+
end
|
135
|
+
##
|
136
|
+
# Set the Text rotation
|
137
|
+
# Valid values: Integers from -90 to 90,
|
138
|
+
# or :stacked (sets #rotation_stacked to true)
|
139
|
+
def rotation=(rot)
|
140
|
+
if rot.to_s.downcase == 'stacked'
|
141
|
+
@rotation_stacked = true
|
142
|
+
@rotation = 0
|
143
|
+
elsif rot.kind_of?(Integer)
|
144
|
+
@rotation_stacked = false
|
145
|
+
@rotation = rot % 360
|
146
|
+
else
|
147
|
+
raise TypeError, "rotation value must be an Integer or the String 'stacked'"
|
148
|
+
end
|
149
|
+
end
|
150
|
+
##
|
151
|
+
# Backward compatibility method. May disappear at some point in the future.
|
152
|
+
def center_across!
|
153
|
+
self.horizontal_align = :merge
|
154
|
+
end
|
155
|
+
alias :merge! :center_across!
|
156
|
+
##
|
157
|
+
# Is the cell formatted as a Date?
|
158
|
+
def date?
|
159
|
+
!!/[YMD]/.match(@number_format.to_s)
|
160
|
+
end
|
161
|
+
##
|
162
|
+
# Is the cell formatted as a DateTime?
|
163
|
+
def datetime?
|
164
|
+
!!/([YMD].*[hms])|([hms].*[YMD])/.match(@number_format.to_s)
|
165
|
+
end
|
166
|
+
##
|
167
|
+
# Is the cell formatted as a Time?
|
168
|
+
def time?
|
169
|
+
!!/[hms]/.match(@number_format.to_s)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module Spreadsheet
|
2
|
+
##
|
3
|
+
# Formula implementation. At the moment this is just a placeholder.
|
4
|
+
# You may access the last calculated #value, other attributes are needed for
|
5
|
+
# writing the Formula back into modified Excel Files.
|
6
|
+
class Formula
|
7
|
+
attr_accessor :data, :value, :shared
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module Spreadsheet
|
2
|
+
##
|
3
|
+
# The Row class. Encapsulates Cell data and formatting.
|
4
|
+
# Since Row is a subclass of Array, you may use all the standard Array methods
|
5
|
+
# to manipulate a Row.
|
6
|
+
# By convention, Row#at will give you raw values, while Row#[] may be
|
7
|
+
# overridden to return enriched data if necessary (see also the Date- and
|
8
|
+
# DateTime-handling in Excel::Row#[]
|
9
|
+
#
|
10
|
+
# Useful Attributes are:
|
11
|
+
# #idx:: The 0-based index of this Row in its Worksheet.
|
12
|
+
# #formats:: A parallel array containing Formatting information for
|
13
|
+
# all cells stored in a Row.
|
14
|
+
# #default_format:: The default Format used when writing a Cell if no explicit
|
15
|
+
# Format is stored in #formats for the cell.
|
16
|
+
# #height:: The height of this Row in points (defaults to 12).
|
17
|
+
class Row < Array
|
18
|
+
class << self
|
19
|
+
def updater *keys
|
20
|
+
keys.each do |key|
|
21
|
+
define_method key do |*args|
|
22
|
+
res = super
|
23
|
+
@worksheet.row_updated @idx, self if @worksheet
|
24
|
+
res
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
attr_reader :formats, :default_format
|
30
|
+
attr_accessor :idx, :height, :worksheet
|
31
|
+
updater :[]=, :clear, :concat, :delete, :delete_if, :fill, :insert, :map!,
|
32
|
+
:pop, :push, :reject!, :replace, :reverse!, :shift, :slice!,
|
33
|
+
:sort!, :uniq!, :unshift
|
34
|
+
def initialize worksheet, idx, cells=[]
|
35
|
+
@worksheet = worksheet
|
36
|
+
@idx = idx
|
37
|
+
while !cells.empty? && !cells.last
|
38
|
+
cells.pop
|
39
|
+
end
|
40
|
+
super cells
|
41
|
+
@first_used ||= index_of_first self
|
42
|
+
@first_unused ||= size
|
43
|
+
@formats = []
|
44
|
+
@height = 12
|
45
|
+
end
|
46
|
+
##
|
47
|
+
# Set the default Format used when writing a Cell if no explicit Format is
|
48
|
+
# stored for the cell.
|
49
|
+
def default_format= format
|
50
|
+
@worksheet.add_format format
|
51
|
+
@default_format = format
|
52
|
+
end
|
53
|
+
##
|
54
|
+
# #first_unused (really last used + 1) - the 0-based index of the first of
|
55
|
+
# all remaining contiguous blank Cells.
|
56
|
+
alias :first_unused :size
|
57
|
+
##
|
58
|
+
# #first_used the 0-based index of the first non-blank Cell.
|
59
|
+
def first_used
|
60
|
+
index_of_first self
|
61
|
+
end
|
62
|
+
##
|
63
|
+
# The Format for the Cell at _idx_ (0-based), or default_format
|
64
|
+
# if no Format is set.
|
65
|
+
def format idx
|
66
|
+
@formats[idx] || @default_format
|
67
|
+
end
|
68
|
+
##
|
69
|
+
# Set the Format for the Cell at _idx_ (0-based).
|
70
|
+
def set_format idx, fmt
|
71
|
+
@formats[idx] = fmt
|
72
|
+
@worksheet.add_format fmt
|
73
|
+
@worksheet.row_updated @idx, self if @worksheet
|
74
|
+
fmt
|
75
|
+
end
|
76
|
+
def inspect
|
77
|
+
variables = instance_variables.collect do |name|
|
78
|
+
"%s=%s" % [name, instance_variable_get(name)]
|
79
|
+
end.join(' ')
|
80
|
+
sprintf "#<%s:0x%014x %s %s>", self.class, object_id, variables, super
|
81
|
+
end
|
82
|
+
private
|
83
|
+
def index_of_first ary # :nodoc:
|
84
|
+
ary.index(ary.find do |elm| elm end)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'spreadsheet/format'
|
2
|
+
require 'spreadsheet/encodings'
|
3
|
+
|
4
|
+
module Spreadsheet
|
5
|
+
##
|
6
|
+
# The Workbook class represents a Spreadsheet-Document and is the entry point
|
7
|
+
# for all Spreadsheet manipulation.
|
8
|
+
#
|
9
|
+
# Interesting Attributes:
|
10
|
+
# #default_format:: The default format used for all cells in this Workbook.
|
11
|
+
# that have no format set explicitly or in
|
12
|
+
# Row#default_format or Worksheet#default_format.
|
13
|
+
class Workbook
|
14
|
+
include Encodings
|
15
|
+
attr_reader :io, :worksheets, :formats, :fonts
|
16
|
+
attr_accessor :encoding, :version, :default_format
|
17
|
+
def initialize io = nil, opts={:default_format => Format.new}
|
18
|
+
@worksheets = []
|
19
|
+
@io = io
|
20
|
+
@fonts = []
|
21
|
+
@formats = []
|
22
|
+
if @default_format = opts[:default_format]
|
23
|
+
@formats.push @default_format
|
24
|
+
end
|
25
|
+
end
|
26
|
+
##
|
27
|
+
# Add a Font to the Workbook. Used by the parser. You should not need to
|
28
|
+
# use this Method.
|
29
|
+
def add_font font
|
30
|
+
@fonts.push font
|
31
|
+
end
|
32
|
+
##
|
33
|
+
# Add a Format to the Workbook. If you use Row#set_format, you should not
|
34
|
+
# need to use this Method.
|
35
|
+
def add_format format
|
36
|
+
@formats.push(format).uniq!
|
37
|
+
format
|
38
|
+
end
|
39
|
+
##
|
40
|
+
# Add a Worksheet to the Workbook.
|
41
|
+
def add_worksheet worksheet
|
42
|
+
worksheet.workbook = self
|
43
|
+
@worksheets.push worksheet
|
44
|
+
worksheet
|
45
|
+
end
|
46
|
+
##
|
47
|
+
# Create a new Worksheet in this Workbook.
|
48
|
+
# Used without options this creates a Worksheet with the name 'WorksheetN'
|
49
|
+
# where the new Worksheet is the Nth Worksheet in this Workbook.
|
50
|
+
#
|
51
|
+
# Use the option <em>:name => 'My pretty Name'</em> to override this
|
52
|
+
# behavior.
|
53
|
+
def create_worksheet opts = {}
|
54
|
+
opts[:name] ||= client("Worksheet#{@worksheets.size.next}", 'UTF8')
|
55
|
+
add_worksheet Worksheet.new(opts)
|
56
|
+
end
|
57
|
+
##
|
58
|
+
# The Font at _idx_
|
59
|
+
def font idx
|
60
|
+
@fonts[idx]
|
61
|
+
end
|
62
|
+
##
|
63
|
+
# The Format at _idx_, or - if _idx_ is a String -
|
64
|
+
# the Format with name == _idx_
|
65
|
+
def format idx
|
66
|
+
case idx
|
67
|
+
when Integer
|
68
|
+
@formats[idx] || @default_format
|
69
|
+
when String
|
70
|
+
@formats.find do |fmt| fmt.name == idx end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
def inspect
|
74
|
+
"#<#{self.class}:#{object_id} "
|
75
|
+
variables = (instance_variables - uninspect_variables).collect do |name|
|
76
|
+
"%s=%s" % [name, instance_variable_get(name)]
|
77
|
+
end.join(' ')
|
78
|
+
uninspect = uninspect_variables.collect do |name|
|
79
|
+
var = instance_variable_get name
|
80
|
+
"%s=%s[%i]" % [name, var.class, var.size]
|
81
|
+
end.join(' ')
|
82
|
+
sprintf "#<%s:0x%014x %s %s>", self.class, object_id,
|
83
|
+
variables, uninspect
|
84
|
+
end
|
85
|
+
def uninspect_variables # :nodoc:
|
86
|
+
%w{@formats @fonts @worksheets}
|
87
|
+
end
|
88
|
+
##
|
89
|
+
# The Worksheet at _idx_, or - if _idx_ is a String -
|
90
|
+
# the Worksheet with name == _idx_
|
91
|
+
def worksheet idx
|
92
|
+
case idx
|
93
|
+
when Integer
|
94
|
+
@worksheets[idx]
|
95
|
+
when String
|
96
|
+
@worksheets.find do |sheet| sheet.name == idx end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
##
|
100
|
+
# Write this Workbook to a File, IO Stream or Writer Object. The latter will
|
101
|
+
# make more sense once there are more than just an Excel-Writer available.
|
102
|
+
def write io_path_or_writer
|
103
|
+
if io_path_or_writer.is_a? Writer
|
104
|
+
io_path_or_writer.write self
|
105
|
+
else
|
106
|
+
writer(io_path_or_writer).write(self)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
##
|
110
|
+
# Returns a new instance of the default Writer class for this Workbook (can
|
111
|
+
# only be an Excel::Writer::Workbook at this time)
|
112
|
+
def writer io_or_path, type=Excel, version=self.version
|
113
|
+
if type == Excel
|
114
|
+
Excel::Writer::Workbook.new io_or_path
|
115
|
+
else
|
116
|
+
raise NotImplementedError, "No Writer defined for #{type}"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|