surpass 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +0 -0
- data/README.txt +133 -0
- data/Rakefile +35 -0
- data/examples/big-16mb.rb +25 -0
- data/examples/big-random-strings.rb +28 -0
- data/examples/blanks.rb +34 -0
- data/examples/col_width.rb +16 -0
- data/examples/dates.rb +31 -0
- data/examples/format.rb +23 -0
- data/examples/hello-world.rb +9 -0
- data/examples/image.rb +10 -0
- data/examples/merged.rb +36 -0
- data/examples/merged0.rb +27 -0
- data/examples/merged1.rb +99 -0
- data/examples/num_formats.rb +55 -0
- data/examples/numbers.rb +24 -0
- data/examples/outline.rb +110 -0
- data/examples/panes.rb +48 -0
- data/examples/protection.rb +132 -0
- data/examples/python.bmp +0 -0
- data/examples/row_styles.rb +16 -0
- data/examples/row_styles_empty.rb +15 -0
- data/examples/set_cell_and_range_style.rb +12 -0
- data/examples/wrapped-text.rb +13 -0
- data/examples/write_arrays.rb +16 -0
- data/examples/ws_props.rb +80 -0
- data/lib/biff_record.rb +2168 -0
- data/lib/bitmap.rb +218 -0
- data/lib/cell.rb +214 -0
- data/lib/chart.rb +16 -0
- data/lib/column.rb +40 -0
- data/lib/document.rb +406 -0
- data/lib/excel_formula.rb +6 -0
- data/lib/excel_magic.rb +1013 -0
- data/lib/formatting.rb +554 -0
- data/lib/row.rb +137 -0
- data/lib/style.rb +179 -0
- data/lib/surpass.rb +51 -0
- data/lib/utilities.rb +86 -0
- data/lib/workbook.rb +206 -0
- data/lib/worksheet.rb +561 -0
- data/spec/biff_record_spec.rb +268 -0
- data/spec/cell_spec.rb +56 -0
- data/spec/data/random-strings.txt +10000 -0
- data/spec/document_spec.rb +168 -0
- data/spec/excel_formula_spec.rb +0 -0
- data/spec/formatting_spec.rb +53 -0
- data/spec/reference/P-0508-0000507647-3280-5298.xls +0 -0
- data/spec/reference/all-cell-styles.bin +0 -0
- data/spec/reference/all-number-formats.bin +0 -0
- data/spec/reference/all-styles.bin +0 -0
- data/spec/reference/mini.xls +0 -0
- data/spec/row_spec.rb +19 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/style_spec.rb +89 -0
- data/spec/utilities_spec.rb +57 -0
- data/spec/workbook_spec.rb +48 -0
- data/spec/worksheet_spec.rb +0 -0
- data/stats/cloc.txt +8 -0
- data/stats/rcov.txt +0 -0
- data/stats/specdoc.txt +158 -0
- data/surpass-manual-0-0-3.pdf +0 -0
- data/surpass.gemspec +34 -0
- data/tasks/ann.rake +80 -0
- data/tasks/bones.rake +20 -0
- data/tasks/excel.rake +6 -0
- data/tasks/gem.rake +201 -0
- data/tasks/git.rake +40 -0
- data/tasks/metrics.rake +42 -0
- data/tasks/notes.rake +27 -0
- data/tasks/post_load.rake +34 -0
- data/tasks/rdoc.rake +51 -0
- data/tasks/rubyforge.rake +55 -0
- data/tasks/setup.rb +292 -0
- data/tasks/spec.rake +54 -0
- data/tasks/svn.rake +47 -0
- data/tasks/test.rake +40 -0
- metadata +144 -0
data/lib/worksheet.rb
ADDED
@@ -0,0 +1,561 @@
|
|
1
|
+
class Worksheet
|
2
|
+
include Utilities
|
3
|
+
|
4
|
+
attr_accessor :name
|
5
|
+
attr_accessor :parent
|
6
|
+
attr_accessor :rows
|
7
|
+
attr_accessor :cols
|
8
|
+
attr_accessor :merged_ranges
|
9
|
+
attr_accessor :bmp_rec
|
10
|
+
attr_accessor :show_formulas
|
11
|
+
attr_accessor :show_grid
|
12
|
+
attr_accessor :show_headers
|
13
|
+
attr_accessor :panes_frozen
|
14
|
+
attr_accessor :show_empty_as_zero
|
15
|
+
attr_accessor :auto_colour_grid
|
16
|
+
attr_accessor :cols_right_to_left
|
17
|
+
attr_accessor :show_outline
|
18
|
+
attr_accessor :remove_splits
|
19
|
+
attr_accessor :selected
|
20
|
+
# RED HERRING ALERT: "sheet_visible" is a clone of the "selected" attribute.
|
21
|
+
# Typically a workbook created by the Excel UI will have one sheet
|
22
|
+
# (the sheet that was selected when the user saved it)
|
23
|
+
# with both bits set to 1, and all other sheets will have both
|
24
|
+
# bits set to 0. The true visibility of the sheet is found in the "visibility"
|
25
|
+
# attribute obtained from the BOUNDSHEET record.
|
26
|
+
attr_accessor :sheet_visible
|
27
|
+
attr_accessor :page_preview
|
28
|
+
attr_accessor :first_visible_row
|
29
|
+
attr_accessor :first_visible_col
|
30
|
+
attr_accessor :grid_colour
|
31
|
+
attr_accessor :preview_magn
|
32
|
+
attr_accessor :normal_magn
|
33
|
+
attr_accessor :visibility
|
34
|
+
attr_accessor :vert_split_pos
|
35
|
+
attr_accessor :horz_split_pos
|
36
|
+
attr_accessor :vert_split_first_visible
|
37
|
+
attr_accessor :horz_split_first_visible
|
38
|
+
|
39
|
+
attr_accessor :delta
|
40
|
+
attr_accessor :save_recalc
|
41
|
+
|
42
|
+
attr_accessor :print_headers
|
43
|
+
attr_accessor :print_grid
|
44
|
+
attr_accessor :grid_set
|
45
|
+
attr_accessor :vert_page_breaks
|
46
|
+
attr_accessor :horz_page_breaks
|
47
|
+
attr_accessor :header_str
|
48
|
+
attr_accessor :footer_str
|
49
|
+
attr_accessor :print_centered_vert
|
50
|
+
attr_accessor :print_centered_horz
|
51
|
+
attr_accessor :left_margin
|
52
|
+
attr_accessor :right_margin
|
53
|
+
attr_accessor :top_margin
|
54
|
+
attr_accessor :bottom_margin
|
55
|
+
attr_accessor :paper_size_code
|
56
|
+
attr_accessor :print_scaling
|
57
|
+
attr_accessor :start_page_number
|
58
|
+
attr_accessor :fit_width_to_pages
|
59
|
+
attr_accessor :fit_height_to_pages
|
60
|
+
attr_accessor :print_in_rows
|
61
|
+
attr_accessor :portrait
|
62
|
+
attr_accessor :print_not_colour
|
63
|
+
attr_accessor :print_draft
|
64
|
+
attr_accessor :print_notes
|
65
|
+
attr_accessor :print_notes_at_end
|
66
|
+
attr_accessor :print_omit_errors
|
67
|
+
attr_accessor :print_hres
|
68
|
+
attr_accessor :print_vres
|
69
|
+
attr_accessor :header_margin
|
70
|
+
attr_accessor :footer_margin
|
71
|
+
attr_accessor :copies_num
|
72
|
+
|
73
|
+
attr_accessor :show_auto_page_breaks
|
74
|
+
attr_accessor :dialogue_sheet
|
75
|
+
attr_accessor :auto_style_outline
|
76
|
+
attr_accessor :outline_below
|
77
|
+
attr_accessor :outline_right
|
78
|
+
attr_accessor :fit_num_pages
|
79
|
+
attr_accessor :show_row_outline
|
80
|
+
attr_accessor :show_col_outline
|
81
|
+
attr_accessor :alt_expr_eval
|
82
|
+
attr_accessor :alt_formula_entries
|
83
|
+
|
84
|
+
attr_accessor :col_default_width
|
85
|
+
attr_reader :calc_mode
|
86
|
+
attr_accessor :calc_count
|
87
|
+
|
88
|
+
attr_accessor :protect
|
89
|
+
attr_accessor :wnd_protect
|
90
|
+
attr_accessor :obj_protect
|
91
|
+
attr_accessor :scen_protect
|
92
|
+
attr_accessor :password
|
93
|
+
|
94
|
+
def initialize(name, parent)
|
95
|
+
@name = name
|
96
|
+
@parent = parent
|
97
|
+
@rows = {}
|
98
|
+
@cols = {}
|
99
|
+
@merged_ranges = []
|
100
|
+
@bmp_rec = ''
|
101
|
+
@show_formulas = 0
|
102
|
+
@show_grid = 1
|
103
|
+
@show_headers = 1
|
104
|
+
@panes_frozen = 0
|
105
|
+
@show_empty_as_zero = 1
|
106
|
+
@auto_colour_grid = 1
|
107
|
+
@cols_right_to_left = 0
|
108
|
+
@show_outline = 1
|
109
|
+
@remove_splits = 0
|
110
|
+
@selected = 0
|
111
|
+
@sheet_visible = 0
|
112
|
+
@page_preview = 0
|
113
|
+
|
114
|
+
@first_visible_row = 0
|
115
|
+
@first_visible_col = 0
|
116
|
+
@grid_colour = 0x40
|
117
|
+
@preview_magn = 0
|
118
|
+
@normal_magn = 0
|
119
|
+
@visibility = 0
|
120
|
+
|
121
|
+
@vert_split_pos = nil
|
122
|
+
@horz_split_pos = nil
|
123
|
+
@vert_split_first_visible = nil
|
124
|
+
@horz_split_first_visible = nil
|
125
|
+
@split_active_pane = nil # TODO test implications of converting None -> Nil
|
126
|
+
|
127
|
+
@row_gut_width = 0
|
128
|
+
@col_gut_height = 0
|
129
|
+
|
130
|
+
@show_auto_page_breaks = 1
|
131
|
+
@dialogue_sheet = 0
|
132
|
+
@auto_style_outline = 0
|
133
|
+
@outline_below = 0
|
134
|
+
@outline_right = 0
|
135
|
+
@fit_num_pages = 0
|
136
|
+
@show_row_outline = 1
|
137
|
+
@show_col_outline = 1
|
138
|
+
@alt_expr_eval = 0
|
139
|
+
@alt_formula_entries = 0
|
140
|
+
|
141
|
+
@row_default_height = 0x00FF
|
142
|
+
@col_default_width = 0x0008
|
143
|
+
|
144
|
+
@default_row_height_mismatch = 0
|
145
|
+
@default_row_hidden = 0
|
146
|
+
@default_row_space_above = 0
|
147
|
+
@default_row_space_below = 0
|
148
|
+
|
149
|
+
@calc_mode = 1
|
150
|
+
@calc_count = 0x0064
|
151
|
+
@rc_ref_mode = 1
|
152
|
+
@iterations_on = 0
|
153
|
+
@delta = 0.001
|
154
|
+
@save_recalc = 0
|
155
|
+
@formula_options = ExcelFormula::RECALC_ALWAYS | ExcelFormula::CALC_ON_OPEN
|
156
|
+
|
157
|
+
@print_headers = 0
|
158
|
+
@print_grid = 0
|
159
|
+
@grid_set = 1
|
160
|
+
@vert_page_breaks = []
|
161
|
+
@horz_page_breaks = []
|
162
|
+
@header_str = '&P'
|
163
|
+
@footer_str = '&F'
|
164
|
+
@print_centered_vert = 0
|
165
|
+
@print_centered_horz = 1
|
166
|
+
@left_margin = 0.3 #0.5
|
167
|
+
@right_margin = 0.3 #0.5
|
168
|
+
@top_margin = 0.61 #1.0
|
169
|
+
@bottom_margin = 0.37 #1.0
|
170
|
+
@paper_size_code = 9 # A4
|
171
|
+
@print_scaling = 100
|
172
|
+
@start_page_number = 1
|
173
|
+
@fit_width_to_pages = 1
|
174
|
+
@fit_height_to_pages = 1
|
175
|
+
@print_in_rows = 1
|
176
|
+
@portrait = 1
|
177
|
+
@print_not_colour = 0
|
178
|
+
@print_draft = 0
|
179
|
+
@print_notes = 0
|
180
|
+
@print_notes_at_end = 0
|
181
|
+
@print_omit_errors = 0
|
182
|
+
@print_hres = 0x012C # 300 dpi
|
183
|
+
@print_vres = 0x012C # 300 dpi
|
184
|
+
@header_margin = 0.1
|
185
|
+
@footer_margin = 0.1
|
186
|
+
@copies_num = 1
|
187
|
+
|
188
|
+
@wnd_protect = 0
|
189
|
+
@obj_protect = 0
|
190
|
+
@protect = 0
|
191
|
+
@scen_protect = 0
|
192
|
+
@password = ''
|
193
|
+
|
194
|
+
@charts = []
|
195
|
+
end
|
196
|
+
|
197
|
+
# Accessors Performing Conversions
|
198
|
+
def row_default_height
|
199
|
+
twips_to_pixels(@row_default_height)
|
200
|
+
end
|
201
|
+
|
202
|
+
def row_default_height=(pixels)
|
203
|
+
@row_default_height = pixels_to_twips(pixels)
|
204
|
+
end
|
205
|
+
|
206
|
+
def calc_mode=(value)
|
207
|
+
@calc_mode = (value == 0xFFFF && value) || value & 0x01
|
208
|
+
end
|
209
|
+
|
210
|
+
def set_cell_style(r, c, style, create_blanks = false)
|
211
|
+
cell = rows[r].cell(c)
|
212
|
+
if cell.nil?
|
213
|
+
write(r, c, nil, style) if create_blanks
|
214
|
+
else
|
215
|
+
cell.set_style(style)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
def hide_columns(col_range)
|
220
|
+
col_range.each do |c|
|
221
|
+
hide_column(c)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
def unhide_columns(col_range)
|
226
|
+
col_range.each do |c|
|
227
|
+
unhide_column(c)
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
def set_column_widths(col_range, width)
|
232
|
+
col_range.each do |c|
|
233
|
+
set_column_width(c, width)
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
def hide_column(c)
|
238
|
+
col(c).hidden = true
|
239
|
+
end
|
240
|
+
|
241
|
+
def unhide_column(c)
|
242
|
+
col(c).hidden = false
|
243
|
+
end
|
244
|
+
|
245
|
+
# TODO fix this if column doesn't exist yet.
|
246
|
+
def set_column_width(c, width)
|
247
|
+
if width < 100
|
248
|
+
# Assume we are trying to use Excel-user style widths, scale up accordingly.
|
249
|
+
# You can call col's width method directly to avoid this.
|
250
|
+
width = width * 260
|
251
|
+
end
|
252
|
+
col(c).width = width
|
253
|
+
end
|
254
|
+
|
255
|
+
# Change the style for a range of cells. If nil is supplied for row_range,
|
256
|
+
# the new style is supplied to every row (i.e. the entire column). Only
|
257
|
+
# changes style for cells which actually exist, so this does not paint
|
258
|
+
# anything which has not been written to.
|
259
|
+
def set_range_style(row_range, col_range, style, create_blanks = false)
|
260
|
+
row_range ||= 0..65535
|
261
|
+
col_range ||= 0..255
|
262
|
+
|
263
|
+
@rows.each do |i, r|
|
264
|
+
next unless row_range.include?(i)
|
265
|
+
r.cells.each do |c|
|
266
|
+
next unless col_range.include?(c.col)
|
267
|
+
c.set_style(style)
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
# Write the text stored in label in a single cell at (r,c) according to style.
|
273
|
+
def write(r, c, label = "", style = @parent.styles.default_style)
|
274
|
+
row(r).write(c, label, style)
|
275
|
+
end
|
276
|
+
|
277
|
+
def write_array_to_row(array, r, c = 0, style = @parent.styles.default_style)
|
278
|
+
array.each_with_index do |a, i|
|
279
|
+
row(r).write(c + i, a, style)
|
280
|
+
end
|
281
|
+
end
|
282
|
+
alias :rarray :write_array_to_row
|
283
|
+
|
284
|
+
def write_array_to_column(array, c, r = 0, style = @parent.styles.default_style)
|
285
|
+
array.each_with_index do |a, i|
|
286
|
+
row(r + i).write(c, a, style)
|
287
|
+
end
|
288
|
+
end
|
289
|
+
alias :carray :write_array_to_column
|
290
|
+
|
291
|
+
def write_arrays(array_of_arrays, r = 0, c = 0, style = @parent.styles.default_style)
|
292
|
+
array_of_arrays.each_with_index do |a, i|
|
293
|
+
raise "not an array of arrays!" unless a.is_a?(Array)
|
294
|
+
write_array_to_row(a, r + i, c, style)
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
# Comment from xlwt:
|
299
|
+
## Stand-alone merge of previously written cells.
|
300
|
+
## Problems: (1) style to be used should be existing style of
|
301
|
+
## the top-left cell, not an arg.
|
302
|
+
## (2) should ensure that any previous data value in
|
303
|
+
## non-top-left cells is nobbled.
|
304
|
+
## Note: if a cell is set by a data record then later
|
305
|
+
## is referenced by a [MUL]BLANK record, Excel will blank
|
306
|
+
## out the cell on the screen, but OOo & Gnu will not
|
307
|
+
## blank it out. Need to do something better than writing
|
308
|
+
## multiple records. In the meantime, avoid this method and use
|
309
|
+
## write_merge() instead.
|
310
|
+
def merge(r1, r2, c1, c2, style = @parent.styles.default_style)
|
311
|
+
row(r1).write_blanks(c1 + 1, c2, style) if c2 > c1
|
312
|
+
((r1+1)...(r2+1)).each do |r|
|
313
|
+
row(r).write_blanks(c1, c2, style)
|
314
|
+
end
|
315
|
+
@merged_ranges << [r1, r2, c1, c2]
|
316
|
+
end
|
317
|
+
|
318
|
+
def write_merge(r1, r2, c1, c2, label="", style = @parent.styles.default_style)
|
319
|
+
write(r1, c1, label, style)
|
320
|
+
merge(r1, r2, c1, c2, style)
|
321
|
+
end
|
322
|
+
|
323
|
+
def to_biff
|
324
|
+
result = []
|
325
|
+
result << Biff8BOFRecord.new(Biff8BOFRecord::WORKSHEET).to_biff
|
326
|
+
# Calc Settings
|
327
|
+
result << CalcModeRecord.new(@calc_mode).to_biff
|
328
|
+
result << CalcCountRecord.new(@calc_count & 0xFFFF).to_biff
|
329
|
+
result << RefModeRecord.new(@rc_ref_mode & 0x01).to_biff
|
330
|
+
result << IterationRecord.new(@iterations_on & 0x01).to_biff
|
331
|
+
result << DeltaRecord.new(@delta).to_biff
|
332
|
+
result << SaveRecalcRecord.new(@save_recalc & 0x01).to_biff
|
333
|
+
|
334
|
+
result << guts_record
|
335
|
+
result << default_row_height_record
|
336
|
+
result << wsbool_record
|
337
|
+
result << @cols.sort.collect {|k, v| v.to_biff }.join
|
338
|
+
result << dimensions_rec
|
339
|
+
|
340
|
+
# Print Settings
|
341
|
+
result << PrintHeadersRecord.new(@print_headers).to_biff
|
342
|
+
result << PrintGridLinesRecord.new(@print_grid).to_biff
|
343
|
+
result << GridSetRecord.new(@grid_set).to_biff
|
344
|
+
result << HorizontalPageBreaksRecord.new(@horz_page_breaks.collect {|b| b.is_a?(Integer) ? [b, 0, -1] : b }).to_biff
|
345
|
+
result << VerticalPageBreaksRecord.new(@vert_page_breaks.collect {|b| b.is_a?(Integer) ? [b, 0, -1] : b }).to_biff
|
346
|
+
result << HeaderRecord.new(@header_str).to_biff
|
347
|
+
result << FooterRecord.new(@footer_str).to_biff
|
348
|
+
result << HCenterRecord.new(@print_centered_horz).to_biff
|
349
|
+
result << VCenterRecord.new(@print_centered_vert).to_biff
|
350
|
+
result << LeftMarginRecord.new(@left_margin).to_biff
|
351
|
+
result << RightMarginRecord.new(@right_margin).to_biff
|
352
|
+
result << TopMarginRecord.new(@top_margin).to_biff
|
353
|
+
result << BottomMarginRecord.new(@bottom_margin).to_biff
|
354
|
+
result << setup_page_record
|
355
|
+
|
356
|
+
# Protection Settings
|
357
|
+
result << ProtectRecord.new(as_numeric(@protect)).to_biff()
|
358
|
+
result << ScenarioProtectRecord.new(as_numeric(@scen_protect)).to_biff()
|
359
|
+
result << WindowProtectRecord.new(as_numeric(@wnd_protect)).to_biff()
|
360
|
+
result << ObjectProtectRecord.new(as_numeric(@obj_protect)).to_biff()
|
361
|
+
result << PasswordRecord.new(@password).to_biff()
|
362
|
+
|
363
|
+
keys = @rows.keys.sort
|
364
|
+
keys.each do |i|
|
365
|
+
result << @rows[i].to_biff
|
366
|
+
result << @rows[i].cells_biff
|
367
|
+
end
|
368
|
+
|
369
|
+
# @charts.each do |c|
|
370
|
+
# result << c.to_biff
|
371
|
+
# end
|
372
|
+
result << MergedCellsRecord.new(@merged_ranges).to_biff
|
373
|
+
result << @bmp_rec
|
374
|
+
result << window_2_record
|
375
|
+
result << panes_record
|
376
|
+
# result << hyperlink_table_record
|
377
|
+
result << EOFRecord.new.to_biff
|
378
|
+
|
379
|
+
result.join
|
380
|
+
end
|
381
|
+
|
382
|
+
def guts_record
|
383
|
+
max_row_level = @rows.values.inject(-1) {|level, row| row.level > level ? row.level : level }
|
384
|
+
max_col_level = @cols.values.inject(-1) {|level, col| col.level > level ? col.level : level }
|
385
|
+
|
386
|
+
row_visible_levels = @rows.empty? ? 0 : max_row_level + 1
|
387
|
+
col_visible_levels = @cols.empty? ? 0 : max_col_level + 1
|
388
|
+
|
389
|
+
GutsRecord.new(@row_gut_width, @col_gut_height, row_visible_levels, col_visible_levels).to_biff
|
390
|
+
end
|
391
|
+
|
392
|
+
def default_row_height_record
|
393
|
+
options = 0x00
|
394
|
+
options |= (@default_row_height_mismatch & 0x01) << 0
|
395
|
+
options |= (@default_row_hidden & 0x01) << 1
|
396
|
+
options |= (@default_row_space_above & 0x01) << 2
|
397
|
+
options |= (@default_row_space_below & 0x01) << 3
|
398
|
+
|
399
|
+
DefaultRowHeight.new(options, @row_default_height).to_biff
|
400
|
+
end
|
401
|
+
|
402
|
+
def wsbool_record
|
403
|
+
options = 0x00
|
404
|
+
options |= (@show_auto_page_breaks & 0x01) << 0
|
405
|
+
options |= (@dialogue_sheet & 0x01) << 4
|
406
|
+
options |= (@auto_style_outline & 0x01) << 5
|
407
|
+
options |= (@outline_below & 0x01) << 6
|
408
|
+
options |= (@outline_right & 0x01) << 7
|
409
|
+
options |= (@fit_num_pages & 0x01) << 8
|
410
|
+
options |= (@show_row_outline & 0x01) << 10
|
411
|
+
options |= (@show_col_outline & 0x01) << 11
|
412
|
+
options |= (@alt_expr_eval & 0x01) << 14
|
413
|
+
options |= (@alt_formula_entries & 0x01) << 15
|
414
|
+
|
415
|
+
WSBoolRecord.new(options).to_biff
|
416
|
+
end
|
417
|
+
|
418
|
+
def dimensions_rec
|
419
|
+
first_used_row = 0
|
420
|
+
last_used_row = 0
|
421
|
+
first_used_col = 0
|
422
|
+
last_used_col = 0
|
423
|
+
|
424
|
+
if !@rows.empty?
|
425
|
+
first_used_row = @rows.keys.sort.first
|
426
|
+
last_used_row = @rows.keys.sort.last
|
427
|
+
first_used_col = 0xFFFFFFFF
|
428
|
+
last_used_col = 0
|
429
|
+
end
|
430
|
+
|
431
|
+
first_used_col = @rows.values.inject(first_used_col) {|min_col, r| r.min_col_index < min_col ? min_col = r.min_col_index : min_col }
|
432
|
+
last_used_col = @rows.values.inject(last_used_col) {|max_col, r| r.max_col_index > max_col ? max_col = r.max_col_index : max_col }
|
433
|
+
|
434
|
+
DimensionsRecord.new(first_used_row, last_used_row, first_used_col, last_used_col).to_biff
|
435
|
+
end
|
436
|
+
|
437
|
+
def setup_page_record
|
438
|
+
setup_page_options = (@print_in_rows & 0x01) << 0
|
439
|
+
setup_page_options |= (@portrait & 0x01) << 1
|
440
|
+
setup_page_options |= (0x00 & 0x01) << 2
|
441
|
+
setup_page_options |= (@print_not_colour & 0x01) << 3
|
442
|
+
setup_page_options |= (@print_draft & 0x01) << 4
|
443
|
+
setup_page_options |= (@print_notes & 0x01) << 5
|
444
|
+
setup_page_options |= (0x00 & 0x01) << 6
|
445
|
+
setup_page_options |= (0x01 & 0x01) << 7
|
446
|
+
setup_page_options |= (@print_notes_at_end & 0x01) << 9
|
447
|
+
setup_page_options |= (@print_omit_errors & 0x03) << 10
|
448
|
+
|
449
|
+
args = [
|
450
|
+
@paper_size_code,
|
451
|
+
@print_scaling,
|
452
|
+
@start_page_number,
|
453
|
+
@fit_width_to_pages,
|
454
|
+
@fit_height_to_pages,
|
455
|
+
setup_page_options,
|
456
|
+
@print_hres,
|
457
|
+
@print_vres,
|
458
|
+
@header_margin,
|
459
|
+
@footer_margin,
|
460
|
+
@copies_num
|
461
|
+
]
|
462
|
+
SetupPageRecord.new(*args).to_biff
|
463
|
+
end
|
464
|
+
|
465
|
+
def window_2_record
|
466
|
+
options = 0
|
467
|
+
options |= (as_numeric(@show_formulas ) & 0x01) << 0
|
468
|
+
options |= (as_numeric(@show_grid ) & 0x01) << 1
|
469
|
+
options |= (as_numeric(@show_headers ) & 0x01) << 2
|
470
|
+
options |= (as_numeric(@panes_frozen ) & 0x01) << 3
|
471
|
+
options |= (as_numeric(@show_empty_as_zero ) & 0x01) << 4
|
472
|
+
options |= (as_numeric(@auto_colour_grid ) & 0x01) << 5
|
473
|
+
options |= (as_numeric(@cols_right_to_left ) & 0x01) << 6
|
474
|
+
options |= (as_numeric(@show_outline ) & 0x01) << 7
|
475
|
+
options |= (as_numeric(@remove_splits ) & 0x01) << 8
|
476
|
+
options |= (as_numeric(@selected ) & 0x01) << 9
|
477
|
+
options |= (as_numeric(@sheet_visible ) & 0x01) << 10
|
478
|
+
options |= (as_numeric(@page_preview ) & 0x01) << 11
|
479
|
+
|
480
|
+
if @page_preview != 0
|
481
|
+
if @preview_magn == 0
|
482
|
+
scl_magn = 60
|
483
|
+
else
|
484
|
+
scl_magn = @preview_magn
|
485
|
+
end
|
486
|
+
else
|
487
|
+
scl_magn = @normal_magn
|
488
|
+
end
|
489
|
+
|
490
|
+
Window2Record.new(options, @first_visible_row, @first_visible_col, @grid_colour, @preview_magn, @normal_magn, scl_magn).to_biff
|
491
|
+
end
|
492
|
+
|
493
|
+
def panes_record
|
494
|
+
return '' if @vert_split_pos.nil? && @horz_split_pos.nil?
|
495
|
+
@vert_split_pos = 0 if @vert_split_pos.nil?
|
496
|
+
@horz_split_pos = 0 if @horz_split_pos.nil?
|
497
|
+
if @panes_frozen
|
498
|
+
@vert_split_first_visible = @vert_split_pos if @vert_split_first_visible.nil?
|
499
|
+
@horz_split_first_visible = @horz_split_pos if @horz_split_first_visible.nil?
|
500
|
+
else
|
501
|
+
@vert_split_first_visible = 0 if @vert_split_first_visible.nil?
|
502
|
+
@horz_split_first_visible = 0 if @horz_split_first_visible.nil?
|
503
|
+
# inspired by pyXLWriter
|
504
|
+
@horz_split_pos = 20 * @horz_split_pos + 255
|
505
|
+
@vert_split_pos = 113.879 * @vert_split_pos + 390
|
506
|
+
end
|
507
|
+
@split_active_pane = 0 if @vert_split_pos > 0 and @horz_split_pos > 0
|
508
|
+
@split_active_pane = 1 if @vert_split_pos < 0 and @horz_split_pos == 0
|
509
|
+
@split_active_pane = 2 if @vert_split_pos == 0 and @horz_split_pos > 0
|
510
|
+
@split_active_pane = 3
|
511
|
+
|
512
|
+
args = [@vert_split_pos, @horz_split_pos, @horz_split_first_visible, @vert_split_first_visible, @split_active_pane]
|
513
|
+
PanesRecord.new(*args).to_biff
|
514
|
+
end
|
515
|
+
|
516
|
+
def hyperlink_table_record
|
517
|
+
result = ''
|
518
|
+
return result if @links.nil?
|
519
|
+
@links.each do |a, b|
|
520
|
+
x, y = a
|
521
|
+
url, target, textmark, description = b
|
522
|
+
result += HyperlinkRecord.new(x, x, y, y, url, target, textmark, description).to_biff
|
523
|
+
result += QuicktipRecord(x, x, y, y).to_biff unless description.nil?
|
524
|
+
end
|
525
|
+
result
|
526
|
+
end
|
527
|
+
|
528
|
+
# Fetch the row indicated by index, or create it if necessary.
|
529
|
+
def row(index)
|
530
|
+
rows[index] ||= Row.new(index, self)
|
531
|
+
end
|
532
|
+
|
533
|
+
# Fetch the col indicated by index, or create it if necessary.
|
534
|
+
def col(index)
|
535
|
+
cols[index] ||= Column.new(index, self)
|
536
|
+
end
|
537
|
+
alias :column :col
|
538
|
+
|
539
|
+
def row_height(row)
|
540
|
+
if @rows.include?(row)
|
541
|
+
@rows[row].height_in_pixels
|
542
|
+
else
|
543
|
+
17
|
544
|
+
end
|
545
|
+
end
|
546
|
+
|
547
|
+
def col_width(col)
|
548
|
+
if cols.keys.include?(col)
|
549
|
+
col.width_in_pixels
|
550
|
+
else
|
551
|
+
64
|
552
|
+
end
|
553
|
+
end
|
554
|
+
|
555
|
+
def insert_bitmap(filename, row, col, x = 0, y = 0, scale_x = 1, scale_y = 1)
|
556
|
+
bmp = ImDataBmpRecord.new(filename)
|
557
|
+
obj = ObjBmpRecord.new(row, col, self, bmp, x, y, scale_x, scale_y)
|
558
|
+
|
559
|
+
@bmp_rec += obj.to_biff + bmp.to_biff
|
560
|
+
end
|
561
|
+
end
|