WriteExcel 0.2.0

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.
Files changed (80) hide show
  1. data/.document +5 -0
  2. data/.gitignore +21 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +17 -0
  5. data/Rakefile +47 -0
  6. data/VERSION +1 -0
  7. data/examples/a_simple.rb +42 -0
  8. data/examples/autofilters.rb +266 -0
  9. data/examples/bigfile.rb +30 -0
  10. data/examples/copyformat.rb +51 -0
  11. data/examples/data_validate.rb +278 -0
  12. data/examples/date_time.rb +86 -0
  13. data/examples/demo.rb +118 -0
  14. data/examples/diag_border.rb +35 -0
  15. data/examples/formats.rb +489 -0
  16. data/examples/header.rb +136 -0
  17. data/examples/hidden.rb +28 -0
  18. data/examples/hyperlink.rb +42 -0
  19. data/examples/images.rb +52 -0
  20. data/examples/merge1.rb +39 -0
  21. data/examples/merge2.rb +44 -0
  22. data/examples/merge3.rb +65 -0
  23. data/examples/merge4.rb +82 -0
  24. data/examples/merge5.rb +79 -0
  25. data/examples/protection.rb +46 -0
  26. data/examples/regions.rb +52 -0
  27. data/examples/repeat.rb +42 -0
  28. data/examples/stats.rb +75 -0
  29. data/examples/stocks.rb +80 -0
  30. data/examples/tab_colors.rb +30 -0
  31. data/lib/WriteExcel.rb +30 -0
  32. data/lib/WriteExcel/biffwriter.rb +259 -0
  33. data/lib/WriteExcel/chart.rb +217 -0
  34. data/lib/WriteExcel/excelformula.y +138 -0
  35. data/lib/WriteExcel/excelformulaparser.rb +573 -0
  36. data/lib/WriteExcel/format.rb +1108 -0
  37. data/lib/WriteExcel/formula.rb +986 -0
  38. data/lib/WriteExcel/olewriter.rb +322 -0
  39. data/lib/WriteExcel/properties.rb +250 -0
  40. data/lib/WriteExcel/storage_lite.rb +590 -0
  41. data/lib/WriteExcel/workbook.rb +2602 -0
  42. data/lib/WriteExcel/worksheet.rb +6378 -0
  43. data/spec/WriteExcel_spec.rb +7 -0
  44. data/spec/spec.opts +1 -0
  45. data/spec/spec_helper.rb +9 -0
  46. data/test/tc_all.rb +31 -0
  47. data/test/tc_biff.rb +104 -0
  48. data/test/tc_chart.rb +22 -0
  49. data/test/tc_example_match.rb +1280 -0
  50. data/test/tc_format.rb +1264 -0
  51. data/test/tc_formula.rb +63 -0
  52. data/test/tc_ole.rb +110 -0
  53. data/test/tc_storage_lite.rb +102 -0
  54. data/test/tc_workbook.rb +115 -0
  55. data/test/tc_worksheet.rb +115 -0
  56. data/test/test_00_IEEE_double.rb +14 -0
  57. data/test/test_01_add_worksheet.rb +12 -0
  58. data/test/test_02_merge_formats.rb +58 -0
  59. data/test/test_04_dimensions.rb +397 -0
  60. data/test/test_05_rows.rb +182 -0
  61. data/test/test_06_extsst.rb +80 -0
  62. data/test/test_11_date_time.rb +484 -0
  63. data/test/test_12_date_only.rb +506 -0
  64. data/test/test_13_date_seconds.rb +486 -0
  65. data/test/test_21_escher.rb +629 -0
  66. data/test/test_22_mso_drawing_group.rb +739 -0
  67. data/test/test_23_note.rb +78 -0
  68. data/test/test_24_txo.rb +80 -0
  69. data/test/test_26_autofilter.rb +327 -0
  70. data/test/test_27_autofilter.rb +144 -0
  71. data/test/test_28_autofilter.rb +174 -0
  72. data/test/test_29_process_jpg.rb +131 -0
  73. data/test/test_30_validation_dval.rb +82 -0
  74. data/test/test_31_validation_dv_strings.rb +131 -0
  75. data/test/test_32_validation_dv_formula.rb +211 -0
  76. data/test/test_40_property_types.rb +191 -0
  77. data/test/test_41_properties.rb +238 -0
  78. data/test/test_42_set_properties.rb +430 -0
  79. data/test/ts_all.rb +34 -0
  80. metadata +154 -0
@@ -0,0 +1,1108 @@
1
+ ##############################################################################
2
+ #
3
+ # Format - A class for defining Excel formatting.
4
+ #
5
+ #
6
+ # Used in conjunction with Spreadsheet::WriteExcel
7
+ #
8
+ # Copyright 2000-2008, John McNamara, jmcnamara@cpan.org
9
+ #
10
+ # original written in Perl by John McNamara
11
+ # converted to Ruby by Hideo Nakamura, cxn03651@msj.biglobe.ne.jp
12
+ #
13
+ #require 'nkf'
14
+
15
+ class Format
16
+
17
+ COLORS = {
18
+ 'aqua' => 0x0F,
19
+ 'cyan' => 0x0F,
20
+ 'black' => 0x08,
21
+ 'blue' => 0x0C,
22
+ 'brown' => 0x10,
23
+ 'magenta' => 0x0E,
24
+ 'fuchsia' => 0x0E,
25
+ 'gray' => 0x17,
26
+ 'grey' => 0x17,
27
+ 'green' => 0x11,
28
+ 'lime' => 0x0B,
29
+ 'navy' => 0x12,
30
+ 'orange' => 0x35,
31
+ 'pink' => 0x21,
32
+ 'purple' => 0x14,
33
+ 'red' => 0x0A,
34
+ 'silver' => 0x16,
35
+ 'white' => 0x09,
36
+ 'yellow' => 0x0D,
37
+ }
38
+ NonAscii = /[^!"#\$%&'\(\)\*\+,\-\.\/\:\;<=>\?@0-9A-Za-z_\[\\\]^` ~\0\n]/
39
+
40
+ attr_accessor :xf_index, :used_merge
41
+ attr_accessor :bold, :text_wrap, :text_justlast
42
+ attr_accessor :fg_color, :bg_color, :color, :font, :size, :font_outline, :font_shadow
43
+ attr_accessor :align, :border
44
+ attr_accessor :font_index
45
+ attr_accessor :num_format
46
+ attr_reader :type
47
+ attr_reader :font, :size, :font_family, :font_strikeout, :font_script, :font_charset
48
+ attr_reader :font_encoding, :merge_range, :reading_order
49
+ attr_reader :diag_type, :diag_color, :diag_border
50
+ attr_reader :num_format_enc, :locked, :hidden
51
+ attr_reader :rotation, :indent, :shrink, :pattern, :bottom, :top, :left, :right
52
+ attr_reader :bottom_color, :top_color, :left_color, :right_color
53
+ attr_reader :italic, :underline, :font_strikeout
54
+ attr_reader :text_h_align, :text_v_align, :font_only
55
+
56
+ ###############################################################################
57
+ #
58
+ # initialize(xf_index=0, properties = {})
59
+ # xf_index :
60
+ # properties : Hash of property => value
61
+ #
62
+ # Constructor
63
+ #
64
+ def initialize(xf_index = 0, properties = {})
65
+ @xf_index = xf_index
66
+
67
+ @type = 0
68
+ @font_index = 0
69
+ @font = 'Arial'
70
+ @size = 10
71
+ @bold = 0x0190
72
+ @italic = 0
73
+ @color = 0x7FFF
74
+ @underline = 0
75
+ @font_strikeout = 0
76
+ @font_outline = 0
77
+ @font_shadow = 0
78
+ @font_script = 0
79
+ @font_family = 0
80
+ @font_charset = 0
81
+ @font_encoding = 0
82
+
83
+ @num_format = 0
84
+ @num_format_enc = 0
85
+
86
+ @hidden = 0
87
+ @locked = 1
88
+
89
+ @text_h_align = 0
90
+ @text_wrap = 0
91
+ @text_v_align = 2
92
+ @text_justlast = 0
93
+ @rotation = 0
94
+
95
+ @fg_color = 0x40
96
+ @bg_color = 0x41
97
+
98
+ @pattern = 0
99
+
100
+ @bottom = 0
101
+ @top = 0
102
+ @left = 0
103
+ @right = 0
104
+
105
+ @bottom_color = 0x40
106
+ @top_color = 0x40
107
+ @left_color = 0x40
108
+ @right_color = 0x40
109
+
110
+ @indent = 0
111
+ @shrink = 0
112
+ @merge_range = 0
113
+ @reading_order = 0
114
+
115
+ @diag_type = 0
116
+ @diag_color = 0x40
117
+ @diag_border = 0
118
+
119
+ @font_only = 0
120
+
121
+ # Temp code to prevent merged formats in non-merged cells.
122
+ @used_merge = 0
123
+
124
+ set_format_properties(properties) unless properties.empty?
125
+ end
126
+
127
+
128
+ ###############################################################################
129
+ #
130
+ # copy($format)
131
+ #
132
+ # Copy the attributes of another Spreadsheet::WriteExcel::Format object.
133
+ #
134
+ def copy(other)
135
+ return unless other.kind_of?(Format)
136
+
137
+ # copy properties except xf, merge_range, used_merge
138
+ # Copy properties
139
+ @type = other.type
140
+ @font_index = other.font_index
141
+ @font = other.font
142
+ @size = other.size
143
+ @bold = other.bold
144
+ @italic = other.italic
145
+ @color = other.color
146
+ @underline = other.underline
147
+ @font_strikeout = other.font_strikeout
148
+ @font_outline = other.font_outline
149
+ @font_shadow = other.font_shadow
150
+ @font_script = other.font_script
151
+ @font_family = other.font_family
152
+ @font_charset = other.font_charset
153
+ @font_encoding = other.font_encoding
154
+
155
+ @num_format = other.num_format
156
+ @num_format_enc = other.num_format_enc
157
+
158
+ @hidden = other.hidden
159
+ @locked = other.locked
160
+
161
+ @text_h_align = other.text_h_align
162
+ @text_wrap = other.text_wrap
163
+ @text_v_align = other.text_v_align
164
+ @text_justlast = other.text_justlast
165
+ @rotation = other.rotation
166
+
167
+ @fg_color = other.fg_color
168
+ @bg_color = other.bg_color
169
+
170
+ @pattern = other.pattern
171
+
172
+ @bottom = other.bottom
173
+ @top = other.top
174
+ @left = other.left
175
+ @right = other.right
176
+
177
+ @bottom_color = other.bottom_color
178
+ @top_color = other.top_color
179
+ @left_color = other.left_color
180
+ @right_color = other.right_color
181
+
182
+ @indent = other.indent
183
+ @shrink = other.shrink
184
+ @reading_order = other.reading_order
185
+
186
+ @diag_type = other.diag_type
187
+ @diag_color = other.diag_color
188
+ @diag_border = other.diag_border
189
+
190
+ @font_only = other.font_only
191
+ end
192
+
193
+ ###############################################################################
194
+ #
195
+ # get_xf($style)
196
+ #
197
+ # Generate an Excel BIFF XF record.
198
+ #
199
+ def get_xf
200
+
201
+ # Local Variable
202
+ # record; # Record identifier
203
+ # length; # Number of bytes to follow
204
+ #
205
+ # ifnt; # Index to FONT record
206
+ # ifmt; # Index to FORMAT record
207
+ # style; # Style and other options
208
+ # align; # Alignment
209
+ # indent; #
210
+ # icv; # fg and bg pattern colors
211
+ # border1; # Border line options
212
+ # border2; # Border line options
213
+ # border3; # Border line options
214
+
215
+ # Set the type of the XF record and some of the attributes.
216
+ if @type == 0xFFF5 then
217
+ style = 0xFFF5
218
+ else
219
+ style = @locked
220
+ style |= @hidden << 1
221
+ end
222
+
223
+ # Flags to indicate if attributes have been set.
224
+ atr_num = (@num_format != 0) ? 1 : 0
225
+ atr_fnt = (@font_index != 0) ? 1 : 0
226
+ atr_alc = (@text_h_align != 0 ||
227
+ @text_v_align != 2 ||
228
+ @shrink != 0 ||
229
+ @merge_range != 0 ||
230
+ @text_wrap != 0 ||
231
+ @indent != 0) ? 1 : 0
232
+ atr_bdr = (@bottom != 0 ||
233
+ @top != 0 ||
234
+ @left != 0 ||
235
+ @right != 0 ||
236
+ @diag_type != 0) ? 1 : 0
237
+ atr_pat = (@fg_color != 0x40 ||
238
+ @bg_color != 0x41 ||
239
+ @pattern != 0x00) ? 1 : 0
240
+ atr_prot = (@hidden != 0 ||
241
+ @locked != 1) ? 1 : 0
242
+
243
+ # Set attribute changed flags for the style formats.
244
+ if @xf_index != 0 and @type == 0xFFF5
245
+ if @xf_index >= 16
246
+ atr_num = 0
247
+ atr_fnt = 1
248
+ else
249
+ atr_num = 1
250
+ atr_fnt = 0
251
+ end
252
+ atr_alc = 1
253
+ atr_bdr = 1
254
+ atr_pat = 1
255
+ atr_prot = 1
256
+ end
257
+
258
+ # Set a default diagonal border style if none was specified.
259
+ @diag_border = 1 if (@diag_border ==0 and @diag_type != 0)
260
+
261
+ # Reset the default colours for the non-font properties
262
+ @fg_color = 0x40 if @fg_color == 0x7FFF
263
+ @bg_color = 0x41 if @bg_color == 0x7FFF
264
+ @bottom_color = 0x40 if @bottom_color == 0x7FFF
265
+ @top_color = 0x40 if @top_color == 0x7FFF
266
+ @left_color = 0x40 if @left_color == 0x7FFF
267
+ @right_color = 0x40 if @right_color == 0x7FFF
268
+ @diag_color = 0x40 if @diag_color == 0x7FFF
269
+
270
+ # Zero the default border colour if the border has not been set.
271
+ @bottom_color = 0 if @bottom == 0
272
+ @top_color = 0 if @top == 0
273
+ @right_color = 0 if @right == 0
274
+ @left_color = 0 if @left == 0
275
+ @diag_color = 0 if @diag_type == 0
276
+
277
+ # The following 2 logical statements take care of special cases in relation
278
+ # to cell colours and patterns:
279
+ # 1. For a solid fill (_pattern == 1) Excel reverses the role of foreground
280
+ # and background colours.
281
+ # 2. If the user specifies a foreground or background colour without a
282
+ # pattern they probably wanted a solid fill, so we fill in the defaults.
283
+ #
284
+ if (@pattern <= 0x01 && @bg_color != 0x41 && @fg_color == 0x40)
285
+ @fg_color = @bg_color
286
+ @bg_color = 0x40
287
+ @pattern = 1
288
+ end
289
+
290
+ if (@pattern <= 0x01 && @bg_color == 0x41 && @fg_color != 0x40)
291
+ @bg_color = 0x40
292
+ @pattern = 1
293
+ end
294
+
295
+ # Set default alignment if indent is set.
296
+ @text_h_align = 1 if @indent != 0 and @text_h_align == 0
297
+
298
+
299
+ record = 0x00E0
300
+ length = 0x0014
301
+
302
+ ifnt = @font_index
303
+ ifmt = @num_format
304
+
305
+
306
+ align = @text_h_align
307
+ align |= @text_wrap << 3
308
+ align |= @text_v_align << 4
309
+ align |= @text_justlast << 7
310
+ align |= @rotation << 8
311
+
312
+ indent = @indent
313
+ indent |= @shrink << 4
314
+ indent |= @merge_range << 5
315
+ indent |= @reading_order << 6
316
+ indent |= atr_num << 10
317
+ indent |= atr_fnt << 11
318
+ indent |= atr_alc << 12
319
+ indent |= atr_bdr << 13
320
+ indent |= atr_pat << 14
321
+ indent |= atr_prot << 15
322
+
323
+
324
+ border1 = @left
325
+ border1 |= @right << 4
326
+ border1 |= @top << 8
327
+ border1 |= @bottom << 12
328
+
329
+ border2 = @left_color
330
+ border2 |= @right_color << 7
331
+ border2 |= @diag_type << 14
332
+
333
+ border3 = 0
334
+ border3 |= @top_color
335
+ border3 |= @bottom_color << 7
336
+ border3 |= @diag_color << 14
337
+ border3 |= @diag_border << 21
338
+ border3 |= @pattern << 26
339
+
340
+ icv = @fg_color
341
+ icv |= @bg_color << 7
342
+
343
+ header = [record, length].pack("vv")
344
+ data = [ifnt, ifmt, style, align, indent,
345
+ border1, border2, border3, icv].pack("vvvvvvvVv")
346
+
347
+ return header + data
348
+ end
349
+
350
+ ###############################################################################
351
+ #
352
+ # get_font()
353
+ #
354
+ # Generate an Excel BIFF FONT record.
355
+ #
356
+ def get_font
357
+
358
+ # my $record; # Record identifier
359
+ # my $length; # Record length
360
+
361
+ # my $dyHeight; # Height of font (1/20 of a point)
362
+ # my $grbit; # Font attributes
363
+ # my $icv; # Index to color palette
364
+ # my $bls; # Bold style
365
+ # my $sss; # Superscript/subscript
366
+ # my $uls; # Underline
367
+ # my $bFamily; # Font family
368
+ # my $bCharSet; # Character set
369
+ # my $reserved; # Reserved
370
+ # my $cch; # Length of font name
371
+ # my $rgch; # Font name
372
+ # my $encoding; # Font name character encoding
373
+
374
+
375
+ dyHeight = @size * 20
376
+ icv = @color
377
+ bls = @bold
378
+ sss = @font_script
379
+ uls = @underline
380
+ bFamily = @font_family
381
+ bCharSet = @font_charset
382
+ rgch = @font
383
+ encoding = @font_encoding
384
+
385
+ # Handle utf8 strings
386
+ if rgch =~ NonAscii
387
+ rgch = NKF.nkf('-w16B0 -m0 -W', rgch)
388
+ encoding = 1
389
+ end
390
+
391
+ cch = rgch.length
392
+ #
393
+ # Handle Unicode font names.
394
+ if (encoding == 1)
395
+ raise "Uneven number of bytes in Unicode font name" if cch % 2 != 0
396
+ cch /= 2 if encoding !=0
397
+ rgch = rgch.unpack('n*').pack('v*')
398
+ end
399
+
400
+ record = 0x31
401
+ length = 0x10 + rgch.length
402
+ reserved = 0x00
403
+
404
+ grbit = 0x00
405
+ grbit |= 0x02 if @italic != 0
406
+ grbit |= 0x08 if @font_strikeout != 0
407
+ grbit |= 0x10 if @font_outline != 0
408
+ grbit |= 0x20 if @font_shadow != 0
409
+
410
+
411
+ header = [record, length].pack("vv")
412
+ data = [dyHeight, grbit, icv, bls,
413
+ sss, uls, bFamily,
414
+ bCharSet, reserved, cch, encoding].pack('vvvvvCCCCCC')
415
+
416
+ return header + data + rgch
417
+ end
418
+
419
+ ###############################################################################
420
+ #
421
+ # get_font_key()
422
+ #
423
+ # Returns a unique hash key for a font. Used by Workbook->_store_all_fonts()
424
+ #
425
+ def get_font_key
426
+ # The following elements are arranged to increase the probability of
427
+ # generating a unique key. Elements that hold a large range of numbers
428
+ # e.g. _color are placed between two binary elements such as _italic
429
+
430
+ key = "#{@font}#{@size}#{@font_script}#{@underline}#{@font_strikeout}#{@bold}#{@font_outline}"
431
+ key += "#{@font_family}#{@font_charset}#{@font_shadow}#{@color}#{@italic}#{@font_encoding}"
432
+ result = key.gsub(' ', '_') # Convert the key to a single word
433
+
434
+ return result
435
+ end
436
+
437
+ ###############################################################################
438
+ #
439
+ # get_xf_index()
440
+ #
441
+ # Returns the used by Worksheet->_XF()
442
+ #
443
+ def get_xf_index
444
+ return @xf_index
445
+ end
446
+
447
+
448
+ ###############################################################################
449
+ #
450
+ # get_color(colour)
451
+ #
452
+ # Used in conjunction with the set_xxx_color methods to convert a color
453
+ # string into a number. Color range is 0..63 but we will restrict it
454
+ # to 8..63 to comply with Gnumeric. Colors 0..7 are repeated in 8..15.
455
+ #
456
+ def get_color(colour = nil)
457
+ # Return the default color, 0x7FFF, if undef,
458
+ return 0x7FFF if colour.nil?
459
+
460
+ if colour.kind_of?(Numeric)
461
+ if colour < 0
462
+ return 0x7FFF
463
+
464
+ # or an index < 8 mapped into the correct range,
465
+ elsif colour < 8
466
+ return (colour + 8).to_i
467
+
468
+ # or the default color if arg is outside range,
469
+ elsif colour > 63
470
+ return 0x7FFF
471
+
472
+ # or an integer in the valid range
473
+ else
474
+ return colour.to_i
475
+ end
476
+ elsif colour.kind_of?(String)
477
+ # or the color string converted to an integer,
478
+ if COLORS.has_key?(colour)
479
+ return COLORS[colour]
480
+
481
+ # or the default color if string is unrecognised,
482
+ else
483
+ return 0x7FFF
484
+ end
485
+ else
486
+ return 0x7FFF
487
+ end
488
+ end
489
+
490
+ ###############################################################################
491
+ #
492
+ # class method Format._get_color(colour)
493
+ #
494
+ # used from Worksheet.rb
495
+ #
496
+ # this is cut & copy of get_color().
497
+ #
498
+ def self._get_color(colour)
499
+ # Return the default color, 0x7FFF, if undef,
500
+ return 0x7FFF if colour.nil?
501
+
502
+ if colour.kind_of?(Numeric)
503
+ if colour < 0
504
+ return 0x7FFF
505
+
506
+ # or an index < 8 mapped into the correct range,
507
+ elsif colour < 8
508
+ return (colour + 8).to_i
509
+
510
+ # or the default color if arg is outside range,
511
+ elsif 63 < colour
512
+ return 0x7FFF
513
+
514
+ # or an integer in the valid range
515
+ else
516
+ return colour.to_i
517
+ end
518
+ elsif colour.kind_of?(String)
519
+ # or the color string converted to an integer,
520
+ if COLORS.has_key?(colour)
521
+ return COLORS[colour]
522
+
523
+ # or the default color if string is unrecognised,
524
+ else
525
+ return 0x7FFF
526
+ end
527
+ else
528
+ return 0x7FFF
529
+ end
530
+ end
531
+
532
+ ###############################################################################
533
+ #
534
+ # set_type()
535
+ #
536
+ # Set the XF object type as 0 = cell XF or 0xFFF5 = style XF.
537
+ #
538
+ def set_type(type = nil)
539
+
540
+ if !type.nil? and type == 0
541
+ @type = 0x0000
542
+ else
543
+ @type = 0xFFF5
544
+ end
545
+ end
546
+
547
+ ###############################################################################
548
+ #
549
+ # set_size(size)
550
+ #
551
+ # Default state: Font size is 10
552
+ # Default action: Set font size to 1
553
+ # Valid args: Integer values from 1 to as big as your screen.
554
+ # Set the font size. Excel adjusts the height of a row
555
+ # to accommodate the
556
+ #
557
+ # largest font size in the row. You can also explicitly specify the height
558
+ # of a row using the set_row() worksheet method.Set cell alignment.
559
+ #
560
+ def set_size(size = 1)
561
+ if size.kind_of?(Numeric) && size >= 1
562
+ @size = size.to_i
563
+ end
564
+ end
565
+
566
+ ###############################################################################
567
+ #
568
+ # set_color(color)
569
+ #
570
+ # Default state: Excels default color, usually black
571
+ # Default action: Set the default color
572
+ # Valid args: Integers from 8..63 or the following strings:
573
+ # 'black', 'blue', 'brown', 'cyan', 'gray'
574
+ # 'green', 'lime', 'magenta', 'navy', 'orange'
575
+ # 'pink', 'purple', 'red', 'silver', 'white', 'yellow'
576
+ #
577
+ # Set the font colour. The set_color() method is used as follows:
578
+ #
579
+ # format = workbook.add_format()
580
+ # format.set_color('red')
581
+ # worksheet.write(0, 0, 'wheelbarrow', format)
582
+ #
583
+ # Note: The set_color() method is used to set the colour of the font in a cell.
584
+ # To set the colour of a cell use the set_bg_color()
585
+ # and set_pattern() methods.
586
+ #
587
+ def set_color(color = 0x7FFF)
588
+ @color = get_color(color)
589
+ end
590
+
591
+ ###############################################################################
592
+ #
593
+ # set_italic()
594
+ #
595
+ # Default state: Italic is off
596
+ # Default action: Turn italic on
597
+ # Valid args: 0, 1
598
+ #
599
+ # Set the italic property of the font:
600
+ #
601
+ # format.set_italic() # Turn italic on
602
+ #
603
+ def set_italic(arg = 1)
604
+ begin
605
+ if arg == 1 then @italic = 1 # italic on
606
+ elsif arg == 0 then @italic = 0 # italic off
607
+ else
608
+ raise ArgumentError,
609
+ "\n\n set_italic(#{arg.inspect})\n arg must be 0, 1, or none. ( 0:OFF , 1 and none:ON )\n"
610
+ end
611
+ end
612
+ end
613
+
614
+ ###############################################################################
615
+ #
616
+ # set_underline()
617
+ #
618
+ # Default state: Underline is off
619
+ # Default action: Turn on single underline
620
+ # Valid args: 0 = No underline
621
+ # 1 = Single underline
622
+ # 2 = Double underline
623
+ # 33 = Single accounting underline
624
+ # 34 = Double accounting underline
625
+ #
626
+ # Set the underline property of the font.
627
+ #
628
+ def set_underline(arg = 1)
629
+ begin
630
+ case arg
631
+ when 0 then @underline = 0 # off
632
+ when 1 then @underline = 1 # Single
633
+ when 2 then @underline = 2 # Double
634
+ when 33 then @underline = 33 # Single accounting
635
+ when 34 then @underline = 34 # Double accounting
636
+ else
637
+ raise ArgumentError,
638
+ "\n\n set_underline(#{arg.inspect})\n arg must be 0, 1, or none, 2, 33, 34.\n"
639
+ " ( 0:OFF, 1 and none:Single, 2:Double, 33:Single accounting, 34:Double accounting )\n"
640
+ end
641
+ end
642
+ end
643
+
644
+ ###############################################################################
645
+ #
646
+ # set_font_strikeout()
647
+ #
648
+ # Default state: Strikeout is off
649
+ # Default action: Turn strikeout on
650
+ # Valid args: 0, 1
651
+ #
652
+ # Set the strikeout property of the font.
653
+ #
654
+ def set_font_strikeout(arg = 1)
655
+ begin
656
+ if arg == 0 then @font_strikeout = 0
657
+ elsif arg == 1 then @font_strikeout = 1
658
+ else
659
+ raise ArgumentError,
660
+ "\n\n set_font_strikeout(#{arg.inspect})\n arg must be 0, 1, or none.\n"
661
+ " ( 0:OFF, 1 and none:Strikeout )\n"
662
+ end
663
+ end
664
+ end
665
+
666
+ ###############################################################################
667
+ #
668
+ # set_font_script()
669
+ #
670
+ # Default state: Super/Subscript is off
671
+ # Default action: Turn Superscript on
672
+ # Valid args: 0 = Normal
673
+ # 1 = Superscript
674
+ # 2 = Subscript
675
+ #
676
+ # Set the superscript/subscript property of the font.
677
+ # This format is currently not very useful.
678
+ #
679
+ def set_font_script(arg = 1)
680
+ begin
681
+ if arg == 0 then @font_script = 0
682
+ elsif arg == 1 then @font_script = 1
683
+ elsif arg == 2 then @font_script = 2
684
+ else
685
+ raise ArgumentError,
686
+ "\n\n set_font_script(#{arg.inspect})\n arg must be 0, 1, or none. or 2\n"
687
+ " ( 0:OFF, 1 and none:Superscript, 2:Subscript )\n"
688
+ end
689
+ end
690
+ end
691
+
692
+ ###############################################################################
693
+ #
694
+ # set_font_outline()
695
+ #
696
+ # Default state: Outline is off
697
+ # Default action: Turn outline on
698
+ # Valid args: 0, 1
699
+ #
700
+ # Macintosh only.
701
+ #
702
+ def set_font_outline(arg = 1)
703
+ begin
704
+ if arg == 0 then @font_outline = 0
705
+ elsif arg == 1 then @font_outline = 1
706
+ else
707
+ raise ArgumentError,
708
+ "\n\n set_font_outline(#{arg.inspect})\n arg must be 0, 1, or none.\n"
709
+ " ( 0:OFF, 1 and none:outline on )\n"
710
+ end
711
+ end
712
+ end
713
+
714
+ ###############################################################################
715
+ #
716
+ # set_font_shadow()
717
+ #
718
+ # Default state: Shadow is off
719
+ # Default action: Turn shadow on
720
+ # Valid args: 0, 1
721
+ #
722
+ # Macintosh only.
723
+ #
724
+ def set_font_shadow(arg = 1)
725
+ begin
726
+ if arg == 0 then @font_shadow = 0
727
+ elsif arg == 1 then @font_shadow = 1
728
+ else
729
+ raise ArgumentError,
730
+ "\n\n set_font_shadow(#{arg.inspect})\n arg must be 0, 1, or none.\n"
731
+ " ( 0:OFF, 1 and none:shadow on )\n"
732
+ end
733
+ end
734
+ end
735
+
736
+ ###############################################################################
737
+ #
738
+ # set_locked()
739
+ #
740
+ # Default state: Cell locking is on
741
+ # Default action: Turn locking on
742
+ # Valid args: 0, 1
743
+ #
744
+ # This property can be used to prevent modification of a cells contents.
745
+ # Following Excel's convention, cell locking is turned on by default.
746
+ # However, it only has an effect if the worksheet has been protected,
747
+ # see the worksheet protect() method.
748
+ #
749
+ # locked = workbook.add_format()
750
+ # locked.set_locked(1) # A non-op
751
+ #
752
+ # unlocked = workbook.add_format()
753
+ # locked.set_locked(0)
754
+ #
755
+ # # Enable worksheet protection
756
+ # worksheet.protect()
757
+ #
758
+ # # This cell cannot be edited.
759
+ # worksheet.write('A1', '=1+2', locked)
760
+ #
761
+ # # This cell can be edited.
762
+ # worksheet.write('A2', '=1+2', unlocked)
763
+ #
764
+ # Note: This offers weak protection even with a password, see the note
765
+ # in relation to the protect() method.
766
+ #
767
+ def set_locked(arg = 1)
768
+ begin
769
+ if arg == 0 then @locked = 0
770
+ elsif arg == 1 then @locked = 1
771
+ else
772
+ raise ArgumentError,
773
+ "\n\n set_locked(#{arg.inspect})\n arg must be 0, 1, or none.\n"
774
+ " ( 0:OFF, 1 and none:Lock On )\n"
775
+ end
776
+ end
777
+ end
778
+
779
+ ###############################################################################
780
+ #
781
+ # set_hidden()
782
+ #
783
+ # Default state: Formula hiding is off
784
+ # Default action: Turn hiding on
785
+ # Valid args: 0, 1
786
+ #
787
+ # This property is used to hide a formula while still displaying
788
+ # its result. This is generally used to hide complex calculations
789
+ # from end users who are only interested in the result. It only has
790
+ # an effect if the worksheet has been protected,
791
+ # see the worksheet protect() method.
792
+ #
793
+ # my hidden = workbook.add_format()
794
+ # hidden.set_hidden()
795
+ #
796
+ # # Enable worksheet protection
797
+ # worksheet.protect()
798
+ #
799
+ # # The formula in this cell isn't visible
800
+ # worksheet.write('A1', '=1+2', hidden)
801
+ #
802
+ # Note: This offers weak protection even with a password,
803
+ # see the note in relation to the protect() method .
804
+ #
805
+ def set_hidden(arg = 1)
806
+ begin
807
+ if arg == 0 then @hidden = 0
808
+ elsif arg == 1 then @hidden = 1
809
+ else
810
+ raise ArgumentError,
811
+ "\n\n set_hidden(#{arg.inspect})\n arg must be 0, 1, or none.\n"
812
+ " ( 0:OFF, 1 and none:hiding On )\n"
813
+ end
814
+ end
815
+ end
816
+
817
+ ###############################################################################
818
+ #
819
+ # set_align()
820
+ #
821
+ # Set cell alignment.
822
+ #
823
+ # Default state: Alignment is off
824
+ # Default action: Left alignment
825
+ # Valid args: 'left' Horizontal
826
+ # 'center'
827
+ # 'right'
828
+ # 'fill'
829
+ # 'justify'
830
+ # 'center_across'
831
+ #
832
+ # 'top' Vertical
833
+ # 'vcenter'
834
+ # 'bottom'
835
+ # 'vjustify'
836
+ #
837
+ # This method is used to set the horizontal and vertical text alignment
838
+ # within a cell. Vertical and horizontal alignments can be combined.
839
+ # The method is used as follows:
840
+ #
841
+ # my $format = $workbook->add_format();
842
+ # $format->set_align('center');
843
+ # $format->set_align('vcenter');
844
+ # $worksheet->set_row(0, 30);
845
+ # $worksheet->write(0, 0, 'X', $format);
846
+ #
847
+ # Text can be aligned across two or more adjacent cells using
848
+ # the center_across property. However, for genuine merged cells
849
+ # it is better to use the merge_range() worksheet method.
850
+ #
851
+ # The vjustify (vertical justify) option can be used to provide
852
+ # automatic text wrapping in a cell. The height of the cell will be
853
+ # adjusted to accommodate the wrapped text. To specify where the text
854
+ # wraps use the set_text_wrap() method.
855
+ #
856
+ def set_align(align = 'left')
857
+
858
+ return unless align.kind_of?(String)
859
+
860
+ location = align.downcase
861
+
862
+ case location
863
+ when 'left' then set_text_h_align(1)
864
+ when 'centre', 'center' then set_text_h_align(2)
865
+ when 'right' then set_text_h_align(3)
866
+ when 'fill' then set_text_h_align(4)
867
+ when 'justify' then set_text_h_align(5)
868
+ when 'center_across', 'centre_across' then set_text_h_align(6)
869
+ when 'merge' then set_text_h_align(6) # S:WE name
870
+ when 'distributed' then set_text_h_align(7)
871
+ when 'equal_space' then set_text_h_align(7) # ParseExcel
872
+
873
+ when 'top' then set_text_v_align(0)
874
+ when 'vcentre' then set_text_v_align(1)
875
+ when 'vcenter' then set_text_v_align(1)
876
+ when 'bottom' then set_text_v_align(2)
877
+ when 'vjustify' then set_text_v_align(3)
878
+ when 'vdistributed' then set_text_v_align(4)
879
+ when 'vequal_space' then set_text_v_align(4) # ParseExcel
880
+ end
881
+ end
882
+
883
+ ###############################################################################
884
+ #
885
+ # set_valign()
886
+ #
887
+ # Set vertical cell alignment. This is required by the set_format_properties()
888
+ # method to differentiate between the vertical and horizontal properties.
889
+ #
890
+ def set_valign(alignment)
891
+ set_align(alignment);
892
+ end
893
+
894
+ ###############################################################################
895
+ #
896
+ # set_center_across()
897
+ #
898
+ # Implements the Excel5 style "merge".
899
+ #
900
+ def set_center_across(val=true)
901
+ set_text_h_align(6)
902
+ end
903
+
904
+ ###############################################################################
905
+ #
906
+ # set_merge()
907
+ #
908
+ # This was the way to implement a merge in Excel5. However it should have been
909
+ # called "center_across" and not "merge".
910
+ # This is now deprecated. Use set_center_across() or better merge_range().
911
+ #
912
+ #
913
+ def set_merge(val=true)
914
+ set_text_h_align(6)
915
+ end
916
+
917
+ ###############################################################################
918
+ #
919
+ #set_text_wrap()
920
+ #
921
+ # Default state: Text wrap is off
922
+ # Default action: Turn text wrap on
923
+ # Valid args: 0, 1
924
+ #
925
+ # Here is an example using the text wrap property, the escape
926
+ # character \n is used to indicate the end of line:
927
+ #
928
+ # format = workbook.add_format()
929
+ # format.set_text_wrap()
930
+ # worksheet.write(0, 0, "It's\na bum\nwrap", format)
931
+ #
932
+ def set_text_wrap(arg = 1)
933
+ begin
934
+ if arg == 0 then @text_wrap = 0
935
+ elsif arg == 1 then @text_wrap = 1
936
+ else
937
+ raise ArgumentError,
938
+ "\n\n set_text_wrap(#{arg.inspect})\n arg must be 0, 1, or none.\n"
939
+ " ( 0:OFF, 1 and none:text wrap On )\n"
940
+ end
941
+ end
942
+ end
943
+
944
+ ###############################################################################
945
+ #
946
+ # set_bold()
947
+ #
948
+ # Default state: bold is off (internal value = 400)
949
+ # Default action: Turn bold on
950
+ # Valid args: 0, 1 [1]
951
+ #
952
+ # Set the bold property of the font:
953
+ #
954
+ # format.set_bold() # Turn bold on
955
+ #
956
+ #[1] Actually, values in the range 100..1000 are also valid.
957
+ # 400 is normal, 700 is bold and 1000 is very bold indeed.
958
+ # It is probably best to set the value to 1 and use normal bold.
959
+ #
960
+ def set_bold(weight = nil)
961
+ if weight.nil?
962
+ weight = 0x2BC
963
+ elsif !weight.kind_of?(Numeric)
964
+ weight = 0x190
965
+ elsif weight == 1 # Bold text
966
+ weight = 0x2BC
967
+ elsif weight == 0 # Normal text
968
+ weight = 0x190
969
+ elsif weight < 0x064 # Lower bound
970
+ weight = 0x190
971
+ elsif weight > 0x3E8 # Upper bound
972
+ weight = 0x190
973
+ else
974
+ weight = weight.to_i
975
+ end
976
+
977
+ @bold = weight
978
+ end
979
+
980
+
981
+ ###############################################################################
982
+ #
983
+ # set_border($style)
984
+ #
985
+ # Set cells borders to the same style
986
+ #
987
+ def set_border(style)
988
+ set_bottom(style)
989
+ set_top(style)
990
+ set_left(style)
991
+ set_right(style)
992
+ end
993
+
994
+
995
+ ###############################################################################
996
+ #
997
+ # set_border_color($color)
998
+ #
999
+ # Set cells border to the same color
1000
+ #
1001
+ def set_border_color(color)
1002
+ set_bottom_color(color);
1003
+ set_top_color(color);
1004
+ set_left_color(color);
1005
+ set_right_color(color);
1006
+ end
1007
+
1008
+ ###############################################################################
1009
+ #
1010
+ # set_rotation($angle)
1011
+ #
1012
+ # Set the rotation angle of the text. An alignment property.
1013
+ #
1014
+ def set_rotation(rotation)
1015
+ # Argument should be a number
1016
+ return unless rotation.kind_of?(Numeric)
1017
+
1018
+ # The arg type can be a double but the Excel dialog only allows integers.
1019
+ rotation = rotation.to_i
1020
+
1021
+ # if (rotation == 270)
1022
+ # rotation = 255
1023
+ # elsif (rotation >= -90 or rotation <= 90)
1024
+ # rotation = -rotation +90 if rotation < 0;
1025
+ # else
1026
+ # # carp "Rotation $rotation outside range: -90 <= angle <= 90";
1027
+ # rotation = 0;
1028
+ # end
1029
+ #
1030
+ if rotation == 270
1031
+ rotation = 255
1032
+ elsif rotation >= -90 && rotation <= 90
1033
+ rotation = -rotation + 90 if rotation < 0
1034
+ else
1035
+ rotation = 0
1036
+ end
1037
+
1038
+ @rotation = rotation;
1039
+ end
1040
+
1041
+
1042
+ ###############################################################################
1043
+ #
1044
+ # set_format_properties(*properties)
1045
+ # properties : Hash of properies
1046
+ # ex) font = { :color => 'red', :bold => 1 }
1047
+ # shade = { :bg_color => 'green', :pattern => 1 }
1048
+ # 1) set_format_properties( :bold => 1 [, :color => 'red'..] )
1049
+ # 2) set_format_properties( font [, shade, ..])
1050
+ # 3) set_format_properties( :bold => 1, font, ...)
1051
+ #
1052
+ # Convert hashes of properties to method calls.
1053
+ #
1054
+ def set_format_properties(*properties)
1055
+ return if properties.empty?
1056
+ properties.each do |property|
1057
+ property.each do |key, value|
1058
+ # Strip leading "-" from Tk style properties e.g. -color => 'red'.
1059
+ key.sub!(/^-/, '') if key.kind_of?(String)
1060
+
1061
+ # Create a sub to set the property.
1062
+ if value.kind_of?(String)
1063
+ s = "set_#{key}('#{value}')"
1064
+ else
1065
+ s = "set_#{key}(#{value})"
1066
+ end
1067
+ eval s
1068
+ end
1069
+ end
1070
+ end
1071
+
1072
+ # Renamed rarely used set_properties() to set_format_properties() to avoid
1073
+ # confusion with Workbook method of the same name. The following acts as an
1074
+ # alias for any code that uses the old name.
1075
+ # *set_properties = *set_format_properties;
1076
+
1077
+ # Dynamically create set methods that aren't already defined.
1078
+ def method_missing(name, *args)
1079
+ # -- original perl comment --
1080
+ # There are two types of set methods: set_property() and
1081
+ # set_property_color(). When a method is AUTOLOADED we store a new anonymous
1082
+ # sub in the appropriate slot in the symbol table. The speeds up subsequent
1083
+ # calls to the same method.
1084
+
1085
+ method = "#{name}"
1086
+
1087
+ # Check for a valid method names, i.e. "set_xxx_yyy".
1088
+ method =~ /set_(\w+)/ or raise "Unknown method: #{method}\n"
1089
+
1090
+ # Match the attribute, i.e. "@xxx_yyy".
1091
+ attribute = "@#{$1}"
1092
+
1093
+ # Check that the attribute exists
1094
+ # ........
1095
+ if method =~ /set\w+color$/ # for "set_property_color" methods
1096
+ value = get_color(args[0])
1097
+ else # for "set_xxx" methods
1098
+ value = args[0].nil? ? 1 : args[0]
1099
+ end
1100
+ if value.kind_of?(String)
1101
+ s = "#{attribute} = \"#{value.to_s}\""
1102
+ else
1103
+ s = "#{attribute} = #{value.to_s}"
1104
+ end
1105
+ eval s
1106
+ end
1107
+
1108
+ end