writeexcel 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. data/README +26 -31
  2. data/examples/a_simple.rb +42 -42
  3. data/examples/{autofilters.rb → autofilter.rb} +264 -266
  4. data/examples/bigfile.rb +29 -0
  5. data/examples/chart_area.rb +120 -0
  6. data/examples/chart_bar.rb +119 -0
  7. data/examples/chart_column.rb +119 -0
  8. data/examples/chart_line.rb +119 -0
  9. data/examples/chart_pie.rb +107 -0
  10. data/examples/chart_scatter.rb +120 -0
  11. data/examples/chart_stock.rb +147 -0
  12. data/examples/copyformat.rb +51 -51
  13. data/examples/data_validate.rb +278 -278
  14. data/examples/date_time.rb +86 -86
  15. data/examples/defined_name.rb +31 -0
  16. data/examples/demo.rb +120 -118
  17. data/examples/diag_border.rb +35 -35
  18. data/examples/formats.rb +489 -489
  19. data/examples/header.rb +136 -136
  20. data/examples/hidden.rb +28 -28
  21. data/examples/hyperlink.rb +42 -42
  22. data/examples/images.rb +52 -52
  23. data/examples/merge1.rb +39 -39
  24. data/examples/merge2.rb +44 -44
  25. data/examples/merge3.rb +65 -65
  26. data/examples/merge4.rb +82 -82
  27. data/examples/merge5.rb +79 -79
  28. data/examples/properties.rb +33 -0
  29. data/examples/properties_jp.rb +32 -0
  30. data/examples/protection.rb +46 -46
  31. data/examples/regions.rb +52 -52
  32. data/examples/repeat.rb +42 -42
  33. data/examples/stats.rb +75 -75
  34. data/examples/stocks.rb +80 -80
  35. data/examples/tab_colors.rb +30 -30
  36. data/examples/write_arrays.rb +82 -0
  37. data/lib/writeexcel.rb +1134 -18
  38. data/lib/writeexcel/biffwriter.rb +273 -260
  39. data/lib/writeexcel/chart.rb +2306 -217
  40. data/lib/writeexcel/charts/area.rb +152 -0
  41. data/lib/writeexcel/charts/bar.rb +177 -0
  42. data/lib/writeexcel/charts/column.rb +156 -0
  43. data/lib/writeexcel/charts/external.rb +61 -0
  44. data/lib/writeexcel/charts/line.rb +152 -0
  45. data/lib/writeexcel/charts/pie.rb +169 -0
  46. data/lib/writeexcel/charts/scatter.rb +192 -0
  47. data/lib/writeexcel/charts/stock.rb +211 -0
  48. data/lib/writeexcel/excelformulaparser.rb +208 -195
  49. data/lib/writeexcel/format.rb +1697 -1108
  50. data/lib/writeexcel/formula.rb +1050 -986
  51. data/lib/writeexcel/olewriter.rb +322 -322
  52. data/lib/writeexcel/properties.rb +251 -250
  53. data/lib/writeexcel/storage_lite.rb +968 -0
  54. data/lib/writeexcel/workbook.rb +3294 -2630
  55. data/lib/writeexcel/worksheet.rb +9012 -6377
  56. data/test/excelfile/Chart1.xls +0 -0
  57. data/test/excelfile/Chart2.xls +0 -0
  58. data/test/excelfile/Chart3.xls +0 -0
  59. data/test/excelfile/Chart4.xls +0 -0
  60. data/test/excelfile/Chart5.xls +0 -0
  61. data/test/perl_output/Chart1.xls.data +0 -0
  62. data/test/perl_output/Chart2.xls.data +0 -0
  63. data/test/perl_output/Chart3.xls.data +0 -0
  64. data/test/perl_output/Chart4.xls.data +0 -0
  65. data/test/perl_output/Chart5.xls.data +0 -0
  66. data/test/perl_output/a_simple.xls +0 -0
  67. data/test/perl_output/autofilter.xls +0 -0
  68. data/test/perl_output/chart_area.xls +0 -0
  69. data/test/perl_output/chart_bar.xls +0 -0
  70. data/test/perl_output/chart_column.xls +0 -0
  71. data/test/perl_output/chart_line.xls +0 -0
  72. data/test/perl_output/data_validate.xls +0 -0
  73. data/test/perl_output/date_time.xls +0 -0
  74. data/test/perl_output/demo.xls +0 -0
  75. data/test/perl_output/demo101.bin +0 -0
  76. data/test/perl_output/demo201.bin +0 -0
  77. data/test/perl_output/demo301.bin +0 -0
  78. data/test/perl_output/demo401.bin +0 -0
  79. data/test/perl_output/demo501.bin +0 -0
  80. data/test/perl_output/diag_border.xls +0 -0
  81. data/test/perl_output/headers.xls +0 -0
  82. data/test/perl_output/hyperlink.xls +0 -0
  83. data/test/perl_output/images.xls +0 -0
  84. data/test/perl_output/merge1.xls +0 -0
  85. data/test/perl_output/merge2.xls +0 -0
  86. data/test/perl_output/merge3.xls +0 -0
  87. data/test/perl_output/merge4.xls +0 -0
  88. data/test/perl_output/merge5.xls +0 -0
  89. data/test/perl_output/protection.xls +0 -0
  90. data/test/perl_output/regions.xls +0 -0
  91. data/test/perl_output/stats.xls +0 -0
  92. data/test/perl_output/stocks.xls +0 -0
  93. data/test/perl_output/tab_colors.xls +0 -0
  94. data/test/perl_output/unicode_cyrillic.xls +0 -0
  95. data/test/perl_output/workbook1.xls +0 -0
  96. data/test/perl_output/workbook2.xls +0 -0
  97. data/test/tc_all.rb +32 -31
  98. data/test/tc_biff.rb +104 -104
  99. data/test/tc_chart.rb +22 -22
  100. data/test/tc_example_match.rb +1944 -1280
  101. data/test/tc_format.rb +1254 -1267
  102. data/test/tc_formula.rb +63 -63
  103. data/test/tc_ole.rb +110 -110
  104. data/test/tc_storage_lite.rb +149 -0
  105. data/test/tc_workbook.rb +140 -115
  106. data/test/tc_worksheet.rb +115 -115
  107. data/test/test_00_IEEE_double.rb +14 -14
  108. data/test/test_01_add_worksheet.rb +12 -12
  109. data/test/test_02_merge_formats.rb +58 -58
  110. data/test/test_04_dimensions.rb +397 -397
  111. data/test/test_05_rows.rb +182 -182
  112. data/test/test_06_extsst.rb +80 -80
  113. data/test/test_11_date_time.rb +484 -484
  114. data/test/test_12_date_only.rb +506 -506
  115. data/test/test_13_date_seconds.rb +486 -486
  116. data/test/test_21_escher.rb +642 -629
  117. data/test/test_22_mso_drawing_group.rb +750 -739
  118. data/test/test_23_note.rb +78 -78
  119. data/test/test_24_txo.rb +80 -80
  120. data/test/test_25_position_object.rb +82 -0
  121. data/test/test_26_autofilter.rb +327 -327
  122. data/test/test_27_autofilter.rb +144 -144
  123. data/test/test_28_autofilter.rb +174 -174
  124. data/test/test_29_process_jpg.rb +681 -131
  125. data/test/test_30_validation_dval.rb +82 -82
  126. data/test/test_31_validation_dv_strings.rb +131 -131
  127. data/test/test_32_validation_dv_formula.rb +211 -211
  128. data/test/test_40_property_types.rb +191 -191
  129. data/test/test_41_properties.rb +238 -238
  130. data/test/test_42_set_properties.rb +442 -419
  131. data/test/test_50_name_stored.rb +305 -0
  132. data/test/test_51_name_print_area.rb +363 -0
  133. data/test/test_52_name_print_titles.rb +460 -0
  134. data/test/test_53_autofilter.rb +209 -0
  135. data/test/test_60_chart_generic.rb +576 -0
  136. data/test/test_61_chart_subclasses.rb +97 -0
  137. data/test/test_62_chart_formats.rb +270 -0
  138. data/test/test_63_chart_area_formats.rb +647 -0
  139. data/test/test_chartex.rb +35 -0
  140. data/test/ts_all.rb +46 -34
  141. data/writeexcel.gemspec +18 -0
  142. data/writeexcel.rdoc +583 -0
  143. metadata +162 -108
@@ -1,322 +1,322 @@
1
- ###############################################################################
2
- #
3
- # BIFFwriter - An abstract base class for Excel workbooks and worksheets.
4
- #
5
- #
6
- # Used in conjunction with Spreadsheet::WriteExcel
7
- #
8
- # Copyright 2000-2008, John McNamara, jmcnamara@cpan.org
9
- #
10
- # original written in Perl by John McNamara
11
- # converted to Ruby by Hideo Nakamura, cxn03651@msj.biglobe.ne.jp
12
- #
13
- class MaxSizeError < StandardError; end
14
-
15
- class OLEWriter
16
-
17
- # Not meant for public consumption
18
- MaxSize = 7087104 # Use Spreadsheet::WriteExcel::Big to exceed this
19
- BlockSize = 4096
20
- BlockDiv = 512
21
- ListBlocks = 127
22
-
23
- attr_reader :biff_size, :book_size, :big_blocks, :list_blocks
24
- attr_reader :root_start, :size_allowed
25
- attr_accessor :biff_only, :internal_fh
26
-
27
- # Accept an IO or IO-like object or a filename (as a String)
28
- def initialize(arg)
29
- if arg.kind_of?(String)
30
- @io = File.open(arg, "w")
31
- else
32
- @io = arg
33
- end
34
- @io.binmode
35
-
36
- @filehandle = ""
37
- @fileclosed = false
38
- @internal_fh = 0
39
- @biff_only = 0
40
- @size_allowed = true
41
- @biff_size = 0
42
- @book_size = 0
43
- @big_blocks = 0
44
- @list_blocks = 0
45
- @root_start = 0
46
- @block_count = 4
47
- end
48
-
49
- # Imitate IO.open behavior
50
-
51
- ###############################################################################
52
- #
53
- # _initialize()
54
- #
55
- # Create a new filehandle or use the provided filehandle.
56
- #
57
- def _initialize
58
- olefile = @olefilename
59
-
60
- # If the filename is a reference it is assumed that it is a valid
61
- # filehandle, if not we create a filehandle.
62
- #
63
-
64
- # Create a new file, open for writing
65
- fh = open(olefile, "wb")
66
-
67
- # Workbook.pm also checks this but something may have happened since
68
- # then.
69
- raise "Can't open olefile. It may be in use or protected.\n" unless fh
70
-
71
- @internal_fh = 1
72
-
73
- # Store filehandle
74
- @filehandle = fh
75
- end
76
-
77
- def self.open(arg)
78
- if block_given?
79
- ole = self.new(arg)
80
- result = yield(ole)
81
- ole.close
82
- result
83
- else
84
- self.new(arg)
85
- end
86
- end
87
-
88
- ###############################################################################
89
- #
90
- # write($data)
91
- #
92
- # Write BIFF data to OLE file.
93
- #
94
- def write(data)
95
- #print "ole write\n"
96
- #print data.unpack('C*').map! {|c| sprintf("%02X", c) }.join(' ') + "\n\n"
97
- @io.write(data)
98
- end
99
- # def print(data)
100
- # @io.print(data)
101
- # end
102
-
103
- ###############################################################################
104
- #
105
- # set_size($biffsize)
106
- #
107
- # Set the size of the data to be written to the OLE stream
108
- #
109
- # $big_blocks = (109 depot block x (128 -1 marker word)
110
- # - (1 x end words)) = 13842
111
- # $maxsize = $big_blocks * 512 bytes = 7087104
112
- #
113
- def set_size(size = BlockSize)
114
- if size > MaxSize
115
- return @size_allowed = false
116
- end
117
-
118
- @biff_size = size
119
-
120
- if biff_size > BlockSize
121
- @book_size = size
122
- else
123
- @book_size = BlockSize
124
- end
125
-
126
- @size_allowed = true
127
- end
128
-
129
- ###############################################################################
130
- #
131
- # _calculate_sizes()
132
- #
133
- # Calculate various sizes needed for the OLE stream
134
- #
135
- def calculate_sizes
136
- @big_blocks = (@book_size.to_f/BlockDiv.to_f).ceil
137
- @list_blocks = (@big_blocks / ListBlocks) + 1
138
- @root_start = @big_blocks
139
- end
140
-
141
- ###############################################################################
142
- #
143
- # close()
144
- #
145
- # Write root entry, big block list and close the filehandle.
146
- # This routine is used to explicitly close the open filehandle without
147
- # having to wait for DESTROY.
148
- #
149
- def close
150
- if @size_allowed == true
151
- #print "write_padding"
152
- write_padding if @biff_only == 0
153
- #print "write_property_storage"
154
- write_property_storage if @biff_only == 0
155
- #print "write_big_block_depot"
156
- write_big_block_depot if @biff_only == 0
157
- end
158
- @io.close
159
- end
160
-
161
- ###############################################################################
162
- #
163
- # write_header()
164
- #
165
- # Write OLE header block.
166
- #
167
- def write_header
168
- return if @biff_only == 1
169
- calculate_sizes
170
- root_start = @root_start
171
- num_lists = @list_blocks
172
-
173
- id = [0xD0CF11E0, 0xA1B11AE1].pack("NN")
174
- unknown1 = [0x00, 0x00, 0x00, 0x00].pack("VVVV")
175
- unknown2 = [0x3E, 0x03].pack("vv")
176
- unknown3 = [-2].pack("v")
177
- unknown4 = [0x09].pack("v")
178
- unknown5 = [0x06, 0x00, 0x00].pack("VVV")
179
- num_bbd_blocks = [num_lists].pack("V")
180
- root_startblock = [root_start].pack("V")
181
- unknown6 = [0x00, 0x1000].pack("VV")
182
- sbd_startblock = [-2].pack("V")
183
- unknown7 = [0x00, -2 ,0x00].pack("VVV")
184
-
185
- write(id)
186
- write(unknown1)
187
- write(unknown2)
188
- write(unknown3)
189
- write(unknown4)
190
- write(unknown5)
191
- write(num_bbd_blocks)
192
- write(root_startblock)
193
- write(unknown6)
194
- write(sbd_startblock)
195
- write(unknown7)
196
-
197
- unused = [-1].pack("V")
198
-
199
- 1.upto(num_lists){
200
- root_start += 1
201
- write([root_start].pack("V"))
202
- }
203
-
204
- num_lists.upto(108){
205
- write(unused)
206
- }
207
- end
208
-
209
- ###############################################################################
210
- #
211
- # _write_big_block_depot()
212
- #
213
- # Write big block depot.
214
- #
215
- def write_big_block_depot
216
- num_blocks = @big_blocks
217
- num_lists = @list_blocks
218
- total_blocks = num_lists * 128
219
- used_blocks = num_blocks + num_lists + 2
220
-
221
- marker = [-3].pack("V")
222
- end_of_chain = [-2].pack("V")
223
- unused = [-1].pack("V")
224
-
225
- 1.upto(num_blocks-1){|n|
226
- write([n].pack("V"))
227
- }
228
-
229
- write end_of_chain
230
- write end_of_chain
231
-
232
- 1.upto(num_lists){ write(marker) }
233
-
234
- used_blocks.upto(total_blocks){ write(unused) }
235
-
236
- end
237
-
238
- ###############################################################################
239
- #
240
- # _write_property_storage()
241
- #
242
- # Write property storage. TODO: add summary sheets
243
- #
244
- def write_property_storage
245
-
246
- ######### name type dir start size
247
- write_pps('Root Entry', 0x05, 1, -2, 0x00)
248
- write_pps('Workbook', 0x02, -1, 0x00, @book_size)
249
- write_pps("", 0x00, -1, 0x00, 0x0000)
250
- write_pps("", 0x00, -1, 0x00, 0x0000)
251
- end
252
-
253
- ###############################################################################
254
- #
255
- # _write_pps()
256
- #
257
- # Write property sheet in property storage
258
- #
259
- def write_pps(name, type, dir, start, size)
260
- length = 0
261
- ord_name = []
262
- unless name.empty?
263
- name = name + "\0"
264
- ord_name = name.unpack("c*")
265
- length = name.length * 2
266
- end
267
-
268
- rawname = ord_name.pack("v*")
269
- zero = [0].pack("C")
270
-
271
- pps_sizeofname = [length].pack("v") #0x40
272
- pps_type = [type].pack("v") #0x42
273
- pps_prev = [-1].pack("V") #0x44
274
- pps_next = [-1].pack("V") #0x48
275
- pps_dir = [dir].pack("V") #0x4c
276
-
277
- unknown = [0].pack("V")
278
-
279
- pps_ts1s = [0].pack("V") #0x64
280
- pps_ts1d = [0].pack("V") #0x68
281
- pps_ts2s = [0].pack("V") #0x6c
282
- pps_ts2d = [0].pack("V") #0x70
283
- pps_sb = [start].pack("V") #0x74
284
- pps_size = [size].pack("V") #0x78
285
-
286
- write(rawname)
287
- for n in 1..64-length
288
- write(zero)
289
- end
290
- write(pps_sizeofname)
291
- write(pps_type)
292
- write(pps_prev)
293
- write(pps_next)
294
- write(pps_dir)
295
- for n in 1..5
296
- write(unknown)
297
- end
298
- write(pps_ts1s)
299
- write(pps_ts1d)
300
- write(pps_ts2s)
301
- write(pps_ts2d)
302
- write(pps_sb)
303
- write(pps_size)
304
- write(unknown)
305
- end
306
-
307
- ###############################################################################
308
- #
309
- # _write_padding()
310
- #
311
- # Pad the end of the file
312
- #
313
- def write_padding
314
- min_size = 512
315
- min_size = BlockSize if @biff_size < BlockSize
316
-
317
- if @biff_size % min_size != 0
318
- padding = min_size - (@biff_size % min_size)
319
- write("\0" * padding)
320
- end
321
- end
322
- end
1
+ ###############################################################################
2
+ #
3
+ # BIFFwriter - An abstract base class for Excel workbooks and worksheets.
4
+ #
5
+ #
6
+ # Used in conjunction with WriteExcel
7
+ #
8
+ # Copyright 2000-2010, John McNamara, jmcnamara@cpan.org
9
+ #
10
+ # original written in Perl by John McNamara
11
+ # converted to Ruby by Hideo Nakamura, cxn03651@msj.biglobe.ne.jp
12
+ #
13
+ class MaxSizeError < StandardError; end #:nodoc:
14
+
15
+ class OLEWriter #:nodoc:
16
+
17
+ # Not meant for public consumption
18
+ MaxSize = 7087104 # Use WriteExcel::Big to exceed this
19
+ BlockSize = 4096
20
+ BlockDiv = 512
21
+ ListBlocks = 127
22
+
23
+ attr_reader :biff_size, :book_size, :big_blocks, :list_blocks
24
+ attr_reader :root_start, :size_allowed
25
+ attr_accessor :biff_only, :internal_fh
26
+
27
+ # Accept an IO or IO-like object or a filename (as a String)
28
+ def initialize(arg)
29
+ if arg.kind_of?(String)
30
+ @io = File.open(arg, "w")
31
+ else
32
+ @io = arg
33
+ end
34
+ @io.binmode
35
+
36
+ @filehandle = ""
37
+ @fileclosed = false
38
+ @internal_fh = 0
39
+ @biff_only = 0
40
+ @size_allowed = true
41
+ @biff_size = 0
42
+ @book_size = 0
43
+ @big_blocks = 0
44
+ @list_blocks = 0
45
+ @root_start = 0
46
+ @block_count = 4
47
+ end
48
+
49
+ # Imitate IO.open behavior
50
+
51
+ ###############################################################################
52
+ #
53
+ # _initialize()
54
+ #
55
+ # Create a new filehandle or use the provided filehandle.
56
+ #
57
+ def _initialize
58
+ olefile = @olefilename
59
+
60
+ # If the filename is a reference it is assumed that it is a valid
61
+ # filehandle, if not we create a filehandle.
62
+ #
63
+
64
+ # Create a new file, open for writing
65
+ fh = open(olefile, "wb")
66
+
67
+ # Workbook.pm also checks this but something may have happened since
68
+ # then.
69
+ raise "Can't open olefile. It may be in use or protected.\n" unless fh
70
+
71
+ @internal_fh = 1
72
+
73
+ # Store filehandle
74
+ @filehandle = fh
75
+ end
76
+
77
+ def self.open(arg)
78
+ if block_given?
79
+ ole = self.new(arg)
80
+ result = yield(ole)
81
+ ole.close
82
+ result
83
+ else
84
+ self.new(arg)
85
+ end
86
+ end
87
+
88
+ ###############################################################################
89
+ #
90
+ # write($data)
91
+ #
92
+ # Write BIFF data to OLE file.
93
+ #
94
+ def write(data)
95
+ #print "ole write\n"
96
+ #print data.unpack('C*').map! {|c| sprintf("%02X", c) }.join(' ') + "\n\n"
97
+ @io.write(data)
98
+ end
99
+ # def print(data)
100
+ # @io.print(data)
101
+ # end
102
+
103
+ ###############################################################################
104
+ #
105
+ # set_size($biffsize)
106
+ #
107
+ # Set the size of the data to be written to the OLE stream
108
+ #
109
+ # $big_blocks = (109 depot block x (128 -1 marker word)
110
+ # - (1 x end words)) = 13842
111
+ # $maxsize = $big_blocks * 512 bytes = 7087104
112
+ #
113
+ def set_size(size = BlockSize)
114
+ if size > MaxSize
115
+ return @size_allowed = false
116
+ end
117
+
118
+ @biff_size = size
119
+
120
+ if biff_size > BlockSize
121
+ @book_size = size
122
+ else
123
+ @book_size = BlockSize
124
+ end
125
+
126
+ @size_allowed = true
127
+ end
128
+
129
+ ###############################################################################
130
+ #
131
+ # _calculate_sizes()
132
+ #
133
+ # Calculate various sizes needed for the OLE stream
134
+ #
135
+ def calculate_sizes
136
+ @big_blocks = (@book_size.to_f/BlockDiv.to_f).ceil
137
+ @list_blocks = (@big_blocks / ListBlocks) + 1
138
+ @root_start = @big_blocks
139
+ end
140
+
141
+ ###############################################################################
142
+ #
143
+ # close()
144
+ #
145
+ # Write root entry, big block list and close the filehandle.
146
+ # This routine is used to explicitly close the open filehandle without
147
+ # having to wait for DESTROY.
148
+ #
149
+ def close
150
+ if @size_allowed == true
151
+ #print "write_padding"
152
+ write_padding if @biff_only == 0
153
+ #print "write_property_storage"
154
+ write_property_storage if @biff_only == 0
155
+ #print "write_big_block_depot"
156
+ write_big_block_depot if @biff_only == 0
157
+ end
158
+ @io.close
159
+ end
160
+
161
+ ###############################################################################
162
+ #
163
+ # write_header()
164
+ #
165
+ # Write OLE header block.
166
+ #
167
+ def write_header
168
+ return if @biff_only == 1
169
+ calculate_sizes
170
+ root_start = @root_start
171
+ num_lists = @list_blocks
172
+
173
+ id = [0xD0CF11E0, 0xA1B11AE1].pack("NN")
174
+ unknown1 = [0x00, 0x00, 0x00, 0x00].pack("VVVV")
175
+ unknown2 = [0x3E, 0x03].pack("vv")
176
+ unknown3 = [-2].pack("v")
177
+ unknown4 = [0x09].pack("v")
178
+ unknown5 = [0x06, 0x00, 0x00].pack("VVV")
179
+ num_bbd_blocks = [num_lists].pack("V")
180
+ root_startblock = [root_start].pack("V")
181
+ unknown6 = [0x00, 0x1000].pack("VV")
182
+ sbd_startblock = [-2].pack("V")
183
+ unknown7 = [0x00, -2 ,0x00].pack("VVV")
184
+
185
+ write(id)
186
+ write(unknown1)
187
+ write(unknown2)
188
+ write(unknown3)
189
+ write(unknown4)
190
+ write(unknown5)
191
+ write(num_bbd_blocks)
192
+ write(root_startblock)
193
+ write(unknown6)
194
+ write(sbd_startblock)
195
+ write(unknown7)
196
+
197
+ unused = [-1].pack("V")
198
+
199
+ 1.upto(num_lists){
200
+ root_start += 1
201
+ write([root_start].pack("V"))
202
+ }
203
+
204
+ num_lists.upto(108){
205
+ write(unused)
206
+ }
207
+ end
208
+
209
+ ###############################################################################
210
+ #
211
+ # _write_big_block_depot()
212
+ #
213
+ # Write big block depot.
214
+ #
215
+ def write_big_block_depot
216
+ num_blocks = @big_blocks
217
+ num_lists = @list_blocks
218
+ total_blocks = num_lists * 128
219
+ used_blocks = num_blocks + num_lists + 2
220
+
221
+ marker = [-3].pack("V")
222
+ end_of_chain = [-2].pack("V")
223
+ unused = [-1].pack("V")
224
+
225
+ 1.upto(num_blocks-1){|n|
226
+ write([n].pack("V"))
227
+ }
228
+
229
+ write end_of_chain
230
+ write end_of_chain
231
+
232
+ 1.upto(num_lists){ write(marker) }
233
+
234
+ used_blocks.upto(total_blocks){ write(unused) }
235
+
236
+ end
237
+
238
+ ###############################################################################
239
+ #
240
+ # _write_property_storage()
241
+ #
242
+ # Write property storage. TODO: add summary sheets
243
+ #
244
+ def write_property_storage
245
+
246
+ ######### name type dir start size
247
+ write_pps('Root Entry', 0x05, 1, -2, 0x00)
248
+ write_pps('Workbook', 0x02, -1, 0x00, @book_size)
249
+ write_pps("", 0x00, -1, 0x00, 0x0000)
250
+ write_pps("", 0x00, -1, 0x00, 0x0000)
251
+ end
252
+
253
+ ###############################################################################
254
+ #
255
+ # _write_pps()
256
+ #
257
+ # Write property sheet in property storage
258
+ #
259
+ def write_pps(name, type, dir, start, size)
260
+ length = 0
261
+ ord_name = []
262
+ unless name.empty?
263
+ name = name + "\0"
264
+ ord_name = name.unpack("c*")
265
+ length = name.length * 2
266
+ end
267
+
268
+ rawname = ord_name.pack("v*")
269
+ zero = [0].pack("C")
270
+
271
+ pps_sizeofname = [length].pack("v") #0x40
272
+ pps_type = [type].pack("v") #0x42
273
+ pps_prev = [-1].pack("V") #0x44
274
+ pps_next = [-1].pack("V") #0x48
275
+ pps_dir = [dir].pack("V") #0x4c
276
+
277
+ unknown = [0].pack("V")
278
+
279
+ pps_ts1s = [0].pack("V") #0x64
280
+ pps_ts1d = [0].pack("V") #0x68
281
+ pps_ts2s = [0].pack("V") #0x6c
282
+ pps_ts2d = [0].pack("V") #0x70
283
+ pps_sb = [start].pack("V") #0x74
284
+ pps_size = [size].pack("V") #0x78
285
+
286
+ write(rawname)
287
+ for n in 1..64-length
288
+ write(zero)
289
+ end
290
+ write(pps_sizeofname)
291
+ write(pps_type)
292
+ write(pps_prev)
293
+ write(pps_next)
294
+ write(pps_dir)
295
+ for n in 1..5
296
+ write(unknown)
297
+ end
298
+ write(pps_ts1s)
299
+ write(pps_ts1d)
300
+ write(pps_ts2s)
301
+ write(pps_ts2d)
302
+ write(pps_sb)
303
+ write(pps_size)
304
+ write(unknown)
305
+ end
306
+
307
+ ###############################################################################
308
+ #
309
+ # _write_padding()
310
+ #
311
+ # Pad the end of the file
312
+ #
313
+ def write_padding
314
+ min_size = 512
315
+ min_size = BlockSize if @biff_size < BlockSize
316
+
317
+ if @biff_size % min_size != 0
318
+ padding = min_size - (@biff_size % min_size)
319
+ write("\0" * padding)
320
+ end
321
+ end
322
+ end