spreadsheet-excel 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/CHANGES +124 -0
  2. data/CVS/Entries +10 -0
  3. data/CVS/Repository +1 -0
  4. data/CVS/Root +1 -0
  5. data/README +69 -0
  6. data/doc/CVS/Entries +3 -0
  7. data/doc/CVS/Repository +1 -0
  8. data/doc/CVS/Root +1 -0
  9. data/doc/format.txt +330 -0
  10. data/doc/spreadsheet.txt +178 -0
  11. data/examples/CVS/Entries +3 -0
  12. data/examples/CVS/Repository +1 -0
  13. data/examples/CVS/Root +1 -0
  14. data/examples/example_basic.rb +27 -0
  15. data/examples/example_format.rb +69 -0
  16. data/lib/CVS/Entries +1 -0
  17. data/lib/CVS/Repository +1 -0
  18. data/lib/CVS/Root +1 -0
  19. data/lib/spreadsheet/CVS/Entries +7 -0
  20. data/lib/spreadsheet/CVS/Repository +1 -0
  21. data/lib/spreadsheet/CVS/Root +1 -0
  22. data/lib/spreadsheet/biffwriter.rb +46 -0
  23. data/lib/spreadsheet/excel.rb +13 -0
  24. data/lib/spreadsheet/format.rb +359 -0
  25. data/lib/spreadsheet/olewriter.rb +178 -0
  26. data/lib/spreadsheet/workbook.rb +279 -0
  27. data/lib/spreadsheet/worksheet.rb +449 -0
  28. data/test/CVS/Entries +9 -0
  29. data/test/CVS/Repository +1 -0
  30. data/test/CVS/Root +1 -0
  31. data/test/perl_output/CVS/Entries +10 -0
  32. data/test/perl_output/CVS/Repository +1 -0
  33. data/test/perl_output/CVS/Root +1 -0
  34. data/test/perl_output/README +31 -0
  35. data/test/perl_output/f_font_biff +0 -0
  36. data/test/perl_output/f_font_key +1 -0
  37. data/test/perl_output/f_xf_biff +0 -0
  38. data/test/perl_output/ole_write_header +0 -0
  39. data/test/perl_output/ws_colinfo +1 -0
  40. data/test/perl_output/ws_store_dimensions +1 -0
  41. data/test/perl_output/ws_store_selection +1 -0
  42. data/test/perl_output/ws_store_window2 +1 -0
  43. data/test/tc_all.rb +6 -0
  44. data/test/tc_biff.rb +62 -0
  45. data/test/tc_excel.rb +26 -0
  46. data/test/tc_format.rb +133 -0
  47. data/test/tc_ole.rb +125 -0
  48. data/test/tc_workbook.rb +71 -0
  49. data/test/tc_worksheet.rb +142 -0
  50. data/test/ts_all.rb +9 -0
  51. metadata +103 -0
@@ -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,3 @@
1
+ /example_basic.rb/1.2/Wed Oct 12 21:05:44 2005//
2
+ /example_format.rb/1.2/Wed Oct 12 21:11:40 2005//
3
+ D
@@ -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////
@@ -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,13 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+
3
+ require "biffwriter"
4
+ require "olewriter"
5
+ require "workbook"
6
+ require "worksheet"
7
+ require "format"
8
+
9
+ module Spreadsheet
10
+ class Excel < Workbook
11
+ VERSION = "0.3.4"
12
+ end
13
+ 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