spreadsheet-excel 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES +124 -0
- data/CVS/Entries +10 -0
- data/CVS/Repository +1 -0
- data/CVS/Root +1 -0
- data/README +69 -0
- data/doc/CVS/Entries +3 -0
- data/doc/CVS/Repository +1 -0
- data/doc/CVS/Root +1 -0
- data/doc/format.txt +330 -0
- data/doc/spreadsheet.txt +178 -0
- data/examples/CVS/Entries +3 -0
- data/examples/CVS/Repository +1 -0
- data/examples/CVS/Root +1 -0
- data/examples/example_basic.rb +27 -0
- data/examples/example_format.rb +69 -0
- data/lib/CVS/Entries +1 -0
- data/lib/CVS/Repository +1 -0
- data/lib/CVS/Root +1 -0
- data/lib/spreadsheet/CVS/Entries +7 -0
- data/lib/spreadsheet/CVS/Repository +1 -0
- data/lib/spreadsheet/CVS/Root +1 -0
- data/lib/spreadsheet/biffwriter.rb +46 -0
- data/lib/spreadsheet/excel.rb +13 -0
- data/lib/spreadsheet/format.rb +359 -0
- data/lib/spreadsheet/olewriter.rb +178 -0
- data/lib/spreadsheet/workbook.rb +279 -0
- data/lib/spreadsheet/worksheet.rb +449 -0
- data/test/CVS/Entries +9 -0
- data/test/CVS/Repository +1 -0
- data/test/CVS/Root +1 -0
- data/test/perl_output/CVS/Entries +10 -0
- data/test/perl_output/CVS/Repository +1 -0
- data/test/perl_output/CVS/Root +1 -0
- data/test/perl_output/README +31 -0
- data/test/perl_output/f_font_biff +0 -0
- data/test/perl_output/f_font_key +1 -0
- data/test/perl_output/f_xf_biff +0 -0
- data/test/perl_output/ole_write_header +0 -0
- data/test/perl_output/ws_colinfo +1 -0
- data/test/perl_output/ws_store_dimensions +1 -0
- data/test/perl_output/ws_store_selection +1 -0
- data/test/perl_output/ws_store_window2 +1 -0
- data/test/tc_all.rb +6 -0
- data/test/tc_biff.rb +62 -0
- data/test/tc_excel.rb +26 -0
- data/test/tc_format.rb +133 -0
- data/test/tc_ole.rb +125 -0
- data/test/tc_workbook.rb +71 -0
- data/test/tc_worksheet.rb +142 -0
- data/test/ts_all.rb +9 -0
- metadata +103 -0
data/doc/spreadsheet.txt
ADDED
@@ -0,0 +1,178 @@
|
|
1
|
+
== Description
|
2
|
+
spreadsheet - A package for generating MS Excel (95) compatable files on
|
3
|
+
any platform.
|
4
|
+
|
5
|
+
Based on version .43 of John McNamara's Perl module
|
6
|
+
Spreadsheet::WriteExcel.
|
7
|
+
|
8
|
+
== Synopsis
|
9
|
+
require "spreadsheet/excel"
|
10
|
+
include Spreadsheet
|
11
|
+
|
12
|
+
workbook = Excel.new("test.xls")
|
13
|
+
|
14
|
+
# There are three ways to create a format
|
15
|
+
format = workbook.add_format(:color=>"blue",:bold=>1,:underline=>1)
|
16
|
+
|
17
|
+
format2 = Format.new(
|
18
|
+
:color => "green",
|
19
|
+
:bold => true,
|
20
|
+
:underline => true
|
21
|
+
)
|
22
|
+
workbook.add_format(format2)
|
23
|
+
|
24
|
+
format3 = Format.new{ |f|
|
25
|
+
f.color = "red"
|
26
|
+
f.bold = true
|
27
|
+
f.underline = true
|
28
|
+
}
|
29
|
+
workbook.add_format(format3)
|
30
|
+
|
31
|
+
worksheet1 = workbook.add_worksheet
|
32
|
+
worksheet2 = workbook.add_worksheet("Numbers")
|
33
|
+
worksheet3 = workbook.add_worksheet("Text")
|
34
|
+
|
35
|
+
worksheet1.write(0,0,"Hello",format)
|
36
|
+
worksheet1.write(1,1,["Matz","Larry","Guido"])
|
37
|
+
|
38
|
+
worksheet2.write(1,3,8876,format2)
|
39
|
+
worksheet2.write_column(4,4,[1,2,3])
|
40
|
+
|
41
|
+
worksheet3.write(2,2,"World",format3)
|
42
|
+
worksheet3.write(3,3,[[1,2,3],[4,5,6],[7,8,9]])
|
43
|
+
|
44
|
+
worksheet1.format_row(1,25,format1)
|
45
|
+
worksheet2.format_column(0..2,30,format2)
|
46
|
+
|
47
|
+
workbook.close
|
48
|
+
|
49
|
+
== Constants
|
50
|
+
VERSION
|
51
|
+
The current version number (a string).
|
52
|
+
|
53
|
+
== Classes
|
54
|
+
=== Excel
|
55
|
+
Excel.new(file_name)
|
56
|
+
Returns a workbook object. You may only have one workbook per file. A
|
57
|
+
".xls" extension for your +file_name+ is recommended but not enforced.
|
58
|
+
|
59
|
+
=== Workbook
|
60
|
+
Workbook#add_worksheet(sheet_name=nil)
|
61
|
+
Adds a worksheet named +sheet_name+ to the workbook object. If +sheet_name+
|
62
|
+
is nil it will default to 'Sheet1', 'Sheet2', etc. Returns a Worksheet
|
63
|
+
instance.
|
64
|
+
|
65
|
+
Workbook#add_format(format)
|
66
|
+
Adds the +format+ to the workbook. When included as part of the 'write'
|
67
|
+
method, the cells specified are formatted appropriately. Returns a Format
|
68
|
+
instance. Note that +format+ can be a format object, or a hash that is
|
69
|
+
automagically converted to a Format object.
|
70
|
+
|
71
|
+
See the synopsis above for different ways to add formats.
|
72
|
+
|
73
|
+
Workbook#close
|
74
|
+
Closes the workbook (and, hence, the IO stream). Be sure to do this.
|
75
|
+
|
76
|
+
=== Worksheet
|
77
|
+
Worksheet#write(row, column, value, format=nil)
|
78
|
+
Writes data to the cell you provide. If +value+ is an Array, the
|
79
|
+
write_row method is called internally.
|
80
|
+
|
81
|
+
If +value+ is a multi-dimensional array, then each element of the array
|
82
|
+
is written within its own row at the appropriate column. In other words,
|
83
|
+
it's written to the spreadsheet in the same manner you would visualize it.
|
84
|
+
|
85
|
+
If +format+ is provided, the cells are each formatted appropriately.
|
86
|
+
|
87
|
+
Worksheet#write_row(row, column, Array, format=nil)
|
88
|
+
Writes a row of data starting at +row+ and +column+ in a left to
|
89
|
+
right manner, with one array element per cell.
|
90
|
+
|
91
|
+
If +format+ is provided, formatting will be applied to each cell.
|
92
|
+
|
93
|
+
Worksheet#write_column(row, column, Array, format=nil)
|
94
|
+
Writes a column of data starting at +row+ and +column+ in a top to
|
95
|
+
bottom manner, with one array element per cell.
|
96
|
+
|
97
|
+
If +format+ is provided, formatting will be applied to each cell.
|
98
|
+
|
99
|
+
Worksheet#format_row(row, height=nil, format=nil, hidden=0, level=0)
|
100
|
+
Applies formatting for an entire row or Range of rows. In addition, you
|
101
|
+
can specify the row height. If you wish to apply row-level formatting
|
102
|
+
without modifying the height, simply pass nil as the second argument.
|
103
|
+
|
104
|
+
Note that this will override any previously defined cell formatting.
|
105
|
+
|
106
|
+
Worksheet#format_column(col, width=nil, format=nil, hidden=false, level=0)
|
107
|
+
Applies formatting for an entire row or Range of columns. In addition, you
|
108
|
+
can specify the column width. If you wish to apply column-level formatting
|
109
|
+
without modifying the width, simply pass nil as the second argument.
|
110
|
+
|
111
|
+
If +hidden+ is any value other than false or nil, the row will be hidden.
|
112
|
+
|
113
|
+
The +level+ value sets the outline level of the row. Adjacent rows with
|
114
|
+
the same outline level are grouped together into a single outline.
|
115
|
+
|
116
|
+
Note that this will override any previously defined cell formatting.
|
117
|
+
|
118
|
+
=== Format
|
119
|
+
Format.new
|
120
|
+
Format.new({key=>val, ...})
|
121
|
+
Format.new{ ... }
|
122
|
+
Creates a new Format object. See the Format documentation (format.txt)
|
123
|
+
for more details.
|
124
|
+
|
125
|
+
== Notes
|
126
|
+
This is a port of John McNamara's Spreadsheet::WriteExcel Perl module,
|
127
|
+
version 0.43 (approximately). There is no support for formulas or large
|
128
|
+
files yet.
|
129
|
+
|
130
|
+
This package creates files in the Excel 95 format.
|
131
|
+
|
132
|
+
== Design Changes
|
133
|
+
The only somewhat major change was to make OLEWriter a subclass of IO,
|
134
|
+
rather than store a filehandle as an attribute within the class. This
|
135
|
+
seems to have worked out fine.
|
136
|
+
|
137
|
+
The set_row() and set_column() methods were renamed as format_row()
|
138
|
+
and format_column(), respectively. All other methods are either
|
139
|
+
identical in name or very similar.
|
140
|
+
|
141
|
+
Other changes consisted mostly of minor code optimizations. Occasionally
|
142
|
+
I was more terse than John was (for better or for worse).
|
143
|
+
|
144
|
+
== Questions
|
145
|
+
Questions about MS Excel should be directed to Microsoft.
|
146
|
+
Questions about the MS Excel format should be directed to Microsoft.
|
147
|
+
Questions about why I use the hex values that I use should be directed to
|
148
|
+
John McNamara (jmcnamara at cpan dot org) or to Microsoft.
|
149
|
+
|
150
|
+
== Future Plans
|
151
|
+
Add support for files > 7MB - need help
|
152
|
+
Add formulas - need help
|
153
|
+
|
154
|
+
== Acknowledgements
|
155
|
+
Many thanks go to John McNamara for his tireless dedication to a very useful
|
156
|
+
and popular module. I also thank him for taking the time to answer some of
|
157
|
+
the questions I had for him while porting his code.
|
158
|
+
|
159
|
+
Thanks go to Jade Meskill for the outline patch.
|
160
|
+
|
161
|
+
== License
|
162
|
+
Ruby's
|
163
|
+
|
164
|
+
== Copyright
|
165
|
+
� 2002-2006, Daniel J. Berger
|
166
|
+
|
167
|
+
All Rights Reserved. This module is free software. It may be used,
|
168
|
+
redistributed and/or modified under the same terms as Ruby itself.
|
169
|
+
|
170
|
+
== Warranty
|
171
|
+
This package is provided "as is" and without any express or
|
172
|
+
implied warranties, including, without limitation, the implied
|
173
|
+
warranties of merchantability and fitness for a particular purpose.
|
174
|
+
|
175
|
+
== Author
|
176
|
+
Daniel J. Berger
|
177
|
+
djberg96 at gmail dot com
|
178
|
+
imperator on IRC (freenode)
|
@@ -0,0 +1 @@
|
|
1
|
+
RubySpreadsheet/examples
|
data/examples/CVS/Root
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
:ext:hwyss@rubyspreadsheet.cvs.sourceforge.net:/cvsroot/rubyspreadsheet
|
@@ -0,0 +1,27 @@
|
|
1
|
+
########################################################################
|
2
|
+
# example_basic.rb
|
3
|
+
#
|
4
|
+
# Simply run this and then open up basic_example.xls with MS Excel
|
5
|
+
# (or Gnumeric or whatever) to view the results.
|
6
|
+
########################################################################
|
7
|
+
base = File.basename(Dir.pwd)
|
8
|
+
if base == "examples" || base =~ /spreadsheet/i
|
9
|
+
Dir.chdir("..") if base == "examples"
|
10
|
+
$LOAD_PATH.unshift(Dir.pwd)
|
11
|
+
$LOAD_PATH.unshift(Dir.pwd + "/lib")
|
12
|
+
Dir.chdir("examples") rescue nil
|
13
|
+
end
|
14
|
+
|
15
|
+
require "spreadsheet/excel"
|
16
|
+
include Spreadsheet
|
17
|
+
|
18
|
+
puts "VERSION: " + Excel::VERSION
|
19
|
+
|
20
|
+
workbook = Excel.new("basic_example.xls")
|
21
|
+
|
22
|
+
worksheet = workbook.add_worksheet
|
23
|
+
|
24
|
+
worksheet.write(0, 0, "Hello")
|
25
|
+
worksheet.write(1, 0, ["Matz","Larry","Guido"])
|
26
|
+
|
27
|
+
workbook.close
|
@@ -0,0 +1,69 @@
|
|
1
|
+
########################################################################
|
2
|
+
# example_formula.rb
|
3
|
+
#
|
4
|
+
# Simply run this and then open up format_example.xls with MS Excel
|
5
|
+
# (or Gnumeric or whatever) to view the results.
|
6
|
+
########################################################################
|
7
|
+
base = File.basename(Dir.pwd)
|
8
|
+
if base == "examples" || base =~ /spreadsheet/i
|
9
|
+
Dir.chdir("..") if base == "examples"
|
10
|
+
$LOAD_PATH.unshift(Dir.pwd)
|
11
|
+
$LOAD_PATH.unshift(Dir.pwd + "/lib")
|
12
|
+
Dir.chdir("examples") rescue nil
|
13
|
+
end
|
14
|
+
|
15
|
+
require "spreadsheet/excel"
|
16
|
+
include Spreadsheet
|
17
|
+
|
18
|
+
version = Excel::VERSION
|
19
|
+
puts "VERSION: " + version
|
20
|
+
|
21
|
+
workbook = Excel.new("format_example.xls")
|
22
|
+
|
23
|
+
# Preferred way to add a format
|
24
|
+
f1 = workbook.add_format(:color=>"blue", :bold=>1, :italic=>true)
|
25
|
+
|
26
|
+
# Another way to add a format
|
27
|
+
f2 = Format.new(
|
28
|
+
:color => "red",
|
29
|
+
:bold => 1,
|
30
|
+
:italic => true
|
31
|
+
)
|
32
|
+
workbook.add_format(f2)
|
33
|
+
|
34
|
+
# Yet another way to add a format
|
35
|
+
# A tiny bit more overhead doing it this way
|
36
|
+
f3 = Format.new{ |f|
|
37
|
+
f.color = "green"
|
38
|
+
f.bold = 1
|
39
|
+
f.italic = true
|
40
|
+
}
|
41
|
+
workbook.add_format(f3)
|
42
|
+
|
43
|
+
f4 = Format.new(:num_format => "d mmm yyyy")
|
44
|
+
f5 = Format.new(:num_format => 0x0f)
|
45
|
+
workbook.add_format(f4)
|
46
|
+
workbook.add_format(f5)
|
47
|
+
|
48
|
+
worksheet1 = workbook.add_worksheet
|
49
|
+
worksheet2 = workbook.add_worksheet("number")
|
50
|
+
worksheet3 = workbook.add_worksheet("text")
|
51
|
+
|
52
|
+
worksheet1.write(0, 0, version)
|
53
|
+
worksheet1.write(0, 1, "Hello", f1)
|
54
|
+
worksheet1.write(1, 1, ["Matz","Larry","Guido"])
|
55
|
+
|
56
|
+
worksheet2.write_column(1, 1, [[1,2,3],[4,5,6],[7,8,9]])
|
57
|
+
worksheet2.write(0, 0, 8888, f2)
|
58
|
+
|
59
|
+
worksheet3.write(0, 0, 36892.521, f5)
|
60
|
+
|
61
|
+
worksheet1.format_row(4..5, 30, f1)
|
62
|
+
|
63
|
+
worksheet2.format_column(3..4, 25, f2)
|
64
|
+
|
65
|
+
worksheet1.write(5,0,"This should be blue")
|
66
|
+
|
67
|
+
worksheet2.write(0,4,"This should be red")
|
68
|
+
|
69
|
+
workbook.close
|
data/lib/CVS/Entries
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
D/spreadsheet////
|
data/lib/CVS/Repository
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
RubySpreadsheet/lib
|
data/lib/CVS/Root
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
:ext:hwyss@rubyspreadsheet.cvs.sourceforge.net:/cvsroot/rubyspreadsheet
|
@@ -0,0 +1,7 @@
|
|
1
|
+
/biffwriter.rb/1.1/Tue Oct 11 17:09:08 2005//
|
2
|
+
/excel.rb/1.4/Fri Feb 17 03:34:00 2006//
|
3
|
+
/format.rb/1.1/Tue Oct 11 17:09:08 2005//
|
4
|
+
/olewriter.rb/1.3/Mon Dec 5 02:03:48 2005//
|
5
|
+
/workbook.rb/1.4/Sun Feb 12 16:42:10 2006//
|
6
|
+
/worksheet.rb/1.2/Fri Feb 17 03:33:24 2006//
|
7
|
+
D
|
@@ -0,0 +1 @@
|
|
1
|
+
RubySpreadsheet/lib/spreadsheet
|
@@ -0,0 +1 @@
|
|
1
|
+
:ext:hwyss@rubyspreadsheet.cvs.sourceforge.net:/cvsroot/rubyspreadsheet
|
@@ -0,0 +1,46 @@
|
|
1
|
+
class BIFFWriter
|
2
|
+
|
3
|
+
BIFF_Version = 0x0500
|
4
|
+
BigEndian = [1].pack("I") == [1].pack("N")
|
5
|
+
|
6
|
+
attr_reader :byte_order, :data, :datasize
|
7
|
+
|
8
|
+
######################################################################
|
9
|
+
# The args here aren't used by BIFFWriter, but they are needed by its
|
10
|
+
# subclasses. I don't feel like creating multiple constructors.
|
11
|
+
######################################################################
|
12
|
+
def initialize(*args)
|
13
|
+
@data = ""
|
14
|
+
@datasize = 0
|
15
|
+
end
|
16
|
+
|
17
|
+
def prepend(*args)
|
18
|
+
@data = args.join << @data
|
19
|
+
@datasize += args.join.length
|
20
|
+
end
|
21
|
+
|
22
|
+
def append(*args)
|
23
|
+
@data << args.join
|
24
|
+
@datasize += args.join.length
|
25
|
+
end
|
26
|
+
|
27
|
+
def store_bof(type = 0x0005)
|
28
|
+
record = 0x0809
|
29
|
+
length = 0x0008
|
30
|
+
build = 0x096C
|
31
|
+
year = 0x07C9
|
32
|
+
|
33
|
+
header = [record,length].pack("vv")
|
34
|
+
data = [BIFF_Version,type,build,year].pack("vvvv")
|
35
|
+
|
36
|
+
prepend(header, data)
|
37
|
+
end
|
38
|
+
|
39
|
+
def store_eof
|
40
|
+
record = 0x000A
|
41
|
+
length = 0x0000
|
42
|
+
header = [record,length].pack("vv")
|
43
|
+
|
44
|
+
append(header)
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,359 @@
|
|
1
|
+
class Format
|
2
|
+
|
3
|
+
COLORS = {
|
4
|
+
'aqua' => 0x0F,
|
5
|
+
'black' => 0x08,
|
6
|
+
'blue' => 0x0C,
|
7
|
+
'brown' => 0x10,
|
8
|
+
'cyan' => 0x0F,
|
9
|
+
'fuchsia' => 0x0E,
|
10
|
+
'gray' => 0x17,
|
11
|
+
'grey' => 0x17,
|
12
|
+
'green' => 0x11,
|
13
|
+
'lime' => 0x0B,
|
14
|
+
'magenta' => 0x0E,
|
15
|
+
'navy' => 0x12,
|
16
|
+
'orange' => 0x1D,
|
17
|
+
'purple' => 0x24,
|
18
|
+
'red' => 0x0A,
|
19
|
+
'silver' => 0x16,
|
20
|
+
'white' => 0x09,
|
21
|
+
'yellow' => 0x0D
|
22
|
+
}
|
23
|
+
|
24
|
+
attr_accessor :xf_index
|
25
|
+
|
26
|
+
def initialize(args={}, xf_index=0)
|
27
|
+
defaults = {}
|
28
|
+
|
29
|
+
defaults.update(:color => 0x7FFF, :bold => 0x0190)
|
30
|
+
defaults.update(:fg_color => 0x40, :pattern => 0, :size => 10)
|
31
|
+
defaults.update(:bg_color => 0x41, :rotation => 0, :font => "Arial")
|
32
|
+
defaults.update(:underline => 0, :italic => 0, :top => 0)
|
33
|
+
defaults.update(:bottom => 0, :right => 0, :left => 0)
|
34
|
+
|
35
|
+
defaults.update(:font_index => 0, :font_family => 0)
|
36
|
+
defaults.update(:font_strikeout => 0, :font_script => 0)
|
37
|
+
defaults.update(:font_outline => 0, :left_color => 0)
|
38
|
+
defaults.update(:font_charset => 0, :right_color => 0)
|
39
|
+
defaults.update(:font_shadow => 0, :top_color => 0x40)
|
40
|
+
defaults.update(:text_v_align => 2, :bottom_color => 0x40)
|
41
|
+
defaults.update(:text_h_align => 0, :num_format => 0)
|
42
|
+
defaults.update(:text_justlast => 0, :text_wrap => 0)
|
43
|
+
|
44
|
+
########################################################################
|
45
|
+
# We must manually create accessors for these so that they can handle
|
46
|
+
# both 0/1 and true/false.
|
47
|
+
########################################################################
|
48
|
+
no_acc = [:bold,:italic,:underline,:strikeout,:text_wrap,:text_justlast]
|
49
|
+
no_acc.push(:fg_color,:bg_color,:color,:font_outline,:font_shadow)
|
50
|
+
|
51
|
+
args.each{|key,val|
|
52
|
+
key = key.to_s.downcase.intern
|
53
|
+
val = 1 if val == true
|
54
|
+
val = 0 if val == false
|
55
|
+
defaults.fetch(key)
|
56
|
+
defaults.update(key=>val)
|
57
|
+
}
|
58
|
+
|
59
|
+
defaults.each{|key,val|
|
60
|
+
unless no_acc.member?(key)
|
61
|
+
self.class.send(:attr_accessor,"#{key}")
|
62
|
+
end
|
63
|
+
send("#{key}=",val)
|
64
|
+
}
|
65
|
+
|
66
|
+
@xf_index = xf_index
|
67
|
+
|
68
|
+
yield self if block_given?
|
69
|
+
end
|
70
|
+
|
71
|
+
def color=(colour)
|
72
|
+
if COLORS.has_key?(colour)
|
73
|
+
@color = COLORS[colour]
|
74
|
+
else
|
75
|
+
if colour.kind_of?(String)
|
76
|
+
raise ArgumentError, "unknown color"
|
77
|
+
else
|
78
|
+
@color = colour
|
79
|
+
end
|
80
|
+
end
|
81
|
+
@color
|
82
|
+
end
|
83
|
+
|
84
|
+
def bg_color=(colour)
|
85
|
+
if COLORS.has_key?(colour)
|
86
|
+
@bg_color = COLORS[colour]
|
87
|
+
else
|
88
|
+
if colour.kind_of?(String)
|
89
|
+
raise ArgumentError, "unknown color"
|
90
|
+
else
|
91
|
+
@bg_color = colour
|
92
|
+
end
|
93
|
+
end
|
94
|
+
@bg_color
|
95
|
+
end
|
96
|
+
|
97
|
+
def fg_color=(colour)
|
98
|
+
if COLORS.has_key?(colour)
|
99
|
+
@fg_color = COLORS[colour]
|
100
|
+
else
|
101
|
+
if colour.kind_of?(String)
|
102
|
+
raise ArgumentError, "unknown color"
|
103
|
+
else
|
104
|
+
@fg_color = colour
|
105
|
+
end
|
106
|
+
end
|
107
|
+
@fg_color
|
108
|
+
end
|
109
|
+
|
110
|
+
def fg_color
|
111
|
+
@fg_color
|
112
|
+
end
|
113
|
+
|
114
|
+
def bg_color
|
115
|
+
@bg_color
|
116
|
+
end
|
117
|
+
|
118
|
+
# Should I return the stringified version of the color if applicable?
|
119
|
+
def color
|
120
|
+
#COLORS.invert.fetch(@color)
|
121
|
+
@color
|
122
|
+
end
|
123
|
+
|
124
|
+
def italic
|
125
|
+
return true if @italic >= 1
|
126
|
+
return false
|
127
|
+
end
|
128
|
+
|
129
|
+
def italic=(val)
|
130
|
+
val = 1 if val == true
|
131
|
+
val = 0 if val == false
|
132
|
+
@italic = val
|
133
|
+
end
|
134
|
+
|
135
|
+
def font_shadow
|
136
|
+
return true if @font_shadow == 1
|
137
|
+
return false
|
138
|
+
end
|
139
|
+
|
140
|
+
def font_shadow=(val)
|
141
|
+
val = 1 if val == true
|
142
|
+
val = 0 if val == false
|
143
|
+
@font_shadow = val
|
144
|
+
end
|
145
|
+
|
146
|
+
def font_outline
|
147
|
+
return true if @font_outline == 1
|
148
|
+
return false
|
149
|
+
end
|
150
|
+
|
151
|
+
def font_outline=(val)
|
152
|
+
val = 1 if val == true
|
153
|
+
val = 0 if val == false
|
154
|
+
@font_outline = val
|
155
|
+
end
|
156
|
+
|
157
|
+
def text_justlast
|
158
|
+
return true if @text_justlast == 1
|
159
|
+
return false
|
160
|
+
end
|
161
|
+
|
162
|
+
def text_justlast=(val)
|
163
|
+
val = 1 if val == true
|
164
|
+
val = 0 if val == false
|
165
|
+
@text_justlast = val
|
166
|
+
end
|
167
|
+
|
168
|
+
def text_wrap
|
169
|
+
return true if @text_wrap == 1
|
170
|
+
return false
|
171
|
+
end
|
172
|
+
|
173
|
+
def text_wrap=(val)
|
174
|
+
val = 1 if val == true
|
175
|
+
val = 0 if val == false
|
176
|
+
@text_wrap = val
|
177
|
+
end
|
178
|
+
|
179
|
+
def strikeout
|
180
|
+
return true if @strikeout == 1
|
181
|
+
return false
|
182
|
+
end
|
183
|
+
|
184
|
+
def strikeout=(val)
|
185
|
+
val = 1 if val == true
|
186
|
+
val = 0 if val == false
|
187
|
+
@strikeout = val
|
188
|
+
end
|
189
|
+
|
190
|
+
def underline
|
191
|
+
return true if @underline == 1
|
192
|
+
return false
|
193
|
+
end
|
194
|
+
|
195
|
+
def underline=(val)
|
196
|
+
val = 1 if val == true
|
197
|
+
val = 0 if val == false
|
198
|
+
@underline = val
|
199
|
+
end
|
200
|
+
|
201
|
+
|
202
|
+
def xf_biff(style=0)
|
203
|
+
atr_num = 0
|
204
|
+
atr_num = 1 if @num_format != 0
|
205
|
+
|
206
|
+
atr_fnt = 0
|
207
|
+
atr_fnt = 1 if @font_index != 0
|
208
|
+
|
209
|
+
atr_alc = @text_wrap
|
210
|
+
atr_bdr = [@bottom,@top,@left,@right].find{ |n| n > 0 } || 0
|
211
|
+
atr_pat = [@fg_color,@bg_color,@pattern].find{ |n| n > 0 } || 0
|
212
|
+
|
213
|
+
atr_prot = 0
|
214
|
+
|
215
|
+
@bottom_color = 0 if @bottom == 0
|
216
|
+
@top_color = 0 if @top == 0
|
217
|
+
@right_color = 0 if @right == 0
|
218
|
+
@left_color = 0 if @left == 0
|
219
|
+
|
220
|
+
record = 0x00E0
|
221
|
+
length = 0x0010
|
222
|
+
|
223
|
+
align = @text_h_align
|
224
|
+
align |= @text_wrap << 3
|
225
|
+
align |= @text_v_align << 4
|
226
|
+
align |= @text_justlast << 7
|
227
|
+
align |= @rotation << 8
|
228
|
+
align |= atr_num << 10
|
229
|
+
align |= atr_fnt << 11
|
230
|
+
align |= atr_alc << 12
|
231
|
+
align |= atr_bdr << 13
|
232
|
+
align |= atr_pat << 14
|
233
|
+
align |= atr_prot << 15
|
234
|
+
|
235
|
+
# Assume a solid fill color if the bg_color or fg_color are set but
|
236
|
+
# the pattern value is not set
|
237
|
+
if @pattern <= 0x01 and @bg_color != 0x41 and @fg_color == 0x40
|
238
|
+
@fg_color = @bg_color
|
239
|
+
@bg_color = 0x40
|
240
|
+
@pattern = 1
|
241
|
+
end
|
242
|
+
|
243
|
+
if @pattern < 0x01 and @bg_color == 0x41 and @fg_color != 0x40
|
244
|
+
@bg_color = 0x40
|
245
|
+
@pattern = 1
|
246
|
+
end
|
247
|
+
|
248
|
+
icv = @fg_color
|
249
|
+
icv |= @bg_color << 7
|
250
|
+
|
251
|
+
fill = @pattern
|
252
|
+
fill |= @bottom << 6
|
253
|
+
fill |= @bottom_color << 9
|
254
|
+
|
255
|
+
border1 = @top
|
256
|
+
border1 |= @left << 3
|
257
|
+
border1 |= @right << 6
|
258
|
+
border1 |= @top_color << 9
|
259
|
+
|
260
|
+
border2 = @left_color
|
261
|
+
border2 |= @right_color << 7
|
262
|
+
|
263
|
+
header = [record,length].pack("vv")
|
264
|
+
fields = [@font_index,@num_format,style,align,icv,fill,border1,border2]
|
265
|
+
data = fields.pack("vvvvvvvv")
|
266
|
+
|
267
|
+
rv = header + data
|
268
|
+
return rv
|
269
|
+
end
|
270
|
+
|
271
|
+
def font_biff
|
272
|
+
dyheight = @size * 20
|
273
|
+
cch = @font.length
|
274
|
+
record = 0x31
|
275
|
+
length = 0x0F + cch
|
276
|
+
reserved = 0x00
|
277
|
+
|
278
|
+
grbit = 0x00
|
279
|
+
grbit |= 0x02 if @italic > 0
|
280
|
+
grbit |= 0x08 if @font_strikeout > 0
|
281
|
+
grbit |= 0x10 if @font_outline > 0
|
282
|
+
grbit |= 0x20 if @font_shadow > 0
|
283
|
+
|
284
|
+
header = [record,length].pack("vv")
|
285
|
+
fields = [dyheight,grbit,@color,@bold,@font_script,@underline,@font_family]
|
286
|
+
fields.push(@font_charset,reserved,cch)
|
287
|
+
|
288
|
+
data = fields.pack("vvvvvCCCCC")
|
289
|
+
rv = header + data + @font
|
290
|
+
|
291
|
+
return rv
|
292
|
+
end
|
293
|
+
|
294
|
+
def font_key
|
295
|
+
key = @font.to_s + @size.to_s + @font_script.to_s + @underline.to_s
|
296
|
+
key += @font_strikeout.to_s + @bold.to_s + @font_outline.to_s
|
297
|
+
key += @font_family.to_s + @font_charset.to_s + @font_shadow.to_s
|
298
|
+
key += @color.to_s + @italic.to_s
|
299
|
+
return key
|
300
|
+
end
|
301
|
+
|
302
|
+
def align=(location = nil)
|
303
|
+
return if location.nil?
|
304
|
+
return if location.kind_of?(Fixnum)
|
305
|
+
location.downcase!
|
306
|
+
|
307
|
+
@text_h_align = 1 if location == 'left'
|
308
|
+
@text_h_align = 2 if location == 'centre'
|
309
|
+
@text_h_align = 2 if location == 'center'
|
310
|
+
@text_h_align = 3 if location == 'right'
|
311
|
+
@text_h_align = 4 if location == 'fill'
|
312
|
+
@text_h_align = 5 if location == 'justify'
|
313
|
+
@text_h_align = 6 if location == 'merge'
|
314
|
+
|
315
|
+
@text_v_align = 0 if location == 'top'
|
316
|
+
@text_v_align = 1 if location == 'vcentre'
|
317
|
+
@text_v_align = 1 if location == 'vcenter'
|
318
|
+
@text_v_align = 2 if location == 'bottom'
|
319
|
+
@text_v_align = 3 if location == 'vjustify'
|
320
|
+
end
|
321
|
+
|
322
|
+
def align
|
323
|
+
[@text_h_align,@text_v_align]
|
324
|
+
end
|
325
|
+
|
326
|
+
def bold=(weight)
|
327
|
+
weight = 1 if weight == true
|
328
|
+
weight = 0 if weight == false
|
329
|
+
weight = 0x2BC if weight.nil?
|
330
|
+
weight = 0x2BC if weight == 1
|
331
|
+
weight = 0x190 if weight == 0
|
332
|
+
weight = 0x190 if weight < 0x064
|
333
|
+
weight = 0x190 if weight > 0x3E8
|
334
|
+
@bold = weight
|
335
|
+
@bold
|
336
|
+
end
|
337
|
+
|
338
|
+
def bold
|
339
|
+
return true if @bold >= 1
|
340
|
+
return false
|
341
|
+
end
|
342
|
+
|
343
|
+
def border=(style)
|
344
|
+
[@bottom,@top,@right,@left].each{ |attr| attr = style }
|
345
|
+
end
|
346
|
+
|
347
|
+
def border
|
348
|
+
[@bottom,@top,@right,@left]
|
349
|
+
end
|
350
|
+
|
351
|
+
def border_color=(color)
|
352
|
+
[@bottom_color,@top_color,@left_color,@right_color].each{ |a| a = color }
|
353
|
+
end
|
354
|
+
|
355
|
+
def border_color
|
356
|
+
[@bottom_color,@top_color,@left_color,@right_color]
|
357
|
+
end
|
358
|
+
|
359
|
+
end
|