ru_excel 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,1930 @@
1
+ dir = File.dirname(__FILE__)
2
+ require dir+'/unicode_utils'
3
+
4
+ module Excel
5
+
6
+ class SharedStringTable
7
+ include UnicodeUtils
8
+ extend UnicodeUtils
9
+ SST_ID = 0x00FC
10
+ CONTINUE_ID = 0x003C
11
+
12
+ def initialize
13
+ @sst_record = ''
14
+ @continues = []
15
+ @current_piece = [ 0, 0].pack('VV')
16
+ @pos = @current_piece.length
17
+
18
+ @str_indexes = {}
19
+ @add_calls = 0
20
+ end
21
+
22
+ def add_str(s)
23
+ @add_calls += 1
24
+ unless (ret = @str_indexes[s])
25
+ ret = @str_indexes[s] = @str_indexes.length
26
+ add_to_sst(s)
27
+ end
28
+ ret
29
+ end
30
+
31
+ def str_index(s)
32
+ @str_indexes[s]
33
+ end
34
+
35
+ def get_biff_record
36
+ new_piece
37
+ result = [SST_ID, @sst_record.length, @add_calls, @str_indexes.length].pack('vvVV')
38
+ result << @sst_record[(8)..-1]
39
+ result << @continues.join('')
40
+ result
41
+ end
42
+
43
+ def add_to_sst(s)
44
+ u_str = upack2(s)
45
+ raise Exception('error=> very long string.') if u_str.length > 0xFFFF
46
+
47
+ is_unicode_str = u_str[2] == ?\1
48
+ if is_unicode_str
49
+ atom_len = 5 # 2 byte -- len,
50
+ # 1 byte -- options,
51
+ # 2 byte -- 1st sym
52
+ else
53
+ atom_len = 4 # 2 byte -- len,
54
+ # 1 byte -- options,
55
+ # 1 byte -- 1st sym
56
+ end
57
+
58
+ save_atom(u_str[(0)...(atom_len)])
59
+ save_splitted(u_str[(atom_len)..-1], is_unicode_str)
60
+ end
61
+
62
+ def new_piece
63
+ if @sst_record == ''
64
+ @sst_record = @current_piece
65
+ else
66
+ curr_piece_len = @current_piece.length
67
+ @continues << [ CONTINUE_ID, @current_piece.length, @current_piece].pack('vva*')
68
+ end
69
+ @current_piece = ''
70
+ @pos = @current_piece.length
71
+ end
72
+
73
+ def save_atom(s)
74
+ atom_len = s.length
75
+ free_space = 0x2020 - @current_piece.length
76
+ new_piece() if free_space < atom_len
77
+ @current_piece += s
78
+ end
79
+
80
+ def save_splitted(s, is_unicode_str)
81
+ i = 0
82
+ str_len = s.length
83
+ while i < str_len
84
+ piece_len = @current_piece.length
85
+ free_space = 0x2020 - piece_len
86
+ tail_len = str_len - i
87
+ need_more_space = free_space < tail_len
88
+
89
+ atom_len = need_more_space ? (is_unicode_str ? free_space & 0xFFFE : free_space) : tail_len
90
+
91
+ @current_piece += s[(i)...(i+atom_len)]
92
+
93
+ if need_more_space
94
+ new_piece()
95
+ @current_piece += is_unicode_str ? "\x01" : "\x00"
96
+ end
97
+ i += atom_len
98
+ end
99
+ end
100
+ end
101
+
102
+ module BiffRecord
103
+ include UnicodeUtils
104
+ BOOK_GLOBAL = 0x0005
105
+ VB_MODULE = 0x0006
106
+ WORKSHEET = 0x0010
107
+ CHART = 0x0020
108
+ MACROSHEET = 0x0040
109
+ WORKSPACE = 0x0100
110
+ def get_biff_data(rec_id, data)
111
+ if data.length > 0x2020
112
+ continues = [ [rec_id, 0x2020].pack(vv) << data[0, 0x2020] ]
113
+ 0x2020.step(data.length, 0x2020) do |i|
114
+ s = data[i, 0x2020]
115
+ continues << [ 0x003c, s.length].pack('vv') << s
116
+ end
117
+ continues.join('')
118
+ else
119
+ [rec_id, data.length].pack('vv') << data
120
+ end
121
+ end
122
+ self.extend self
123
+
124
+ def biff_pack_short(rec_id, short)
125
+ [rec_id, 2, short].pack('v3')
126
+ end
127
+
128
+ def biff_pack_bool(rec_id, bool)
129
+ [rec_id, 2, bool.to_i].pack('v3')
130
+ end
131
+
132
+ def biff_pack_double(rec_id, short)
133
+ [rec_id, 8, short].pack('v2E')
134
+ end
135
+ =begin
136
+ Offset Size Contents
137
+ 0 2 Version, contains 0600H for BIFF8 and BIFF8X
138
+ 2 2 Type of the following data
139
+ 0005H = Workbook globals
140
+ 0006H = Visual Basic module
141
+ 0010H = Worksheet
142
+ 0020H = Chart
143
+ 0040H = Macro sheet
144
+ 0100H = Workspace file
145
+ 4 2 Build identifier
146
+ 6 2 Build year
147
+ 8 4 File history flags
148
+ 12 4 Lowest Excel version that can read all records in this file
149
+ =end
150
+ def biff8BOFRecord(rec_type)
151
+ =begin
152
+ version = 0x0600
153
+ build = 0x0DBB
154
+ year = 0x07CC
155
+ file_hist_flags = 0x00L
156
+ ver_can_read = 0x06L
157
+ [ version, rec_type, build, year, file_hist_flags, ver_can_read].pack('<4H2I')
158
+ =end
159
+ get_biff_data( 0x0809, [0x0600, rec_type, 0x0DBB, 0x07CC, 0x00, 0x06].pack('v4V2') )
160
+ end
161
+
162
+ def self.default_record(name, rec_id, value)
163
+ name = name.to_s
164
+ module_eval <<-"END"
165
+ #{name.capitalize} = get_biff_data(#{rec_id.inspect}, #{value.inspect})
166
+ def #{name}
167
+ #{name.capitalize}
168
+ end
169
+ END
170
+ end
171
+
172
+ def self.default_record_short(name, rec_id, value)
173
+ default_record(name, rec_id, [value].pack('v'))
174
+ end
175
+ def self.default_record_zero(name, rec_id)
176
+ default_record_short(name, rec_id, 0)
177
+ end
178
+ def self.short_record(name, rec_id)
179
+ module_eval <<-"END"
180
+ def #{name}(value)
181
+ biff_pack_short(#{rec_id.inspect}, value)
182
+ end
183
+ END
184
+ end
185
+ def self.bool_record(name, rec_id)
186
+ module_eval <<-"END"
187
+ def #{name}(value)
188
+ biff_pack_bool(#{rec_id.inspect}, value)
189
+ end
190
+ END
191
+ end
192
+ def self.double_record(name, rec_id)
193
+ module_eval <<-"END"
194
+ def #{name}(value)
195
+ biff_pack_double(#{rec_id.inspect}, value)
196
+ end
197
+ END
198
+ end
199
+ default_record(:interaceHdrRecord, 0x00E1, "\xB0\x04")
200
+ default_record(:interaceEndRecord, 0x00E2, "")
201
+ default_record_zero(:mmsRecord, 0x00C1)
202
+
203
+ =begin
204
+ This record is part of the file protection. It contains the name of the
205
+ user that has saved the file. The user name is always stored as an
206
+ equal-sized string. All unused characters after the name are filled
207
+ with space characters. It is not required to write the mentioned string
208
+ length. Every other length will be accepted too.
209
+ =end
210
+ def writeAccessRecord(owner)
211
+ get_biff_data(0x005c, [owner[0,0x30]].pack('A112'))
212
+ end
213
+
214
+ =begin
215
+ This record specifies if the file contains an additional BIFF5/BIFF7
216
+ workbook stream.
217
+ Record DSF, BIFF8
218
+ Offset Size Contents
219
+ 0 2 0 = Only the BIFF8 Workbook stream is present
220
+ 1 = Additional BIFF5/BIFF7 Book stream is in the file
221
+ A double stream file can be read by Excel 5.0 and Excel 95, and still
222
+ contains all new features added to BIFF8 (which are left out in the
223
+ BIFF5/BIFF7 Book stream).
224
+ =end
225
+ default_record_zero(:dsfRecord, 0x0161)
226
+
227
+ def tabIDRecord(sheetcount)
228
+ get_biff_data( 0x013D, (0...sheetcount).to_a.pack('v*'))
229
+ end
230
+
231
+ default_record(:fnGroupCountRecord, 0x009C, [ 0x0E, 0x00].pack('CC'))
232
+
233
+ =begin
234
+ This record is part of the worksheet/workbook protection. It determines
235
+ whether the window configuration of this document is protected. Window
236
+ protection is not active, if this record is omitted.
237
+ =end
238
+ short_record(:windowProtectRecord, 0x0019)
239
+
240
+ =begin
241
+ This record is part of the worksheet/workbook protection.
242
+ It determines whether the objects of the current sheet are protected.
243
+ Object protection is not active, if this record is omitted.
244
+ =end
245
+ short_record(:objectProtectRecord, 0x0063)
246
+
247
+ =begin
248
+ This record is part of the worksheet/workbook protection. It
249
+ determines whether the scenarios of the current sheet are protected.
250
+ Scenario protection is not active, if this record is omitted.
251
+ =end
252
+ short_record(:scenProtectRecord, 0x00DD)
253
+
254
+ =begin
255
+ This record is part of the worksheet/workbook protection. It specifies
256
+ whether a worksheet or a workbook is protected against modification.
257
+ Protection is not active, if this record is omitted.
258
+ =end
259
+ short_record(:protectRecord, 0x0012)
260
+
261
+ =begin
262
+ This record is part of the worksheet/workbook protection. It
263
+ stores a 16-bit hash value, calculated from the worksheet or workbook
264
+ protection password.
265
+ =end
266
+ def passwordRecord(passwd='')
267
+ if passwd == ''
268
+ hash = 0
269
+ else
270
+ hash = 0xCE4B
271
+ i = 1
272
+ passwd.each_byte do |c|
273
+ c <<= i
274
+ hash ^= (c & 0x7fff) | ((c >> 15) & 0x7fff)
275
+ i+=1
276
+ end
277
+ hash ^= passwd.length
278
+ end
279
+ biff_pack_short( 0x0013, hash)
280
+ end
281
+
282
+ default_record_zero(:prot4RevRecord, 0x01AF)
283
+ default_record_zero(:prot4RevPassRecord, 0x01BC)
284
+
285
+ =begin
286
+ This record contains a Boolean value determining whether Excel makes
287
+ a backup of the file while saving.
288
+ =end
289
+ short_record(:backupRecord, 0x0040)
290
+
291
+ =begin
292
+ This record specifies whether and how to show objects in the workbook.
293
+
294
+ Record HIDEOBJ, BIFF3-BIFF8
295
+ Offset Size Contents
296
+ 0 2 Viewing mode for objects
297
+ 0 = Show all objects
298
+ 1 = Show placeholders
299
+ 2 = Do not show objects
300
+ =end
301
+ default_record_zero(:hideObjRecord, 0x008D)
302
+
303
+ default_record_zero(:refreshAllRecord, 0x01B7)
304
+
305
+ =begin
306
+ This record contains a Boolean value determining whether to save values
307
+ linked from external workbooks (CRN records and XCT records). In BIFF3
308
+ and BIFF4 this option is stored in the WSBOOL record.
309
+
310
+ Record BOOKBOOL, BIFF5-BIFF8
311
+
312
+ Offset Size Contents
313
+ 0 2 0 = Save external linked values;
314
+ 1 = Do not save external linked values
315
+ =end
316
+ default_record_zero(:bookBoolRecord, 0x00DA)
317
+
318
+ =begin
319
+ This record stores two Windows country identifiers. The first
320
+ represents the user interface language of the Excel version that has
321
+ saved the file, and the second represents the system regional settings
322
+ at the time the file was saved.
323
+
324
+ Record COUNTRY, BIFF3-BIFF8
325
+
326
+ Offset Size Contents
327
+ 0 2 Windows country identifier of the user interface language of Excel
328
+ 2 2 Windows country identifier of the system regional settings
329
+
330
+ The following table shows most of the used country identifiers. Most
331
+ of these identifiers are equal to the international country calling
332
+ codes.
333
+
334
+ 1 USA
335
+ 2 Canada
336
+ 7 Russia
337
+ =end
338
+ def countryRecord(ui_id, sys_settings_id)
339
+ get_biff_data(0x00DA, [ ui_id, sys_settings_id].pack('v2') )
340
+ end
341
+
342
+ =begin
343
+ This record specifies if the formulas in the workbook can use natural
344
+ language formulas�. This type of formula can refer to cells by its
345
+ content or the content of the column or row header cell.
346
+
347
+ Record USESELFS, BIFF8
348
+
349
+ Offset Size Contents
350
+ 0 2 0 = Do not use natural language formulas
351
+ 1 = Use natural language formulas
352
+ =end
353
+ default_record_short(:useSelfsRecord, 0x0160, 0x01)
354
+
355
+ default_record(:eofRecord, 0x000A, '')
356
+
357
+ =begin
358
+ This record specifies the base date for displaying date values. All
359
+ dates are stored as count of days past this base date. In BIFF2-BIFF4
360
+ this record is part of the Calculation Settings Block.
361
+ In BIFF5-BIFF8 it is stored in the Workbook Globals Substream.
362
+
363
+ Record DATEMODE, BIFF2-BIFF8
364
+
365
+ Offset Size Contents
366
+ 0 2 0 = Base is 1899-Dec-31 (the cell = 1 represents 1900-Jan-01)
367
+ 1 = Base is 1904-Jan-01 (the cell = 1 represents 1904-Jan-02)
368
+ =end
369
+ bool_record(:dateModeRecord, 0x0022)
370
+
371
+ =begin
372
+ This record stores if formulas use the real cell values for calculation
373
+ or the values displayed on the screen. In BIFF2- BIFF4 this record
374
+ is part of the Calculation Settings Block. In BIFF5-BIFF8 it is stored
375
+ in the Workbook Globals Substream.
376
+
377
+ Record PRECISION, BIFF2-BIFF8
378
+
379
+ Offset Size Contents
380
+ 0 2 0 = Use displayed values;
381
+ 1 = Use real cell values
382
+ =end
383
+ bool_record(:precisionRecord, 0x000E)
384
+
385
+ =begin
386
+ This record stores the text encoding used to write byte strings, stored
387
+ as MS Windows code page identifier. The CODEPAGE record in BIFF8 always
388
+ contains the code page 1200 (UTF-16). Therefore it is not
389
+ possible to obtain the encoding used for a protection password (it is
390
+ not UTF-16).
391
+
392
+ Record CODEPAGE, BIFF2-BIFF8
393
+
394
+ Offset Size Contents
395
+ 0 2 Code page identifier used for byte string text encoding
396
+ 016FH = 367 = ASCII
397
+ 01B5H = 437 = IBM PC CP-437 (US)
398
+ 02D0H = 720 = IBM PC CP-720 (OEM Arabic)
399
+ 02E1H = 737 = IBM PC CP-737 (Greek)
400
+ 0307H = 775 = IBM PC CP-775 (Baltic)
401
+ 0352H = 850 = IBM PC CP-850 (Latin I)
402
+ 0354H = 852 = IBM PC CP-852 (Latin II (Central European))
403
+ 0357H = 855 = IBM PC CP-855 (Cyrillic)
404
+ 0359H = 857 = IBM PC CP-857 (Turkish)
405
+ 035AH = 858 = IBM PC CP-858 (Multilingual Latin I with Euro)
406
+ 035CH = 860 = IBM PC CP-860 (Portuguese)
407
+ 035DH = 861 = IBM PC CP-861 (Icelandic)
408
+ 035EH = 862 = IBM PC CP-862 (Hebrew)
409
+ 035FH = 863 = IBM PC CP-863 (Canadian (French))
410
+ 0360H = 864 = IBM PC CP-864 (Arabic)
411
+ 0361H = 865 = IBM PC CP-865 (Nordic)
412
+ 0362H = 866 = IBM PC CP-866 (Cyrillic (Russian))
413
+ 0365H = 869 = IBM PC CP-869 (Greek (Modern))
414
+ 036AH = 874 = Windows CP-874 (Thai)
415
+ 03A4H = 932 = Windows CP-932 (Japanese Shift-JIS)
416
+ 03A8H = 936 = Windows CP-936 (Chinese Simplified GBK)
417
+ 03B5H = 949 = Windows CP-949 (Korean (Wansung))
418
+ 03B6H = 950 = Windows CP-950 (Chinese Traditional BIG5)
419
+ 04B0H = 1200 = UTF-16 (BIFF8)
420
+ 04E2H = 1250 = Windows CP-1250 (Latin II) (Central European)
421
+ 04E3H = 1251 = Windows CP-1251 (Cyrillic)
422
+ 04E4H = 1252 = Windows CP-1252 (Latin I) (BIFF4-BIFF7)
423
+ 04E5H = 1253 = Windows CP-1253 (Greek)
424
+ 04E6H = 1254 = Windows CP-1254 (Turkish)
425
+ 04E7H = 1255 = Windows CP-1255 (Hebrew)
426
+ 04E8H = 1256 = Windows CP-1256 (Arabic)
427
+ 04E9H = 1257 = Windows CP-1257 (Baltic)
428
+ 04EAH = 1258 = Windows CP-1258 (Vietnamese)
429
+ 0551H = 1361 = Windows CP-1361 (Korean (Johab))
430
+ 2710H = 10000 = Apple Roman
431
+ 8000H = 32768 = Apple Roman
432
+ 8001H = 32769 = Windows CP-1252 (Latin I) (BIFF2-BIFF3)
433
+ =end
434
+ UTF_16 = 0x04B0
435
+ default_record_short(:codepageBiff8Record, 0x0042, 0x04b0)
436
+
437
+ =begin
438
+ Offset Size Contents
439
+ 0 2 Horizontal position of the document window (in twips = 1/20 of a point)
440
+ 2 2 Vertical position of the document window (in twips = 1/20 of a point)
441
+ 4 2 Width of the document window (in twips = 1/20 of a point)
442
+ 6 2 Height of the document window (in twips = 1/20 of a point)
443
+ 8 2 Option flags
444
+ Bits Mask Contents
445
+ 0 0001H 0 = Window is visible 1 = Window is hidden
446
+ 1 0002H 0 = Window is open 1 = Window is minimised
447
+ 3 0008H 0 = Horizontal scroll bar hidden 1 = Horizontal scroll bar visible
448
+ 4 0010H 0 = Vertical scroll bar hidden 1 = Vertical scroll bar visible
449
+ 5 0020H 0 = Worksheet tab bar hidden 1 = Worksheet tab bar visible
450
+ 10 2 Index to active (displayed) worksheet
451
+ 12 2 Index of first visible tab in the worksheet tab bar
452
+ 14 2 Number of selected worksheets (highlighted in the worksheet tab bar)
453
+ 16 2 Width of worksheet tab bar (in 1/1000 of window width). The remaining space is used by the
454
+ horizontal scrollbar.
455
+ =end
456
+
457
+ def window1Record(
458
+ hpos_twips, vpos_twips,
459
+ width_twips, height_twips,
460
+ flags,
461
+ active_sheet,
462
+ first_tab_index, selected_tabs, tab_width)
463
+ get_biff_data(0x003D, [ hpos_twips, vpos_twips,
464
+ width_twips, height_twips,
465
+ flags,
466
+ active_sheet,
467
+ first_tab_index, selected_tabs, tab_width].pack('v*') )
468
+ end
469
+
470
+ =begin
471
+ WARNING
472
+ The font with index 4 is omitted in all BIFF versions.
473
+ This means the first four fonts have zero-based indexes, and
474
+ the fifth font and all following fonts are referenced with one-based
475
+ indexes.
476
+
477
+ Offset Size Contents
478
+ 0 2 Height of the font (in twips = 1/20 of a point)
479
+ 2 2 Option flags
480
+ Bit Mask Contents
481
+ 0 0001H 1 = Characters are bold (redundant, see below)
482
+ 1 0002H 1 = Characters are italic
483
+ 2 0004H 1 = Characters are underlined (redundant, see below)
484
+ 3 0008H 1 = Characters are struck out
485
+ 0010H 1 = Outline
486
+ 0020H 1 = Shadow
487
+ 4 2 Colour index
488
+ 6 2 Font weight (100-1000).
489
+ Standard values are 0190H (400) for normal text and 02BCH
490
+ (700) for bold text.
491
+ 8 2 Escapement type
492
+ 0000H = None
493
+ 0001H = Superscript
494
+ 0002H = Subscript
495
+ 10 1 Underline type
496
+ 00H = None
497
+ 01H = Single
498
+ 21H = Single accounting
499
+ 02H = Double
500
+ 22H = Double accounting
501
+ 11 1 Font family
502
+ 00H = None (unknown or don't care)
503
+ 01H = Roman (variable width, serifed)
504
+ 02H = Swiss (variable width, sans-serifed)
505
+ 03H = Modern (fixed width, serifed or sans-serifed)
506
+ 04H = Script (cursive)
507
+ 05H = Decorative (specialised, i.e. Old English, Fraktur)
508
+ 12 1 Character set
509
+ 00H = 0 = ANSI Latin
510
+ 01H = 1 = System default
511
+ 02H = 2 = Symbol
512
+ 4DH = 77 = Apple Roman
513
+ 80H = 128 = ANSI Japanese Shift-JIS
514
+ 81H = 129 = ANSI Korean (Hangul)
515
+ 82H = 130 = ANSI Korean (Johab)
516
+ 86H = 134 = ANSI Chinese Simplified GBK
517
+ 88H = 136 = ANSI Chinese Traditional BIG5
518
+ A1H = 161 = ANSI Greek
519
+ A2H = 162 = ANSI Turkish
520
+ A3H = 163 = ANSI Vietnamese
521
+ B1H = 177 = ANSI Hebrew
522
+ B2H = 178 = ANSI Arabic
523
+ BAH = 186 = ANSI Baltic
524
+ CCH = 204 = ANSI Cyrillic
525
+ DEH = 222 = ANSI Thai
526
+ EEH = 238 = ANSI Latin II (Central European)
527
+ FFH = 255 = OEM Latin I
528
+ 13 1 Not used
529
+ 14 var. Font name
530
+ BIFF5/BIFF7=> Byte string, 8-bit string length
531
+ BIFF8=> Unicode string, 8-bit string length
532
+ The boldness and underline flags are still set in the options field,
533
+ but not used on reading the font. Font weight and underline type
534
+ are specified in separate fields instead.
535
+ =end
536
+
537
+ def fontRecord(
538
+ height, options, colour_index, weight, escapement,
539
+ underline, family, charset,
540
+ name)
541
+
542
+ get_biff_data( 0x0031, [ height, options, colour_index, weight, escapement,
543
+ underline, family, charset, 0x00,
544
+ upack1(name)].pack('v5C4a*') )
545
+ end
546
+
547
+ =begin
548
+ Record FORMAT, BIFF8
549
+ Offset Size Contents
550
+ 0 2 Format index used in other records
551
+ 2 var. Number format string (Unicode string, 16-bit string length)
552
+
553
+ From BIFF5 on, the built-in number formats will be omitted. The built-in
554
+ formats are dependent on the current regional settings of the operating
555
+ system. The following table shows which number formats are used by default
556
+ in a US-English environment. All indexes from 0 to 163 are reserved for
557
+ built-in formats. The first user-defined format starts at 164.
558
+
559
+ The built-in number formats, BIFF5-BIFF8
560
+
561
+ Index Type Format string
562
+ 0 General General
563
+ 1 Decimal 0
564
+ 2 Decimal 0.00
565
+ 3 Decimal #,##0
566
+ 4 Decimal #,##0.00
567
+ 5 Currency "$"#,##0_);("$"#,##
568
+ 6 Currency "$"#,##0_);[Red]("$"#,##
569
+ 7 Currency "$"#,##0.00_);("$"#,##
570
+ 8 Currency "$"#,##0.00_);[Red]("$"#,##
571
+ 9 Percent 0%
572
+ 10 Percent 0.00%
573
+ 11 Scientific 0.00E+00
574
+ 12 Fraction # ?/?
575
+ 13 Fraction # ??/??
576
+ 14 Date M/D/YY
577
+ 15 Date D-MMM-YY
578
+ 16 Date D-MMM
579
+ 17 Date MMM-YY
580
+ 18 Time h:mm AM/PM
581
+ 19 Time h:mm:ss AM/PM
582
+ 20 Time h:mm
583
+ 21 Time h:mm:ss
584
+ 22 Date/Time M/D/YY h:mm
585
+ 37 Account _(#,##0_);(#,##0)
586
+ 38 Account _(#,##0_);[Red](#,##0)
587
+ 39 Account _(#,##0.00_);(#,##0.00)
588
+ 40 Account _(#,##0.00_);[Red](#,##0.00)
589
+ 41 Currency _("$"* #,##0_);_("$"* (#,##0);_("$"* "-"_);_(@_)
590
+ 42 Currency _(* #,##0_);_(* (#,##0);_(* "-"_);_(@_)
591
+ 43 Currency _("$"* #,##0.00_);_("$"* (#,##0.00);_("$"* "-"??_);_(@_)
592
+ 44 Currency _(* #,##0.00_);_(* (#,##0.00);_(* "-"??_);_(@_)
593
+ 45 Time mm:ss
594
+ 46 Time [h]:mm:ss
595
+ 47 Time mm:ss.0
596
+ 48 Scientific ##0.0E+0
597
+ 49 Text @
598
+ =end
599
+ def numberFormatRecord(idx, fmtstr)
600
+ get_biff_data(0x041E, [ idx, upack2(fmtstr)].pack('va'))
601
+ end
602
+
603
+
604
+ =begin
605
+ XF Substructures
606
+ -------------------------------------------------------------------------
607
+ XF_TYPE_PROT XF Type and Cell Protection (3 Bits), BIFF3-BIFF8
608
+ These 3 bits are part of a specific data byte.
609
+ Bit Mask Contents
610
+ 0 01H 1 = Cell is locked
611
+ 1 02H 1 = Formula is hidden
612
+ 2 04H 0 = Cell XF; 1 = Style XF
613
+
614
+ XF_USED_ATTRIB Attributes Used from Parent Style XF (6 Bits),
615
+ BIFF3-BIFF8 Each bit describes the validity of a specific group
616
+ of attributes. In cell XFs a cleared bit means the attributes of the
617
+ parent style XF are used (but only if the attributes are valid there),
618
+ a set bit means the attributes of this XF are used. In style XFs
619
+ a cleared bit means the attribute setting is valid, a set bit means the
620
+ attribute should be ignored.
621
+ Bit Mask Contents
622
+ 0 01H Flag for number format
623
+ 1 02H Flag for font
624
+ 2 04H Flag for horizontal and vertical alignment, text wrap, indentation, orientation, rotation, and
625
+ text direction
626
+ 3 08H Flag for border lines
627
+ 4 10H Flag for background area style
628
+ 5 20H Flag for cell protection (cell locked and formula hidden)
629
+
630
+ XF_HOR_ALIGN Horizontal Alignment (3 Bits), BIFF2-BIFF8 The horizontal
631
+ alignment consists of 3 bits and is part of a specific data byte.
632
+ Value Horizontal alignment
633
+ 00H General
634
+ 01H Left
635
+ 02H Centred
636
+ 03H Right
637
+ 04H Filled
638
+ 05H Justified (BIFF4-BIFF8X)
639
+ 06H Centred across selection (BIFF4-BIFF8X)
640
+ 07H Distributed (BIFF8X)
641
+
642
+ XF_VERT_ALIGN Vertical Alignment (2 or 3 Bits), BIFF4-BIFF8
643
+ The vertical alignment consists of 2 bits (BIFF4) or 3 bits (BIFF5-BIFF8)
644
+ and is part of a specific data byte. Vertical alignment is not available
645
+ in BIFF2 and BIFF3.
646
+ Value Vertical alignment
647
+ 00H Top
648
+ 01H Centred
649
+ 02H Bottom
650
+ 03H Justified (BIFF5-BIFF8X)
651
+ 04H Distributed (BIFF8X)
652
+
653
+ XF_ORIENTATION Text Orientation (2 Bits), BIFF4-BIFF7 In the BIFF
654
+ versions BIFF4-BIFF7, text can be rotated in steps of 90 degrees
655
+ or stacked. The orientation mode consists of 2 bits and is part of
656
+ a specific data byte. In BIFF8 a rotation angle occurs instead of these
657
+ flags.
658
+ Value Text orientation
659
+ 00H Not rotated
660
+ 01H Letters are stacked top-to-bottom, but not rotated
661
+ 02H Text is rotated 90 degrees counterclockwise
662
+ 03H Text is rotated 90 degrees clockwise
663
+
664
+ XF_ROTATION Text Rotation Angle (1 Byte), BIFF8
665
+ Value Text rotation
666
+ 0 Not rotated
667
+ 1-90 1 to 90 degrees counterclockwise
668
+ 91-180 1 to 90 degrees clockwise
669
+ 255 Letters are stacked top-to-bottom, but not rotated
670
+
671
+ XF_BORDER_34 Cell Border Style (4 Bytes), BIFF3-BIFF4 Cell borders
672
+ contain a line style and a line colour for each line of the border.
673
+ Bit Mask Contents
674
+ 2-0 00000007H Top line style
675
+ 7-3 000000F8H Colour index for top line colour
676
+ 10-8 00000700H Left line style
677
+ 15-11 0000F800H Colour index for left line colour
678
+ 18-16 00070000H Bottom line style
679
+ 23-19 00F80000H Colour index for bottom line colour
680
+ 26-24 07000000H Right line style
681
+ 31-27 F8000000H Colour index for right line colour
682
+
683
+ XF_AREA_34 Cell Background Area Style (2 Bytes), BIFF3-BIFF4 A cell
684
+ background area style contains an area pattern and a foreground and
685
+ background colour.
686
+ Bit Mask Contents
687
+ 5-0 003FH Fill pattern
688
+ 10-6 07C0H Colour index for pattern colour
689
+ 15-11 F800H Colour index for pattern background
690
+ ---------------------------------------------------------------------------------------------
691
+ Record XF, BIFF8
692
+ Offset Size Contents
693
+ 0 2 Index to FONT record
694
+ 2 2 Index to FORMAT record
695
+ 4 2 Bit Mask Contents
696
+ 2-0 0007H XF_TYPE_PROT . XF type, cell protection (see above)
697
+ 15-4 FFF0H Index to parent style XF (always FFFH in style XFs)
698
+ 6 1 Bit Mask Contents
699
+ 2-0 07H XF_HOR_ALIGN . Horizontal alignment (see above)
700
+ 3 08H 1 = Text is wrapped at right border
701
+ 6-4 70H XF_VERT_ALIGN . Vertical alignment (see above)
702
+ 7 1 XF_ROTATION=> Text rotation angle (see above)
703
+ 8 1 Bit Mask Contents
704
+ 3-0 0FH Indent level
705
+ 4 10H 1 = Shrink content to fit into cell
706
+ 5 merge
707
+ 7-6 C0H Text direction (BIFF8X only)
708
+ 00b = According to context
709
+ 01b = Left-to-right
710
+ 10b = Right-to-left
711
+ 9 1 Bit Mask Contents
712
+ 7-2 FCH XF_USED_ATTRIB . Used attributes (see above)
713
+ 10 4 Cell border lines and background area
714
+ Bit Mask Contents
715
+ 3-0 0000000FH Left line style
716
+ 7-4 000000F0H Right line style
717
+ 11-8 00000F00H Top line style
718
+ 15-12 0000F000H Bottom line style
719
+ 22-16 007F0000H Colour index for left line colour
720
+ 29-23 3F800000H Colour index for right line colour
721
+ 30 40000000H 1 = Diagonal line from top left to right bottom
722
+ 31 80000000H 1 = Diagonal line from bottom left to right top
723
+ 14 4 Bit Mask Contents
724
+ 6-0 0000007FH Colour index for top line colour
725
+ 13-7 00003F80H Colour index for bottom line colour
726
+ 20-14 001FC000H Colour index for diagonal line colour
727
+ 24-21 01E00000H Diagonal line style
728
+ 31-26 FC000000H Fill pattern
729
+ 18 2 Bit Mask Contents
730
+ 6-0 007FH Colour index for pattern colour
731
+ 13-7 3F80H Colour index for pattern background
732
+ =end
733
+ #rec_id 0x00E0
734
+
735
+ def xfRecord(xf, xftype='cell')
736
+
737
+ font_xf_idx, fmt_str_xf_idx, alignment, borders, pattern, protection = xf
738
+ prt = xftype == 'cell' ?
739
+ (((protection.cell_locked & 0x01) << 0) |
740
+ ((protection.formula_hidden & 0x01) << 1)) : 0xFFF5
741
+ aln =
742
+ ((alignment.horz & 0x07) << 0) |
743
+ ((alignment.wrap & 0x01) << 3) |
744
+ ((alignment.vert & 0x07) << 4)
745
+ rot = alignment.rota
746
+ txt =
747
+ ((alignment.inde & 0x0F) << 0) |
748
+ ((alignment.shri & 0x01) << 4) |
749
+ ((alignment.merg & 0x01) << 5) |
750
+ ((alignment.dire & 0x03) << 6)
751
+ used_attr = xftype == 'cell' ? 0xF8 : 0xF4
752
+
753
+ borders.left_colour = 0x00 if borders.left == Excel::Borders::NO_LINE
754
+ borders.right_colour = 0x00 if borders.right == Excel::Borders::NO_LINE
755
+ borders.top_colour = 0x00 if borders.top == Excel::Borders::NO_LINE
756
+ borders.bottom_colour = 0x00 if borders.bottom == Excel::Borders::NO_LINE
757
+ borders.diag_colour = 0x00 if borders.diag == Excel::Borders::NO_LINE
758
+
759
+ brd1 =
760
+ ((borders.left & 0x0F) << 0 ) |
761
+ ((borders.right & 0x0F) << 4 ) |
762
+ ((borders.top & 0x0F) << 8 ) |
763
+ ((borders.bottom & 0x0F) << 12) |
764
+ ((borders.left_colour & 0x7F) << 16) |
765
+ ((borders.right_colour & 0x7F) << 23) |
766
+ ((borders.need_diag1 & 0x01) << 30) |
767
+ ((borders.need_diag2 & 0x01) << 31)
768
+ brd2 =
769
+ ((borders.top_colour & 0x7F) << 0 ) |
770
+ ((borders.bottom_colour & 0x7F) << 7 ) |
771
+ ((borders.diag_colour & 0x7F) << 14) |
772
+ ((borders.diag & 0x0F) << 21) |
773
+ ((pattern.pattern & 0x0F) << 26)
774
+ pat =
775
+ ((pattern.pattern_fore_colour & 0x7F) << 0 ) |
776
+ ((pattern.pattern_back_colour & 0x7F) << 7 )
777
+ get_biff_data( 0x00E0, [font_xf_idx, fmt_str_xf_idx,
778
+ prt, aln, rot, txt, used_attr,
779
+ brd1, brd2, pat].pack('vvvCCCCVVv') )
780
+ end
781
+
782
+ =begin
783
+ STYLE record for user-defined cell styles, BIFF3-BIFF8
784
+ Offset Size Contents
785
+ 0 2 Bit Mask Contents
786
+ 11-0 0FFFH Index to style XF record
787
+ 15 8000H Always 0 for user-defined styles
788
+ 2 var. BIFF2-BIFF7=> Non-empty byte string, 8-bit string length
789
+ BIFF8=> Non-empty Unicode string, 16-bit string length
790
+ STYLE record for built-in cell styles, BIFF3-BIFF8
791
+ Offset Size Contents
792
+ 0 2 Bit Mask Contents
793
+ 11-0 0FFFH Index to style XF record
794
+ 15 8000H Always 1 for built-in styles
795
+ 2 1 Identifier of the built-in cell style
796
+ 00H = Normal
797
+ 01H = RowLevel_lv (see next field)
798
+ 02H = ColLevel_lv (see next field)
799
+ 03H = Comma
800
+ 04H = Currency
801
+ 05H = Percent
802
+ 06H = Comma [0] (BIFF4-BIFF8)
803
+ 07H = Currency [0] (BIFF4-BIFF8)
804
+ 08H = Hyperlink (BIFF8)
805
+ 09H = Followed Hyperlink (BIFF8)
806
+ 3 1 Level for RowLevel or ColLevel style
807
+ (zero-based, lv), FFH otherwise
808
+ The RowLevel and ColLevel styles specify the formatting of subtotal
809
+ cells in a specific outline level. The level is specified by the last
810
+ field in the STYLE record. Valid values are 0-6 for the outline levels
811
+ 1-7.
812
+ =end
813
+ default_record(:styleRecord, 0x0293, [ 0x8000, 0x00, 0xFF].pack('vCC'))
814
+ # TODO: implement user-defined styles???
815
+
816
+ #class BoundSheetRecord < BiffRecord
817
+ =begin
818
+ This record is located in the workbook globals area and represents
819
+ a sheet inside of the workbook. For each sheet a BOUNDSHEET record
820
+ is written. It stores the sheet name and a stream offset to the BOF
821
+ record within the workbook stream. The record is also known
822
+ as BUNDLESHEET.
823
+
824
+ Record BOUNDSHEET, BIFF5-BIFF8
825
+ Offset Size Contents
826
+ 0 4 Absolute stream position of the BOF record of the sheet represented by this record. This
827
+ field is never encrypted in protected files.
828
+ 4 1 Visibility
829
+ 00H = Visible
830
+ 01H = Hidden
831
+ 02H = Strong hidden
832
+ 5 1 Sheet type
833
+ 00H = Worksheet
834
+ 02H = Chart
835
+ 06H = Visual Basic module
836
+ 6 var. Sheet name
837
+ BIFF5/BIFF7=> Byte string, 8-bit string length
838
+ BIFF8=> Unicode string, 8-bit string length
839
+ =end
840
+ #rec_id 0x0085
841
+
842
+ def boundSheetRecord(stream_pos, visibility, sheetname)
843
+ usheetname = upack1(sheetname)
844
+ uusheetname_len = usheetname.length
845
+ get_biff_data(0x0085, [ stream_pos, visibility.to_i, 0x00, usheetname].pack('VCCa*'))
846
+ end
847
+
848
+
849
+ #class ContinueRecord < BiffRecord
850
+ =begin
851
+ Whenever the content of a record exceeds the given limits (see table),
852
+ the record must be split. Several CONTINUE records containing the
853
+ additional data are added after the parent record.
854
+
855
+ BIFF version Maximum data size of a record
856
+ BIFF2-BIFF7 2080 bytes (2084 bytes including record header)
857
+ BIFF8 8224 bytes (8228 bytes including record header) (0x2020)
858
+
859
+ Record CONTINUE, BIFF2-BIFF8
860
+ Offset Size Contents
861
+ 0 var. Data continuation of the previous record
862
+
863
+ Unicode strings are split in a special way. At the beginning of each
864
+ CONTINUE record the option flags byte is repeated. Only the character
865
+ size flag will be set in this flags byte, the Rich-Text flag and the
866
+ Far-East flag are set to zero. In each CONTINUE record it is possible
867
+ that the character size changes from 8-bit characters to 16-bit
868
+ characters and vice versa.
869
+
870
+ Never a Unicode string is split until and including the first
871
+ character. That means, all header fields (string length, option flags,
872
+ optional Rich-Text size, and optional Far-East data size) and the first
873
+ character of the string have to occur together in the leading record,
874
+ or have to be moved completely into the CONTINUE record. Formatting
875
+ runs cannot be split between their components (character index and FONT
876
+ record index). If a string is split between two formatting runs, the
877
+ option flags field will not be repeated in the CONTINUE record.
878
+ =end
879
+ # rec_id 0x003C
880
+
881
+
882
+ #class SSTRecord < BiffRecord
883
+ =begin
884
+ This record contains a list of all strings used anywhere in the
885
+ workbook. Each string occurs only once. The workbook uses indexes into
886
+ the list to reference the strings.
887
+
888
+ Record SST, BIFF8
889
+ Offset Size Contents
890
+ 0 4 Total number of strings in the workbook (see below)
891
+ 4 4 Number of following strings (nm)
892
+ 8 var. List of nm Unicode strings, 16-bit string length
893
+
894
+ The first field of the SST record counts the total occurrence
895
+ of strings in the workbook. For instance, the string AAA is used
896
+ 3 times and the string BBB is used 2 times. The first field contains
897
+ 5 and the second field contains 2, followed by the two strings.
898
+ =end
899
+ # rec_id 0x00FC
900
+
901
+
902
+ #class ExtSSTRecord < BiffRecord
903
+ =begin
904
+ This record occurs in conjunction with the SST record. It is used
905
+ by Excel to create a hash table with stream offsets to the SST record
906
+ to optimise string search operations. Excel may not shorten this record
907
+ if strings are deleted from the shared string table, so the last part
908
+ might contain invalid data. The stream indexes in this record divide
909
+ the SST into portions containing a constant number of strings.
910
+
911
+ Record EXTSST, BIFF8
912
+
913
+ Offset Size Contents
914
+ 0 2 Number of strings in a portion, this number is >=8
915
+ 2 var. List of OFFSET structures for all portions. Each OFFSET contains the following data
916
+ Offset Size Contents
917
+ 0 4 Absolute stream position of first string of the portion
918
+ 4 2 Position of first string of the portion inside of current record,
919
+ including record header. This counter restarts at zero, if the SST
920
+ record is continued with a CONTINUE record.
921
+ 6 2 Not used
922
+ =end
923
+
924
+ def extSSTRecord(sst_stream_pos, str_placement, portions_len)
925
+
926
+ extsst = {}
927
+ abs_stream_pos = sst_stream_pos
928
+ str_counter = 0
929
+ portion_counter = 0
930
+ while str_counter < str_placement.length
931
+ str_chunk_num, pos_in_chunk = str_placement[str_counter]
932
+ if str_chunk_num != portion_counter
933
+ portion_counter = str_chunk_num
934
+ abs_stream_pos += portions_len[portion_counter-1]
935
+ #print hex(abs_stream_pos)
936
+ end
937
+ str_stream_pos = abs_stream_pos + pos_in_chunk + 4 # header
938
+ extsst[str_counter] = [pos_in_chunk, str_stream_pos]
939
+ str_counter += 1
940
+ end
941
+ exsst_str_count_delta = [8, str_placement.length*8 / 0x2000].max # maybe smth else?
942
+ rec_data = [ exsst_str_count_delta].pack('v')
943
+ str_counter = 0
944
+ rec_data = ''
945
+ while str_counter < str_placement.length
946
+ rec_data << [ extsst[str_counter][1], extsst[str_counter][0], 0].pack('Vvv')
947
+ str_counter += exsst_str_count_delta
948
+ end
949
+
950
+ get_biff_data(0x00FF, rec_data)
951
+ end
952
+
953
+ #class DimensionsRecord < BiffRecord
954
+ =begin
955
+ Record DIMENSIONS, BIFF8
956
+
957
+ Offset Size Contents
958
+ 0 4 Index to first used row
959
+ 4 4 Index to last used row, increased by 1
960
+ 8 2 Index to first used column
961
+ 10 2 Index to last used column, increased by 1
962
+ 12 2 Not used
963
+ =end
964
+ # rec_id 0x0200
965
+ def dimensionsRecord(first_used_row, last_used_row, first_used_col, last_used_col)
966
+ get_biff_data(0x0200, [
967
+ first_used_row, last_used_row + 1,
968
+ first_used_col, last_used_col + 1,
969
+ 0x00].pack('V2v3'))
970
+ end
971
+
972
+
973
+ #class Window2Record < BiffRecord
974
+ =begin
975
+ Record WINDOW2, BIFF8
976
+
977
+ Offset Size Contents
978
+ 0 2 Option flags (see below)
979
+ 2 2 Index to first visible row
980
+ 4 2 Index to first visible column
981
+ 6 2 Colour index of grid line colour. Note that in BIFF2-BIFF7 an RGB colour is
982
+ written instead.
983
+ 8 2 Not used
984
+ 10 2 Cached magnification factor in page break preview (in percent); 0 = Default (60%)
985
+ 12 2 Cached magnification factor in normal view (in percent); 0 = Default (100%)
986
+ 14 4 Not used
987
+
988
+ In BIFF8 this record stores used magnification factors for page break
989
+ preview and normal view. These values are used to restore the
990
+ magnification, when the view is changed. The real magnification of the
991
+ currently active view is stored in the SCL record. The type of the
992
+ active view is stored in the option flags field (see below).
993
+
994
+ 0 0001H 0 = Show formula results 1 = Show formulas
995
+ 1 0002H 0 = Do not show grid lines 1 = Show grid lines
996
+ 2 0004H 0 = Do not show sheet headers 1 = Show sheet headers
997
+ 3 0008H 0 = Panes are not frozen 1 = Panes are frozen (freeze)
998
+ 4 0010H 0 = Show zero values as empty cells 1 = Show zero values
999
+ 5 0020H 0 = Manual grid line colour 1 = Automatic grid line colour
1000
+ 6 0040H 0 = Columns from left to right 1 = Columns from right to left
1001
+ 7 0080H 0 = Do not show outline symbols 1 = Show outline symbols
1002
+ 8 0100H 0 = Keep splits if pane freeze is removed 1 = Remove splits if pane freeze is removed
1003
+ 9 0200H 0 = Sheet not selected 1 = Sheet selected (BIFF5-BIFF8)
1004
+ 10 0400H 0 = Sheet not visible 1 = Sheet visible (BIFF5-BIFF8)
1005
+ 11 0800H 0 = Show in normal view 1 = Show in page break preview (BIFF8)
1006
+
1007
+ The freeze flag specifies, if a following PANE record describes unfrozen or frozen panes.
1008
+ =end
1009
+ #rec_id 0x023E
1010
+
1011
+ def window2Record(options, first_visible_row, first_visible_col, grid_colour, preview_magn, normal_magn)
1012
+ get_biff_data(0x023E, [ options,
1013
+ first_visible_row, first_visible_col,
1014
+ grid_colour,
1015
+ 0x00,
1016
+ preview_magn, normal_magn,
1017
+ 0x00].pack('v7V'))
1018
+ end
1019
+
1020
+
1021
+ #class PanesRecord < BiffRecord
1022
+ =begin
1023
+ This record stores the position of window panes. It is part of the Sheet
1024
+ View Settings Block. If the sheet does not contain any splits, this
1025
+ record will not occur.
1026
+ A sheet can be split in two different ways, with unfrozen panes or with
1027
+ frozen panes. A flag in the WINDOW2 record specifies, if the panes are
1028
+ frozen, which affects the contents of this record.
1029
+
1030
+ Record PANE, BIFF2-BIFF8
1031
+ Offset Size Contents
1032
+ 0 2 Position of the vertical split
1033
+ (px, 0 = No vertical split)
1034
+ Unfrozen pane=> Width of the left pane(s)
1035
+ (in twips = 1/20 of a point)
1036
+ Frozen pane=> Number of visible
1037
+ columns in left pane(s)
1038
+ 2 2 Position of the horizontal split
1039
+ (py, 0 = No horizontal split)
1040
+ Unfrozen pane=> Height of the top pane(s)
1041
+ (in twips = 1/20 of a point)
1042
+ Frozen pane=> Number of visible
1043
+ rows in top pane(s)
1044
+ 4 2 Index to first visible row
1045
+ in bottom pane(s)
1046
+ 6 2 Index to first visible column
1047
+ in right pane(s)
1048
+ 8 1 Identifier of pane with active
1049
+ cell cursor
1050
+ [9] 1 Not used (BIFF5-BIFF8 only, not written
1051
+ in BIFF2-BIFF4)
1052
+
1053
+ If the panes are frozen, pane�0 is always active, regardless
1054
+ of the cursor position. The correct identifiers for all possible
1055
+ combinations of visible panes are shown in the following pictures.
1056
+
1057
+ px = 0, py = 0 px = 0, py > 0
1058
+ -------------------------- ------------|-------------
1059
+ | | | |
1060
+ | | | 3 |
1061
+ | | | |
1062
+ - 3 - --------------------------
1063
+ | | | |
1064
+ | | | 2 |
1065
+ | | | |
1066
+ -------------------------- ------------|-------------
1067
+
1068
+ px > 0, py = 0 px > 0, py > 0
1069
+ ------------|------------- ------------|-------------
1070
+ | | | | | |
1071
+ | | | | 3 | 2 |
1072
+ | | | | | |
1073
+ - 3 | 1 - --------------------------
1074
+ | | | | | |
1075
+ | | | | 1 | 0 |
1076
+ | | | | | |
1077
+ ------------|------------- ------------|-------------
1078
+ =end
1079
+ # rec_id 0x0041
1080
+ def panesRecord(px, py, first_row_bottom, first_col_right, active_pane)
1081
+ get_biff_data 0x0041, [ px, py,
1082
+ first_row_bottom, first_col_right,
1083
+ active_pane].pack('v5')
1084
+ end
1085
+
1086
+
1087
+ #class RowRecord < BiffRecord
1088
+ =begin
1089
+ This record contains the properties of a single row in a sheet. Rows
1090
+ and cells in a sheet are divided into blocks of 32 rows.
1091
+
1092
+ Record ROW, BIFF3-BIFF8
1093
+
1094
+ Offset Size Contents
1095
+ 0 2 Index of this row
1096
+ 2 2 Index to column of the first cell which is described by a cell record
1097
+ 4 2 Index to column of the last cell which is described by a cell record,
1098
+ increased by 1
1099
+ 6 2 Bit Mask Contents
1100
+ 14-0 7FFFH Height of the row, in twips = 1/20 of a point
1101
+ 15 8000H 0 = Row has custom height; 1 = Row has default height
1102
+ 8 2 Not used
1103
+ 10 2 In BIFF3-BIFF4 this field contains a relative offset
1104
+ to calculate stream position of the first cell record
1105
+ for this row. In BIFF5-BIFF8 this field is not used
1106
+ anymore, but the DBCELL record instead.
1107
+ 12 4 Option flags and default row formatting
1108
+ Bit Mask Contents
1109
+ 2-0 00000007H Outline level of the row
1110
+ 4 00000010H 1 = Outline group starts or ends here (depending
1111
+ on where the outline buttons are located,
1112
+ see WSBOOL record), and is collapsed
1113
+ 5 00000020H 1 = Row is hidden (manually, or by a filter or outline group)
1114
+ 6 00000040H 1 = Row height and default font height do not match
1115
+ 7 00000080H 1 = Row has explicit default format (fl)
1116
+ 8 00000100H Always 1
1117
+ 27-16 0FFF0000H If fl=1=> Index to default XF record
1118
+ 28 10000000H 1 = Additional space above the row. This flag is set,
1119
+ if the upper border of at least one cell in this row
1120
+ or if the lower border of at least one cell in the row
1121
+ above is formatted with a thick line style.
1122
+ Thin and medium line styles are not taken into account.
1123
+ 29 20000000H 1 = Additional space below the row. This flag is set,
1124
+ if the lower border of at least one cell in this row
1125
+ or if the upper border of at least one cell in the row
1126
+ below is formatted with a medium or thick line style.
1127
+ Thin line styles are not taken into account.
1128
+ =end
1129
+ # rec_id 0x0208
1130
+
1131
+ def rowRecord(index, first_col, last_col, height_options, options)
1132
+ get_biff_data(0x0208, [ index, first_col, last_col + 1,
1133
+ height_options,
1134
+ 0x00, 0x00,
1135
+ options].pack('v6V'))
1136
+ end
1137
+
1138
+ #class LabelSSTRecord < BiffRecord
1139
+ =begin
1140
+ This record represents a cell that contains a string. It replaces the
1141
+ LABEL record and RSTRING record used in BIFF2-BIFF7.
1142
+ =end
1143
+ # rec_id 0x00FD
1144
+
1145
+ def labelSSTRecord(row, col, xf_idx, sst_idx)
1146
+ get_biff_data(0x00FD, [ row, col, xf_idx, sst_idx].pack('v3V'))
1147
+ end
1148
+
1149
+
1150
+ #class MergedCellsRecord < BiffRecord
1151
+ =begin
1152
+ This record contains all merged cell ranges of the current sheet.
1153
+
1154
+ Record MERGEDCELLS, BIFF8
1155
+
1156
+ Offset Size Contents
1157
+ 0 var. Cell range address list with all merged ranges
1158
+
1159
+ ------------------------------------------------------------------
1160
+
1161
+ A cell range address list consists of a field with the number of ranges
1162
+ and the list of the range addresses.
1163
+
1164
+ Cell range address list, BIFF8
1165
+
1166
+ Offset Size Contents
1167
+ 0 2 Number of following cell range addresses (nm)
1168
+ 2 8*nm List of nm cell range addresses
1169
+
1170
+ ---------------------------------------------------------------------
1171
+ Cell range address, BIFF8
1172
+
1173
+ Offset Size Contents
1174
+ 0 2 Index to first row
1175
+ 2 2 Index to last row
1176
+ 4 2 Index to first column
1177
+ 6 2 Index to last column
1178
+ =end
1179
+ # rec_id 0x00E5
1180
+
1181
+ def mergedCellsRecord(merged_list)
1182
+ i = merged_list.length - 1
1183
+ rec_data = ''
1184
+ while i >= 0
1185
+ j = 0
1186
+ merged = ''
1187
+ while (i >= 0) and (j < 0x403)
1188
+ r1, r2, c1, c2 = merged_list[i]
1189
+ merged << [ r1, r2, c1, c2].pack('v4')
1190
+ i -= 1
1191
+ j += 1
1192
+ end
1193
+ rec_data << [0x00E5, merged.length + 2, j, merged].pack('v3a*')
1194
+ end
1195
+ rec_data
1196
+ end
1197
+
1198
+ #class MulBlankRecord < BiffRecord
1199
+ =begin
1200
+ This record represents a cell range of empty cells. All cells are
1201
+ located in the same row.
1202
+
1203
+ Record MULBLANK, BIFF5-BIFF8
1204
+
1205
+ Offset Size Contents
1206
+ 0 2 Index to row
1207
+ 2 2 Index to first column (fc)
1208
+ 4 2*nc List of nc=lc-fc+1 16-bit indexes to XF records
1209
+ 4+2*nc 2 Index to last column (lc)
1210
+ =end
1211
+ #rec_id 0x00BE
1212
+
1213
+ def mulBlankRecord(row, first_col, last_col, xf_index)
1214
+ blanks_count = last_col-first_col+1
1215
+ rec_data = ([xf_index]*blanks_count).pack('v*')
1216
+ get_biff_data(0x00BE, [ row, first_col, rec_data, last_col].pack('v2a*v'))
1217
+ end
1218
+
1219
+
1220
+ #class BlankRecord < BiffRecord
1221
+ =begin
1222
+ This record represents an empty cell.
1223
+
1224
+ Record BLANK, BIFF5-BIFF8
1225
+
1226
+ Offset Size Contents
1227
+ 0 2 Index to row
1228
+ 2 2 Index to first column (fc)
1229
+ 4 2 indexes to XF record
1230
+ =end
1231
+ # rec_id 0x0201
1232
+
1233
+ def blankRecord(row, col, xf_index)
1234
+ get_biff_data(0x0201, [ row, col, xf_index].pack('v3'))
1235
+ end
1236
+
1237
+
1238
+ #class RKRecord < BiffRecord
1239
+ =begin
1240
+ This record represents a cell that contains an RK value (encoded integer or
1241
+ floating-point value). If a floating-point value cannot be encoded to an RK value,
1242
+ a NUMBER record will be written.
1243
+ =end
1244
+ #rec_id 0x027E
1245
+
1246
+ def rkRecord(row, col, xf_index, rk_encoded)
1247
+ get_biff_data(0x027E, [ row, col, xf_index, rk_encoded].pack('v3V'))
1248
+ end
1249
+
1250
+
1251
+ #class NumberRecord < BiffRecord
1252
+ =begin
1253
+ This record represents a cell that contains an IEEE-754 floating-point value.
1254
+ =end
1255
+ # rec_id 0x0203
1256
+
1257
+ def numberRecord(row, col, xf_index, number)
1258
+ get_biff_data(0x0203, [ row, col, xf_index, number].pack('v3E'))
1259
+ end
1260
+
1261
+
1262
+ #class FormulaRecord < BiffRecord
1263
+ =begin
1264
+ Offset Size Contents
1265
+ 0 2 Index to row
1266
+ 2 2 Index to column
1267
+ 4 2 Index to XF record
1268
+ 6 8 Result of the formula
1269
+ 14 2 Option flags
1270
+ Bit Mask Contents
1271
+ 0 0001H 1 = Recalculate always
1272
+ 1 0002H 1 = Calculate on open
1273
+ 3 0008H 1 = Part of a shared formula
1274
+ 16 4 Not used
1275
+ 20 var. Formula data (RPN token array)
1276
+ =end
1277
+ #rec_id 0x0006
1278
+
1279
+ def formulaRecord(row, col, xf_index, rpn)
1280
+ get_biff_data(0x0006, [ row, col, xf_index, 0xFFFF000000000003, 0, 0].pack('v3QvV') + rpn)
1281
+ end
1282
+
1283
+
1284
+ #class GutsRecord < BiffRecord
1285
+ =begin
1286
+ This record contains information about the layout of outline symbols.
1287
+
1288
+ Record GUTS, BIFF3-BIFF8
1289
+
1290
+ Offset Size Contents
1291
+ 0 2 Width of the area to display row outlines (left of the sheet), in pixel
1292
+ 2 2 Height of the area to display column outlines (above the sheet), in pixel
1293
+ 4 2 Number of visible row outline levels (used row levels + 1; or 0, if not used)
1294
+ 6 2 Number of visible column outline levels (used column levels + 1; or 0, if not used)
1295
+ =end
1296
+ # rec_id 0x0080
1297
+
1298
+ def gutsRecord(row_gut_width, col_gut_height, row_visible_levels, col_visible_levels)
1299
+ get_biff_data(0x0080, [ row_gut_width, col_gut_height, row_visible_levels, col_visible_levels].pack('v4'))
1300
+ end
1301
+
1302
+ #class WSBoolRecord < BiffRecord
1303
+ =begin
1304
+ This record stores a 16 bit value with Boolean options for the current
1305
+ sheet. From BIFF5 on the "Save external linked values" option is moved
1306
+ to the record BOOKBOOL.
1307
+
1308
+ Option flags of record WSBOOL, BIFF3-BIFF8
1309
+
1310
+ Bit Mask Contents
1311
+ 0 0001H 0 = Do not show automatic page breaks
1312
+ 1 = Show automatic page breaks
1313
+ 4 0010H 0 = Standard sheet
1314
+ 1 = Dialogue sheet (BIFF5-BIFF8)
1315
+ 5 0020H 0 = No automatic styles in outlines
1316
+ 1 = Apply automatic styles to outlines
1317
+ 6 0040H 0 = Outline buttons above outline group
1318
+ 1 = Outline buttons below outline group
1319
+ 7 0080H 0 = Outline buttons left of outline group
1320
+ 1 = Outline buttons right of outline group
1321
+ 8 0100H 0 = Scale printout in percent
1322
+ 1 = Fit printout to number of pages
1323
+ 9 0200H 0 = Save external linked values (BIFF3?BIFF4 only)
1324
+ 1 = Do not save external linked values (BIFF3?BIFF4 only)
1325
+ 10 0400H 0 = Do not show row outline symbols
1326
+ 1 = Show row outline symbols
1327
+ 11 0800H 0 = Do not show column outline symbols
1328
+ 1 = Show column outline symbols
1329
+ 13-12 3000H These flags specify the arrangement of windows.
1330
+ They are stored in BIFF4 only.
1331
+ 00 = Arrange windows tiled
1332
+ 01 = Arrange windows horizontal
1333
+ 10 = Arrange windows vertical112 = Arrange windows cascaded
1334
+ The following flags are valid for BIFF4-BIFF8 only
1335
+ 14 4000H 0 = Standard expression evaluation
1336
+ 1 = Alternative expression evaluation
1337
+ 15 8000H 0 = Standard formula entries
1338
+ 1 = Alternative formula entries
1339
+ =end
1340
+ # rec_id 0x0081
1341
+
1342
+ def wsBoolRecord(options)
1343
+ get_biff_data(0x0081, [ options].pack('v'))
1344
+ end
1345
+
1346
+ #class ColInfoRecord < BiffRecord
1347
+ =begin
1348
+ This record specifies the width for a given range of columns.
1349
+ If a column does not have a corresponding COLINFO record,
1350
+ the width specified in the record STANDARDWIDTH is used. If
1351
+ this record is also not present, the contents of the record
1352
+ DEFCOLWIDTH is used instead.
1353
+ This record also specifies a default XF record to use for
1354
+ cells in the columns that are not described by any cell record
1355
+ (which contain the XF index for that cell). Additionally,
1356
+ the option flags field contains hidden, outline, and collapsed
1357
+ options applied at the columns.
1358
+
1359
+ Record COLINFO, BIFF3-BIFF8
1360
+
1361
+ Offset Size Contents
1362
+ 0 2 Index to first column in the range
1363
+ 2 2 Index to last column in the range
1364
+ 4 2 Width of the columns in 1/256 of the width of the zero character, using default font
1365
+ (first FONT record in the file)
1366
+ 6 2 Index to XF record for default column formatting
1367
+ 8 2 Option flags
1368
+ Bits Mask Contents
1369
+ 0 0001H 1 = Columns are hidden
1370
+ 10-8 0700H Outline level of the columns (0 = no outline)
1371
+ 12 1000H 1 = Columns are collapsed
1372
+ 10 2 Not used
1373
+ =end
1374
+ # rec_id 0x007D
1375
+
1376
+ def colInfoRecord(first_col, last_col, width, xf_index, options)
1377
+ get_biff_data(0x007D, [ first_col, last_col, width, xf_index, options, 0].pack('v6'))
1378
+ end
1379
+
1380
+ #class CalcModeRecord < BiffRecord
1381
+ =begin
1382
+ This record is part of the Calculation Settings Block.
1383
+ It specifies whether to calculate formulas manually,
1384
+ automatically or automatically except for multiple table operations.
1385
+
1386
+ Record CALCMODE, BIFF2-BIFF8
1387
+
1388
+ Offset Size Contents
1389
+ 0 2 FFFFH = automatic except for multiple table operations
1390
+ 0000H = manually
1391
+ 0001H = automatically (default)
1392
+ =end
1393
+ # rec_id 0x000D
1394
+ short_record(:calcModeRecord, 0x000D)
1395
+
1396
+
1397
+ #class CalcCountRecord < BiffRecord
1398
+ =begin
1399
+ This record is part of the Calculation Settings Block. It specifies the maximum
1400
+ number of times the formulas should be iteratively calculated. This is a fail-safe
1401
+ against mutually recursive formulas locking up a spreadsheet application.
1402
+
1403
+ Record CALCCOUNT, BIFF2-BIFF8
1404
+
1405
+ Offset Size Contents
1406
+ 0 2 Maximum number of iterations allowed in circular references
1407
+ =end
1408
+
1409
+ # rec_id 0x000C
1410
+ short_record(:calcCountRecord, 0x000c)
1411
+
1412
+ #class RefModeRecord < BiffRecord
1413
+ =begin
1414
+ This record is part of the Calculation Settings Block.
1415
+ It stores which method is used to show cell addresses in formulas.
1416
+ The �RC� mode uses numeric indexes for rows and columns,
1417
+ i.e. �R(1)C(-1)�, or �R1C1:R2C2�.
1418
+ The �A1� mode uses characters for columns and numbers for rows,
1419
+ i.e. �B1�, or �$A$1:$B$2�.
1420
+
1421
+ Record REFMODE, BIFF2-BIFF8
1422
+
1423
+ Offset Size Contents
1424
+ 0 2 0 = RC mode; 1 = A1 mode
1425
+ =end
1426
+ # rec_id 0x00F
1427
+ short_record(:refModeRecord,0x00f)
1428
+
1429
+ #class IterationRecord < BiffRecord
1430
+ =begin
1431
+ This record is part of the Calculation Settings Block.
1432
+ It stores if iterations are allowed while calculating recursive formulas.
1433
+
1434
+ Record ITERATION, BIFF2-BIFF8
1435
+
1436
+ Offset Size Contents
1437
+ 0 2 0 = Iterations off; 1 = Iterations on
1438
+ =end
1439
+ # rec_id 0x011
1440
+ short_record(:iterationRecord, 0x011)
1441
+
1442
+ #class DeltaRecord < BiffRecord
1443
+ =begin
1444
+ This record is part of the Calculation Settings Block.
1445
+ It stores the maximum change of the result to exit an iteration.
1446
+
1447
+ Record DELTA, BIFF2-BIFF8
1448
+
1449
+ Offset Size Contents
1450
+ 0 8 Maximum change in iteration
1451
+ (IEEE 754 floating-point value,
1452
+ 64bit double precision)
1453
+ =end
1454
+ # rec_id 0x010
1455
+ double_record(:deltaRecord, 0x010)
1456
+
1457
+ #class SaveRecalcRecord < BiffRecord
1458
+ =begin
1459
+ This record is part of the Calculation Settings Block.
1460
+ It contains the �Recalculate before save� option in
1461
+ Excel's calculation settings dialogue.
1462
+
1463
+ Record SAVERECALC, BIFF3-BIFF8
1464
+
1465
+ Offset Size Contents
1466
+ 0 2 0 = Do not recalculate;
1467
+ 1 = Recalculate before saving the document
1468
+ =end
1469
+ # rec_id 0x05F
1470
+
1471
+ short_record(:saveRecalcRecord, 0x05f)
1472
+
1473
+ #class PrintHeadersRecord < BiffRecord
1474
+ =begin
1475
+ This record stores if the row and column headers
1476
+ (the areas with row numbers and column letters) will be printed.
1477
+
1478
+ Record PRINTHEADERS, BIFF2-BIFF8
1479
+
1480
+ Offset Size Contents
1481
+ 0 2 0 = Do not print row/column headers;
1482
+ 1 = Print row/column headers
1483
+ =end
1484
+ # rec_id 0x02A
1485
+
1486
+ short_record(:printHeadersRecord,0x02A)
1487
+
1488
+
1489
+ #class PrintGridLinesRecord < BiffRecord
1490
+ =begin
1491
+ This record stores if sheet grid lines will be printed.
1492
+
1493
+ Record PRINTGRIDLINES, BIFF2-BIFF8
1494
+
1495
+ Offset Size Contents
1496
+ 0 2 0 = Do not print sheet grid lines;
1497
+ 1 = Print sheet grid lines
1498
+ =end
1499
+ # rec_id 0x02B
1500
+ short_record(:printGridLinesRecord, 0x02b)
1501
+
1502
+
1503
+ #class GridSetRecord < BiffRecord
1504
+ =begin
1505
+ This record specifies if the option to print sheet grid lines
1506
+ (record PRINTGRIDLINES) has ever been changed.
1507
+
1508
+ Record GRIDSET, BIFF3-BIFF8
1509
+
1510
+ Offset Size Contents
1511
+ 0 2 0 = Print grid lines option never changed
1512
+ 1 = Print grid lines option changed
1513
+ =end
1514
+ #rec_id 0x082
1515
+ short_record(:gridSetRecord, 0x082)
1516
+
1517
+
1518
+ #class DefaultRowHeight < BiffRecord
1519
+ =begin
1520
+ This record specifies the default height and default flags
1521
+ for rows that do not have a corresponding ROW record.
1522
+
1523
+ Record DEFAULTROWHEIGHT, BIFF3-BIFF8
1524
+
1525
+ Offset Size Contents
1526
+ 0 2 Option flags
1527
+ Bit Mask Contents
1528
+ 0 0001H 1 = Row height and default font height do not match
1529
+ 1 0002H 1 = Row is hidden
1530
+ 2 0004H 1 = Additional space above the row
1531
+ 3 0008H 1 = Additional space below the row
1532
+ 2 2 Default height for unused rows, in twips = 1/20 of a point
1533
+ =end
1534
+ # rec_id 0x0225
1535
+
1536
+ def defaultRowHeight(options, def_height)
1537
+ get_biff_data(0x0225, [ options, def_height].pack('v2'))
1538
+ end
1539
+
1540
+
1541
+ #class DefColWidthRecord < BiffRecord
1542
+ =begin
1543
+ This record specifies the default column width for columns that
1544
+ do not have a specific width set using the record COLINFO or COLWIDTH.
1545
+ This record has no effect, if a STANDARDWIDTH record is present in the file.
1546
+
1547
+ Record DEFCOLWIDTH, BIFF2-BIFF8
1548
+
1549
+ Offset Size Contents
1550
+ 0 2 Column width in characters, using the width of the zero
1551
+ character from default font (first FONT record in the file)
1552
+ =end
1553
+ #rec_id 0x0055
1554
+ short_record(:defColWidthRecord, 0x0055)
1555
+
1556
+ #class HorizontalPageBreaksRecord < BiffRecord
1557
+ =begin
1558
+ This record is part of the Page Settings Block. It contains all
1559
+ horizontal manual page breaks.
1560
+
1561
+ Record HORIZONTALPAGEBREAKS, BIFF8
1562
+ Offset Size Contents
1563
+ 0 2 Number of following row index structures (nm)
1564
+ 2 6nm List of nm row index structures. Each row index
1565
+ structure contains
1566
+ Offset Size Contents
1567
+ 0 2 Index to first row below the page break
1568
+ 2 2 Index to first column of this page break
1569
+ 4 2 Index to last column of this page break
1570
+
1571
+ The row indexes in the lists must be ordered ascending.
1572
+ If in BIFF8 a row contains several page breaks, they must be ordered
1573
+ ascending by start column index.
1574
+ =end
1575
+ #rec_id 0x001B
1576
+
1577
+ def horizontalPageBreaksRecord(break_list)
1578
+ get_biff_data(0x001B, [break_list.length, *break_list.flatten].pack('v*'))
1579
+ end
1580
+
1581
+ #class VerticalPageBreaksRecord < BiffRecord
1582
+ =begin
1583
+ This record is part of the Page Settings Block. It contains all
1584
+ vertical manual page breaks.
1585
+
1586
+ Record VERTICALPAGEBREAKS, BIFF8
1587
+ Offset Size Contents
1588
+ 0 2 Number of following column index structures (nm)
1589
+ 2 6nm List of nm column index structures. Each column index
1590
+ structure contains
1591
+ Offset Size Contents
1592
+ 0 2 Index to first column following the page
1593
+ break
1594
+ 2 2 Index to first row of this page break
1595
+ 4 2 Index to last row of this page break
1596
+
1597
+ The column indexes in the lists must be ordered ascending.
1598
+ If in BIFF8 a column contains several page breaks, they must be ordered
1599
+ ascending by start row index.
1600
+ =end
1601
+ #rec_id 0x001A
1602
+ def verticalPageBreaksRecord(break_list)
1603
+ get_biff_data(0x001A, ([break_list.length] + break_list.flatten).pack('v*'))
1604
+ end
1605
+
1606
+ #class HeaderRecord < BiffRecord
1607
+ =begin
1608
+ This record is part of the Page Settings Block. It specifies the
1609
+ page header string for the current worksheet. If this record is not
1610
+ present or completely empty (record size is 0), the sheet does not
1611
+ contain a page header.
1612
+
1613
+ Record HEADER for non-empty page header, BIFF2-BIFF8
1614
+ Offset Size Contents
1615
+ 0 var. Page header string
1616
+ BIFF2-BIFF7=> Non-empty byte string, 8bit string
1617
+ length
1618
+ BIFF8=> Non-empty Unicode string, 16bit string length
1619
+ The header string may contain special commands, i.e. placeholders for
1620
+ the page number, current date, or text formatting attributes. These
1621
+ fields are represented by single letters (exception=> font name and
1622
+ size, see below) with a leading ampersand ("&"). If the ampersand
1623
+ is part of the regular header text, it will be duplicated ("&&"). The
1624
+ page header is divided into 3 sections=> the left, the centred, and the
1625
+ right section. Each section is introduced by a special command. All
1626
+ text and all commands following are part of the selected section. Each
1627
+ section starts with the text formatting specified in the default font
1628
+ (first FONT record in the file). Active formatting attributes from
1629
+ a previous section do not go into the next section.
1630
+
1631
+ The following table shows all available commands
1632
+
1633
+ Command Contents
1634
+ && The "&" character itself
1635
+ &L Start of the left section
1636
+ &C Start of the centred section
1637
+ &R Start of the right section
1638
+ &P Current page number
1639
+ &N Page count
1640
+ &D Current date
1641
+ &T Current time
1642
+ &A Sheet name (BIFF5-BIFF8)
1643
+ &F File name without path
1644
+ &Z File path without file name (BIFF8X)
1645
+ &G Picture (BIFF8X)
1646
+ &B Bold on/off (BIFF2-BIFF4)
1647
+ &I Italic on/off (BIFF2-BIFF4)
1648
+ &U Underlining on/off
1649
+ &E Double underlining on/off (BIFF5-BIFF8)
1650
+ &S Strikeout on/off
1651
+ &X Superscript on/off (BIFF5-BIFF8)
1652
+ &Y Subscript on/off (BIFF5-BIFF8)
1653
+ &"<fontname>" Set new font <fontname>
1654
+ &"<fontname>,<fontstyle>"
1655
+ Set new font with specified style <fontstyle>.
1656
+ The style <fontstyle> is in most cases one of
1657
+ "Regular", "Bold", "Italic", or "Bold Italic".
1658
+ But this setting is dependent on the used font,
1659
+ it may differ (localised style names, or "Standard",
1660
+ "Oblique", ...). (BIFF5-BIFF8)
1661
+ &<fontheight> Set font height in points (<fontheight> is a decimal value).
1662
+ If this command is followed by a plain number to be printed
1663
+ in the header, it will be separated from the font height
1664
+ with a space character.
1665
+ =end
1666
+ #rec_id 0x0014
1667
+
1668
+ def headerRecord(header_str)
1669
+ get_biff_data(0x0014, upack2(header_str))
1670
+ end
1671
+
1672
+ #class FooterRecord < BiffRecord
1673
+ =begin
1674
+ Semantic is equal to HEADER record
1675
+ =end
1676
+ #rec_id 0x0015
1677
+
1678
+ def footerRecord(footer_str)
1679
+ get_biff_data(0x0015, upack2(footer_str))
1680
+ end
1681
+
1682
+
1683
+ #class HCenterRecord < BiffRecord
1684
+ =begin
1685
+ This record is part of the Page Settings Block. It specifies if the
1686
+ sheet is centred horizontally when printed.
1687
+
1688
+ Record HCENTER, BIFF3-BIFF8
1689
+
1690
+ Offset Size Contents
1691
+ 0 2 0 = Print sheet left aligned
1692
+ 1 = Print sheet centred horizontally
1693
+ =end
1694
+ short_record(:hCenterRecord, 0x0083)
1695
+
1696
+ #class VCenterRecord < BiffRecord
1697
+ =begin
1698
+ This record is part of the Page Settings Block. It specifies if the
1699
+ sheet is centred vertically when printed.
1700
+
1701
+ Record VCENTER, BIFF3-BIFF8
1702
+
1703
+ Offset Size Contents
1704
+ 0 2 0 = Print sheet aligned at top page border
1705
+ 1 = Print sheet vertically centred
1706
+ =end
1707
+ # rec_id 0x0084
1708
+ short_record(:vCenterRecord, 0x0084)
1709
+
1710
+
1711
+ #class LeftMarginRecord < BiffRecord
1712
+ =begin
1713
+ This record is part of the Page Settings Block. It contains the left
1714
+ page margin of the current worksheet.
1715
+
1716
+ Record LEFTMARGIN, BIFF2-BIFF8
1717
+
1718
+ Offset Size Contents
1719
+ 0 8 Left page margin in inches
1720
+ (IEEE 754 floating-point value, 64bit double precision)
1721
+ =end
1722
+ #rec_id 0x0026
1723
+ double_record(:leftMarginRecord, 0x0026)
1724
+
1725
+
1726
+ #class RightMarginRecord < BiffRecord
1727
+ =begin
1728
+ This record is part of the Page Settings Block. It contains the right
1729
+ page margin of the current worksheet.
1730
+
1731
+ Offset Size Contents
1732
+ 0 8 Right page margin in inches
1733
+ (IEEE 754 floating-point value, 64?bit double precision)
1734
+ =end
1735
+ #rec_id 0x0027
1736
+ double_record(:rightMarginRecord, 0x0027)
1737
+
1738
+ #class TopMarginRecord < BiffRecord
1739
+ =begin
1740
+ This record is part of the Page Settings Block. It contains the top
1741
+ page margin of the current worksheet.
1742
+
1743
+ Offset Size Contents
1744
+ 0 8 Top page margin in inches
1745
+ (IEEE 754 floating-point value, 64?bit double precision)
1746
+ =end
1747
+ #rec_id 0x0028
1748
+ double_record(:topMarginRecord, 0x0028)
1749
+
1750
+
1751
+ #class BottomMarginRecord < BiffRecord
1752
+ =begin
1753
+ This record is part of the Page Settings Block. It contains the bottom
1754
+ page margin of the current worksheet.
1755
+
1756
+ Offset Size Contents
1757
+ 0 8 Bottom page margin in inches
1758
+ (IEEE 754 floating-point value, 64?bit double precision)
1759
+ =end
1760
+ #rec_id 0x0029
1761
+ double_record(:bottomMarginRecord, 0x0029)
1762
+
1763
+
1764
+ #class SetupPageRecord < BiffRecord
1765
+ =begin
1766
+ This record is part of the Page Settings Block. It stores the page
1767
+ format settings of the current sheet. The pages may be scaled in
1768
+ percent or by using an absolute number of pages. This setting is
1769
+ located in the WSBOOL record. If pages are scaled in percent,
1770
+ the scaling factor in this record is used, otherwise the "Fit to
1771
+ pages" values. One of the "Fit to pages" values may be 0. In this case
1772
+ the sheet is scaled to fit only to the other value.
1773
+
1774
+ Record SETUP, BIFF5-BIFF8
1775
+
1776
+ Offset Size Contents
1777
+ 0 2 Paper size (see below)
1778
+ 2 2 Scaling factor in percent
1779
+ 4 2 Start page number
1780
+ 6 2 Fit worksheet width to this number of pages
1781
+ (0 = use as many as needed)
1782
+ 8 2 Fit worksheet height to this number of pages
1783
+ (0 = use as many as needed)
1784
+ 10 2 Option flags
1785
+ Bit Mask Contents
1786
+ 0 0001H 0 = Print pages in columns
1787
+ 1 = Print pages in rows
1788
+ 1 0002H 0 = Landscape
1789
+ 1 = Portrait
1790
+ 2 0004H 1 = Paper size, scaling factor,
1791
+ paper orientation (portrait/landscape),
1792
+ print resolution and number of copies
1793
+ are not initialised
1794
+ 3 0008H 0 = Print coloured
1795
+ 1 = Print black and white
1796
+ 4 0010H 0 = Default print quality
1797
+ 1 = Draft quality
1798
+ 5 0020H 0 = Do not print cell notes
1799
+ 1 = Print cell notes
1800
+ 6 0040H 0 = Paper orientation setting is valid
1801
+ 1 = Paper orientation setting not
1802
+ initialised
1803
+ 7 0080H 0 = Automatic page numbers
1804
+ 1 = Use start page number
1805
+ The following flags are valid for BIFF8 only
1806
+ 9 0200H 0 = Print notes as displayed
1807
+ 1 = Print notes at end of sheet
1808
+ 11-10 0C00H 00 = Print errors as displayed
1809
+ 01 = Do not print errors
1810
+ 10 = Print errors as "--"
1811
+ 11 = Print errors as "#N/A!"
1812
+ 12 2 Print resolution in dpi
1813
+ 14 2 Vertical print resolution in dpi
1814
+ 16 8 Header margin (IEEE 754 floating-point value,
1815
+ 64bit double precision)
1816
+ 24 8 Footer margin (IEEE 754 floating-point value,
1817
+ 64bit double precision)
1818
+ 32 2 Number of copies to print
1819
+
1820
+
1821
+ PAPER TYPES
1822
+
1823
+ Index Paper type Paper size
1824
+ 0 Undefined
1825
+ 1 Letter 8 1/2" x 11"
1826
+ 2 Letter small 8 1/2" x 11"
1827
+ 3 Tabloid 11" x 17"
1828
+ 4 Ledger 17" x 11"
1829
+ 5 Legal 8 1/2" x 14"
1830
+ 6 Statement 5 1/2" x 8 1/2"
1831
+ 7 Executive 7 1/4" x 10 1/2"
1832
+ 8 A3 297mm x 420mm
1833
+ 9 A4 210mm x 297mm
1834
+ 10 A4 small 210mm x 297mm
1835
+ 11 A5 148mm x 210mm
1836
+ 12 B4 (JIS) 257mm x 364mm
1837
+ 13 B5 (JIS) 182mm x 257mm
1838
+ 14 Folio 8 1/2" x 13"
1839
+ 15 Quarto 215mm x 275mm
1840
+ 16 10x14 10" x 14"
1841
+ 17 11x17 11" x 17"
1842
+ 18 Note 8 1/2" x 11"
1843
+ 19 Envelope #9 3 7/8" x 8 7/8"
1844
+ 20 Envelope #10 4 1/8" x 9 1/2"
1845
+ 21 Envelope #11 4 1/2" x 10 3/8"
1846
+ 22 Envelope #12 4 3/4" x 11"
1847
+ 23 Envelope #14 5" x 11 1/2"
1848
+ 24 C 17" x 22"
1849
+ 25 D 22" x 34"
1850
+ 26 E 34" x 44"
1851
+ 27 Envelope DL 110mm x 220mm
1852
+ 28 Envelope C5 162mm x 229mm
1853
+ 29 Envelope C3 324mm x 458mm
1854
+ 30 Envelope C4 229mm x 324mm
1855
+ 31 Envelope C6 114mm x 162mm
1856
+ 32 Envelope C6/C5 114mm x 229mm
1857
+ 33 B4 (ISO) 250mm x 353mm
1858
+ 34 B5 (ISO) 176mm x 250mm
1859
+ 35 B6 (ISO) 125mm x 176mm
1860
+ 36 Envelope Italy 110mm x 230mm
1861
+ 37 Envelope Monarch 3 7/8" x 7 1/2"
1862
+ 38 63/4 Envelope 3 5/8" x 6 1/2"
1863
+ 39 US Standard Fanfold 14 7/8" x 11"
1864
+ 40 German Std. Fanfold 8 1/2" x 12"
1865
+ 41 German Legal Fanfold 8 1/2" x 13"
1866
+ 42 B4 (ISO) 250mm x 353mm
1867
+ 43 Japanese Postcard 100mm x 148mm
1868
+ 44 9x11 9" x 11"
1869
+ 45 10x11 10" x 11"
1870
+ 46 15x11 15" x 11"
1871
+ 47 Envelope Invite 220mm x 220mm
1872
+ 48 Undefined
1873
+ 49 Undefined
1874
+ 50 Letter Extra 9 1/2" x 12"
1875
+ 51 Legal Extra 9 1/2" x 15"
1876
+ 52 Tabloid Extra 11 11/16" x 18"
1877
+ 53 A4 Extra 235mm x 322mm
1878
+ 54 Letter Transverse 8 1/2" x 11"
1879
+ 55 A4 Transverse 210mm x 297mm
1880
+ 56 Letter Extra Transv. 9 1/2" x 12"
1881
+ 57 Super A/A4 227mm x 356mm
1882
+ 58 Super B/A3 305mm x 487mm
1883
+ 59 Letter Plus 8 1/2" x 12 11/16"
1884
+ 60 A4 Plus 210mm x 330mm
1885
+ 61 A5 Transverse 148mm x 210mm
1886
+ 62 B5 (JIS) Transverse 182mm x 257mm
1887
+ 63 A3 Extra 322mm x 445mm
1888
+ 64 A5 Extra 174mm x 235mm
1889
+ 65 B5 (ISO) Extra 201mm x 276mm
1890
+ 66 A2 420mm x 594mm
1891
+ 67 A3 Transverse 297mm x 420mm
1892
+ 68 A3 Extra Transverse 322mm x 445mm
1893
+ 69 Dbl. Japanese Postcard 200mm x 148mm
1894
+ 70 A6 105mm x 148mm
1895
+ 71
1896
+ 72
1897
+ 73
1898
+ 74
1899
+ 75 Letter Rotated 11" x 8 1/2"
1900
+ 76 A3 Rotated 420mm x 297mm
1901
+ 77 A4 Rotated 297mm x 210mm
1902
+ 78 A5 Rotated 210mm x 148mm
1903
+ 79 B4 (JIS) Rotated 364mm x 257mm
1904
+ 80 B5 (JIS) Rotated 257mm x 182mm
1905
+ 81 Japanese Postcard Rot. 148mm x 100mm
1906
+ 82 Dbl. Jap. Postcard Rot. 148mm x 200mm
1907
+ 83 A6 Rotated 148mm x 105mm
1908
+ 84
1909
+ 85
1910
+ 86
1911
+ 87
1912
+ 88 B6 (JIS) 128mm x 182mm
1913
+ 89 B6 (JIS) Rotated 182mm x 128mm
1914
+ 90 12x11 12" x 11"
1915
+ =end
1916
+ #rec_id 0x00A1
1917
+ def setupPageRecord(paper, scaling, start_num, fit_width_to, fit_height_to,
1918
+ options,
1919
+ hres, vres,
1920
+ header_margin, footer_margin,
1921
+ num_copies)
1922
+ get_biff_data(0x00A1, [ paper, scaling, start_num,
1923
+ fit_width_to, fit_height_to,
1924
+ options,
1925
+ hres, vres,
1926
+ header_margin, footer_margin,
1927
+ num_copies].pack('v8E2v'))
1928
+ end
1929
+ end
1930
+ end