ru_excel 0.0.6

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.
@@ -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