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/style.rb
ADDED
@@ -0,0 +1,179 @@
|
|
1
|
+
class StyleFormat
|
2
|
+
attr_accessor :number_format_string
|
3
|
+
attr_accessor :font
|
4
|
+
attr_accessor :alignment
|
5
|
+
attr_accessor :borders
|
6
|
+
attr_accessor :pattern
|
7
|
+
attr_accessor :protection
|
8
|
+
|
9
|
+
def initialize(hash = {})
|
10
|
+
@number_format_string = hash[:number_format_string] || 'General'
|
11
|
+
|
12
|
+
@font = Font.new(hash_select(hash, /^font_/))
|
13
|
+
@alignment = Alignment.new(hash_select(hash, /^text_/))
|
14
|
+
@borders = Borders.new(hash_select(hash, /^border_/))
|
15
|
+
@pattern = Pattern.new(hash_select(hash, /^fill_/))
|
16
|
+
@protection = Protection.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def hash_select(hash, pattern)
|
20
|
+
new_hash = {}
|
21
|
+
hash.keys.each do |k|
|
22
|
+
next unless k.to_s =~ pattern
|
23
|
+
new_key = k.to_s.gsub(pattern, '').to_sym
|
24
|
+
new_hash[new_key] = hash[k]
|
25
|
+
end
|
26
|
+
new_hash
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class StyleCollection
|
31
|
+
attr_accessor :fonts
|
32
|
+
attr_accessor :number_formats
|
33
|
+
attr_accessor :styles
|
34
|
+
attr_accessor :default_style
|
35
|
+
attr_accessor :default_format
|
36
|
+
|
37
|
+
FIRST_USER_DEFINED_NUM_FORMAT_INDEX = 164
|
38
|
+
|
39
|
+
STANDARD_NUMBER_FORMATS = [
|
40
|
+
'General',
|
41
|
+
'0',
|
42
|
+
'0.00',
|
43
|
+
'#,##0',
|
44
|
+
'#,##0.00',
|
45
|
+
'"$"#,##0_);("$"#,##',
|
46
|
+
'"$"#,##0_);[Red]("$"#,##',
|
47
|
+
'"$"#,##0.00_);("$"#,##',
|
48
|
+
'"$"#,##0.00_);[Red]("$"#,##',
|
49
|
+
'0%',
|
50
|
+
'0.00%',
|
51
|
+
'0.00E+00',
|
52
|
+
'# ?/?',
|
53
|
+
'# ??/??',
|
54
|
+
'M/D/YY',
|
55
|
+
'D-MMM-YY',
|
56
|
+
'D-MMM',
|
57
|
+
'MMM-YY',
|
58
|
+
'h:mm AM/PM',
|
59
|
+
'h:mm:ss AM/PM',
|
60
|
+
'h:mm',
|
61
|
+
'h:mm:ss',
|
62
|
+
'M/D/YY h:mm',
|
63
|
+
'_(#,##0_);(#,##0)',
|
64
|
+
'_(#,##0_);[Red](#,##0)',
|
65
|
+
'_(#,##0.00_);(#,##0.00)',
|
66
|
+
'_(#,##0.00_);[Red](#,##0.00)',
|
67
|
+
'_("$"* #,##0_);_("$"* (#,##0);_("$"* "-"_);_(@_)',
|
68
|
+
'_(* #,##0_);_(* (#,##0);_(* "-"_);_(@_)',
|
69
|
+
'_("$"* #,##0.00_);_("$"* (#,##0.00);_("$"* "-"??_);_(@_)',
|
70
|
+
'_(* #,##0.00_);_(* (#,##0.00);_(* "-"??_);_(@_)',
|
71
|
+
'mm:ss',
|
72
|
+
'[h]:mm:ss',
|
73
|
+
'mm:ss.0',
|
74
|
+
'##0.0E+0',
|
75
|
+
'@'
|
76
|
+
]
|
77
|
+
|
78
|
+
def initialize
|
79
|
+
# Populate default font list.
|
80
|
+
@fonts = {}
|
81
|
+
# Initialize blank fonts into slots 0,1,2,3,5 in order to skip slot 4.
|
82
|
+
[0,1,2,3,5].each do |i|
|
83
|
+
@fonts[i] = Font.new
|
84
|
+
end
|
85
|
+
|
86
|
+
# Populate default number format list.
|
87
|
+
@number_formats = {}
|
88
|
+
STANDARD_NUMBER_FORMATS.each_with_index do |s, i|
|
89
|
+
index = (i <= 23) ? i : i + 14
|
90
|
+
@number_formats[index] = s
|
91
|
+
end
|
92
|
+
|
93
|
+
@styles = {}
|
94
|
+
@default_style = StyleFormat.new
|
95
|
+
|
96
|
+
# Store the 6 parameters of the default_style
|
97
|
+
@default_format = add_style(@default_style)[0]
|
98
|
+
end
|
99
|
+
|
100
|
+
def add(style)
|
101
|
+
if style.nil?
|
102
|
+
0x10 # Return the index of the default style.
|
103
|
+
else
|
104
|
+
add_style(style)[1] # Return the index of the style just stored.
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def number_format_index(number_format_string)
|
109
|
+
index = @number_formats.index(number_format_string)
|
110
|
+
if index.nil?
|
111
|
+
# TODO implement regex to check if valid string
|
112
|
+
index = FIRST_USER_DEFINED_NUM_FORMAT_INDEX + @number_formats.length - STANDARD_NUMBER_FORMATS.length
|
113
|
+
@number_formats[index] = number_format_string
|
114
|
+
end
|
115
|
+
index
|
116
|
+
end
|
117
|
+
|
118
|
+
def font_index(font)
|
119
|
+
index = @fonts.index(font)
|
120
|
+
if index.nil?
|
121
|
+
index = @fonts.length + 1
|
122
|
+
@fonts[index] = font
|
123
|
+
end
|
124
|
+
index
|
125
|
+
end
|
126
|
+
|
127
|
+
def format_index(format)
|
128
|
+
index = @styles.index(format)
|
129
|
+
if index.nil?
|
130
|
+
index = 0x10 + @styles.length
|
131
|
+
@styles[index] = format
|
132
|
+
end
|
133
|
+
index
|
134
|
+
end
|
135
|
+
|
136
|
+
private
|
137
|
+
# This is private, please use add(style) instead.
|
138
|
+
def add_style(style)
|
139
|
+
number_format_index = number_format_index(style.number_format_string)
|
140
|
+
font_index = font_index(style.font)
|
141
|
+
|
142
|
+
format = [font_index, number_format_index, style.alignment, style.borders, style.pattern, style.protection]
|
143
|
+
[format, format_index(format)]
|
144
|
+
end
|
145
|
+
|
146
|
+
public
|
147
|
+
def to_biff
|
148
|
+
fonts_biff + number_formats_biff + cell_styles_biff + StyleRecord.new.to_biff
|
149
|
+
end
|
150
|
+
|
151
|
+
# TODO use inject here?
|
152
|
+
def fonts_biff
|
153
|
+
result = ''
|
154
|
+
@fonts.sort.each do |i, f|
|
155
|
+
result += f.to_biff
|
156
|
+
end
|
157
|
+
result
|
158
|
+
end
|
159
|
+
|
160
|
+
def number_formats_biff
|
161
|
+
result = ''
|
162
|
+
@number_formats.sort.each do |i, f|
|
163
|
+
next if i < FIRST_USER_DEFINED_NUM_FORMAT_INDEX
|
164
|
+
result += NumberFormatRecord.new(i, f).to_biff
|
165
|
+
end
|
166
|
+
result
|
167
|
+
end
|
168
|
+
|
169
|
+
def cell_styles_biff
|
170
|
+
result = ''
|
171
|
+
0.upto(15) do |i|
|
172
|
+
result += XFRecord.new(@default_format, 'style').to_biff
|
173
|
+
end
|
174
|
+
@styles.sort.each do |i, f|
|
175
|
+
result += XFRecord.new(f).to_biff
|
176
|
+
end
|
177
|
+
result
|
178
|
+
end
|
179
|
+
end
|
data/lib/surpass.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
module Surpass
|
2
|
+
|
3
|
+
# :stopdoc:
|
4
|
+
VERSION = '0.0.3'
|
5
|
+
LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
|
6
|
+
PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
|
7
|
+
# :startdoc:
|
8
|
+
|
9
|
+
# Returns the version string for the library.
|
10
|
+
#
|
11
|
+
def self.version
|
12
|
+
VERSION
|
13
|
+
end
|
14
|
+
|
15
|
+
# Returns the library path for the module. If any arguments are given,
|
16
|
+
# they will be joined to the end of the libray path using
|
17
|
+
# <tt>File.join</tt>.
|
18
|
+
#
|
19
|
+
def self.libpath( *args )
|
20
|
+
args.empty? ? LIBPATH : ::File.join(LIBPATH, args.flatten)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns the lpath for the module. If any arguments are given,
|
24
|
+
# they will be joined to the end of the path using
|
25
|
+
# <tt>File.join</tt>.
|
26
|
+
#
|
27
|
+
def self.path( *args )
|
28
|
+
args.empty? ? PATH : ::File.join(PATH, args.flatten)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Utility method used to require all files ending in .rb that lie in the
|
32
|
+
# directory below this file that has the same name as the filename passed
|
33
|
+
# in. Optionally, a specific _directory_ name can be passed in such that
|
34
|
+
# the _filename_ does not have to be equivalent to the directory.
|
35
|
+
#
|
36
|
+
def self.require_all_libs_relative_to( fname, dir = "." )
|
37
|
+
dir ||= ::File.basename(fname, '.*')
|
38
|
+
search_me = ::File.expand_path(
|
39
|
+
::File.join(::File.dirname(fname), dir, '**', '*.rb'))
|
40
|
+
|
41
|
+
Dir.glob(search_me).sort.each do |rb|
|
42
|
+
next if File.basename(rb) === File.basename(__FILE__) # skip surpass.rb
|
43
|
+
require rb
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end # module Surpass
|
48
|
+
|
49
|
+
Surpass.require_all_libs_relative_to(__FILE__)
|
50
|
+
|
51
|
+
require 'date'
|
data/lib/utilities.rb
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
module Utilities
|
2
|
+
# For ease of comparing with pyExcelerator output values
|
3
|
+
# python seems to automatically decode to hex values
|
4
|
+
def hex_array_to_binary_string(array_of_hex_values)
|
5
|
+
[array_of_hex_values.collect {|h| [sprintf("%02x", h)]}.join].pack('H*')
|
6
|
+
end
|
7
|
+
|
8
|
+
def binary_string_to_hex_array(binary_string)
|
9
|
+
binary_string.unpack("H*")
|
10
|
+
end
|
11
|
+
|
12
|
+
def points_to_pixels(points)
|
13
|
+
points*(4.0/3)
|
14
|
+
end
|
15
|
+
|
16
|
+
def pixels_to_points(pixels)
|
17
|
+
pixels * (3.0 / 4)
|
18
|
+
end
|
19
|
+
|
20
|
+
def twips_to_pixels(twips)
|
21
|
+
twips / 15.0
|
22
|
+
end
|
23
|
+
|
24
|
+
def pixels_to_twips(pixels)
|
25
|
+
pixels * 15.0
|
26
|
+
end
|
27
|
+
|
28
|
+
def as_excel_date(date)
|
29
|
+
date = DateTime.parse(date.strftime("%c")) if date.is_a?(Time)
|
30
|
+
excel_date = (date - Date.civil(1899, 12, 31)).to_f
|
31
|
+
excel_date += 1 if excel_date > 59 # Add a day for Excel's missing leap day in 1900
|
32
|
+
excel_date
|
33
|
+
end
|
34
|
+
|
35
|
+
def mock_unicode_string(s)
|
36
|
+
[s.length, 0].pack('vC') + s
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
def as_boolean(input)
|
41
|
+
case input
|
42
|
+
when 1, true
|
43
|
+
true
|
44
|
+
when 0, false
|
45
|
+
false
|
46
|
+
else
|
47
|
+
raise "Can't convert #{input} from excel boolean!"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def as_numeric(input)
|
52
|
+
case input
|
53
|
+
when true, 1
|
54
|
+
1
|
55
|
+
when false, 0
|
56
|
+
0
|
57
|
+
else
|
58
|
+
raise "Can't convert #{input} to excel boolean!"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Mimic python's "hex" function 0x00
|
63
|
+
def hex(value)
|
64
|
+
"0x" + value.to_s(16)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def String.random_alphanumeric(size=16)
|
69
|
+
s = ""
|
70
|
+
size.times { s << (i = Kernel.rand(62); i += ((i < 10) ? 48 : ((i < 36) ? 55 : 61 ))).chr }
|
71
|
+
s
|
72
|
+
end
|
73
|
+
|
74
|
+
class TrueClass
|
75
|
+
def to_i
|
76
|
+
1
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
class FalseClass
|
81
|
+
def to_i
|
82
|
+
0
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
include Utilities
|
data/lib/workbook.rb
ADDED
@@ -0,0 +1,206 @@
|
|
1
|
+
class Workbook
|
2
|
+
MACROS = {
|
3
|
+
'Consolidate_Area' => 0x00,
|
4
|
+
'Auto_Open' => 0x01,
|
5
|
+
'Auto_Close' => 0x02,
|
6
|
+
'Extract' => 0x03,
|
7
|
+
'Database' => 0x04,
|
8
|
+
'Criteria' => 0x05,
|
9
|
+
'Print_Area' => 0x06,
|
10
|
+
'Print_Titles' => 0x07, # in the docs it says Pint_Titles, I think its a mistake
|
11
|
+
'Recorder' => 0x08,
|
12
|
+
'Data_Form' => 0x09,
|
13
|
+
'Auto_Activate' => 0x0A,
|
14
|
+
'Auto_Deactivate' => 0x0B,
|
15
|
+
'Sheet_Title' => 0x0C,
|
16
|
+
'_FilterDatabase' => 0x0D
|
17
|
+
}
|
18
|
+
|
19
|
+
attr_accessor :owner
|
20
|
+
attr_accessor :country_code
|
21
|
+
attr_accessor :wnd_protect
|
22
|
+
attr_accessor :obj_protect
|
23
|
+
attr_accessor :protect
|
24
|
+
attr_accessor :backup_on_save
|
25
|
+
attr_accessor :styles
|
26
|
+
attr_accessor :sst
|
27
|
+
|
28
|
+
def hpos_twips=(value)
|
29
|
+
@hpos_twips = value & 0xFFFF
|
30
|
+
end
|
31
|
+
|
32
|
+
attr_reader :vpos_twips
|
33
|
+
def vpos_twips=(value)
|
34
|
+
@vpos_twips = value & 0xFFFF
|
35
|
+
end
|
36
|
+
|
37
|
+
attr_reader :width_twips
|
38
|
+
def width_twips=(value)
|
39
|
+
@width_twips = value & 0xFFFF
|
40
|
+
end
|
41
|
+
|
42
|
+
attr_reader :height_twips
|
43
|
+
def height_twips=(value)
|
44
|
+
@height_twips = value & 0xFFFF
|
45
|
+
end
|
46
|
+
|
47
|
+
attr_reader :active_sheet
|
48
|
+
def active_sheet=(value)
|
49
|
+
@active_sheet = value & 0xFFFF
|
50
|
+
@first_tab_index = @active_sheet
|
51
|
+
end
|
52
|
+
|
53
|
+
attr_reader :tab_width_twips
|
54
|
+
def tab_width_twips=(value)
|
55
|
+
@tab_width_twips = value & 0xFFFF
|
56
|
+
end
|
57
|
+
|
58
|
+
attr_reader :default_style
|
59
|
+
|
60
|
+
def initialize(filename = nil)
|
61
|
+
@owner = 'None'
|
62
|
+
@wnd_protect = 0
|
63
|
+
@obj_protect = 0
|
64
|
+
@protect = 0
|
65
|
+
@backup_on_save = 0
|
66
|
+
|
67
|
+
@hpos_twips = 0x01E0
|
68
|
+
@vpos_twips = 0x005A
|
69
|
+
@width_twips = 0x3FCF
|
70
|
+
@height_twips = 0x2A4E
|
71
|
+
|
72
|
+
@active_sheet = 0
|
73
|
+
@first_tab_index = 0
|
74
|
+
@selected_tabs = 0x01
|
75
|
+
@tab_width_twips = 0x0258
|
76
|
+
|
77
|
+
@wnd_hidden = false
|
78
|
+
@wnd_mini = false
|
79
|
+
@hscroll_visible = true
|
80
|
+
@vscroll_visible = true
|
81
|
+
@tabs_visible = true
|
82
|
+
|
83
|
+
@styles = ::StyleCollection.new
|
84
|
+
|
85
|
+
@dates_1904 = false
|
86
|
+
@use_cell_values = true
|
87
|
+
|
88
|
+
@sst = SharedStringTable.new
|
89
|
+
|
90
|
+
@worksheets = []
|
91
|
+
@names = []
|
92
|
+
@refs = []
|
93
|
+
|
94
|
+
@filename = filename
|
95
|
+
end
|
96
|
+
|
97
|
+
def add_sheet(name = nil)
|
98
|
+
name ||= "Sheet#{@worksheets.length + 1}"
|
99
|
+
s = Worksheet.new(name, self)
|
100
|
+
@worksheets << s
|
101
|
+
s
|
102
|
+
end
|
103
|
+
|
104
|
+
def print_area(sheetnum, rstart, rend, cstart, cend)
|
105
|
+
if !sheetnum.is_a?(Integer)
|
106
|
+
i = 0
|
107
|
+
@worksheets.each_with_index do |w, i|
|
108
|
+
sheetnum = i+1 if w.name === sheetnum
|
109
|
+
break if sheetnum.is_a?(Integer)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
options = 0x0020 # see Options Flags for Name record
|
114
|
+
|
115
|
+
# FIXME: this is just a bad hack, need to use Formula to make the rpn
|
116
|
+
#~ rpn = ExcelFormula.Formula('').rpn()[2:] # minus the size field
|
117
|
+
rpn = [0x3B, 0x0000, rstart, rend, cstart, cend].pack('Cv5')
|
118
|
+
args = [options, 0x00, MACROS['Print_Area'], sheetnum, rpn]
|
119
|
+
@names << NameRecord.new(*args).to_biff
|
120
|
+
end
|
121
|
+
|
122
|
+
def to_biff
|
123
|
+
raise "You cannot save a workbook with no worksheets" if @worksheets.empty?
|
124
|
+
|
125
|
+
section_1_array = []
|
126
|
+
section_1_array << Biff8BOFRecord.new(Biff8BOFRecord::BOOK_GLOBAL).to_biff
|
127
|
+
section_1_array << InterfaceHeaderRecord.new.to_biff
|
128
|
+
section_1_array << MMSRecord.new.to_biff
|
129
|
+
section_1_array << InterfaceEndRecord.new.to_biff
|
130
|
+
section_1_array << WriteAccessRecord.new(owner).to_biff
|
131
|
+
section_1_array << CodepageBiff8Record.new.to_biff
|
132
|
+
section_1_array << DSFRecord.new.to_biff
|
133
|
+
section_1_array << TabIDRecord.new(@worksheets.length).to_biff
|
134
|
+
section_1_array << FnGroupCountRecord.new.to_biff
|
135
|
+
section_1_array << WindowProtectRecord.new(as_numeric(@wnd_protect)).to_biff
|
136
|
+
section_1_array << ProtectRecord.new(as_numeric(@protect)).to_biff
|
137
|
+
section_1_array << ObjectProtectRecord.new(as_numeric(@obj_protect)).to_biff
|
138
|
+
section_1_array << PasswordRecord.new.to_biff
|
139
|
+
section_1_array << Prot4RevRecord.new.to_biff
|
140
|
+
section_1_array << Prot4RevPassRecord.new.to_biff
|
141
|
+
section_1_array << BackupRecord.new(@backup_on_save).to_biff
|
142
|
+
section_1_array << HideObjRecord.new.to_biff
|
143
|
+
section_1_array << window_1_record
|
144
|
+
section_1_array << DateModeRecord.new(@dates_1904).to_biff
|
145
|
+
section_1_array << PrecisionRecord.new(@use_cell_values).to_biff
|
146
|
+
section_1_array << RefreshAllRecord.new.to_biff
|
147
|
+
section_1_array << BookBoolRecord.new.to_biff
|
148
|
+
section_1_array << @styles.to_biff
|
149
|
+
section_1_array << '' # Palette
|
150
|
+
section_1_array << UseSelfsRecord.new.to_biff
|
151
|
+
section_1 = section_1_array.join
|
152
|
+
|
153
|
+
section_3_array = []
|
154
|
+
section_3_array << CountryRecord.new(@country_code, @country_code).to_biff unless @country_code.nil?
|
155
|
+
# section_3_array << InternalReferenceSupBookRecord.new(@worksheets.length).to_biff
|
156
|
+
# section_3_array << ExternSheetRecord.new(@refs).to_biff
|
157
|
+
# section_3_array << @names.collect {|n| n.to_biff}.join
|
158
|
+
section_3_array << @sst.to_biff
|
159
|
+
section_3 = section_3_array.join
|
160
|
+
|
161
|
+
section_4 = '' # ExtSSTRecord
|
162
|
+
section_5 = EOFRecord.new.to_biff
|
163
|
+
|
164
|
+
@worksheets[@active_sheet].selected = true
|
165
|
+
worksheet_biff_data = @worksheets.collect {|w| w.to_biff }
|
166
|
+
worksheet_biff_data_lengths = worksheet_biff_data.collect {|w| w.length }
|
167
|
+
section_6 = worksheet_biff_data.join
|
168
|
+
|
169
|
+
# Need to know how long the bound sheet records will be
|
170
|
+
boundsheet_data_lengths = @worksheets.collect {|w| BoundSheetRecord.new(0x00, w.visibility, w.name).to_biff.length }
|
171
|
+
total_boundsheet_data_length = boundsheet_data_lengths.inject(0) {|sum, l| sum + l}
|
172
|
+
start_position = section_1.length + total_boundsheet_data_length + section_3.length + section_4.length + section_5.length
|
173
|
+
|
174
|
+
boundsheet_records = []
|
175
|
+
@worksheets.each_with_index do |w, i|
|
176
|
+
boundsheet_records << BoundSheetRecord.new(start_position, w.visibility, w.name).to_biff
|
177
|
+
start_position += worksheet_biff_data_lengths[i]
|
178
|
+
end
|
179
|
+
|
180
|
+
section_2 = boundsheet_records.join
|
181
|
+
section_1 + section_2 + section_3 + section_4 + section_5 + section_6
|
182
|
+
end
|
183
|
+
|
184
|
+
def window_1_record
|
185
|
+
flags = 0
|
186
|
+
flags |= (as_numeric(@wnd_hidden)) << 0
|
187
|
+
flags |= (as_numeric(@wnd_mini)) << 1
|
188
|
+
flags |= (as_numeric(@hscroll_visible)) << 3
|
189
|
+
flags |= (as_numeric(@vscroll_visible)) << 4
|
190
|
+
flags |= (as_numeric(@tabs_visible)) << 5
|
191
|
+
|
192
|
+
args = [@hpos_twips, @vpos_twips, @width_twips, @height_twips, flags, @active_sheet, @first_tab_index, @selected_tabs, @tab_width_twips]
|
193
|
+
Window1Record.new(*args).to_biff
|
194
|
+
end
|
195
|
+
|
196
|
+
def data
|
197
|
+
doc = ExcelDocument.new
|
198
|
+
doc.data(to_biff)
|
199
|
+
end
|
200
|
+
|
201
|
+
def save(filename = nil)
|
202
|
+
@filename = filename unless filename.nil?
|
203
|
+
doc = ExcelDocument.new
|
204
|
+
doc.save(@filename, to_biff)
|
205
|
+
end
|
206
|
+
end
|