writeexcel 0.6.6 → 0.6.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (230) hide show
  1. data/.document +0 -0
  2. data/.gitattributes +0 -0
  3. data/README.rdoc +9 -35
  4. data/Rakefile +0 -0
  5. data/VERSION +1 -1
  6. data/charts/chartex.rb +0 -0
  7. data/charts/demo1.rb +0 -0
  8. data/charts/demo101.bin +0 -0
  9. data/charts/demo2.rb +0 -0
  10. data/charts/demo201.bin +0 -0
  11. data/charts/demo3.rb +0 -0
  12. data/charts/demo301.bin +0 -0
  13. data/charts/demo4.rb +0 -0
  14. data/charts/demo401.bin +0 -0
  15. data/charts/demo5.rb +0 -0
  16. data/charts/demo501.bin +0 -0
  17. data/examples/a_simple.rb +0 -0
  18. data/examples/autofilter.rb +0 -0
  19. data/examples/bigfile.rb +0 -0
  20. data/examples/chart_area.rb +0 -0
  21. data/examples/chart_bar.rb +0 -0
  22. data/examples/chart_column.rb +0 -0
  23. data/examples/chart_line.rb +0 -0
  24. data/examples/chart_pie.rb +0 -0
  25. data/examples/chart_scatter.rb +0 -0
  26. data/examples/chart_stock.rb +0 -0
  27. data/examples/chess.rb +0 -0
  28. data/examples/colors.rb +0 -0
  29. data/examples/comments1.rb +0 -0
  30. data/examples/comments2.rb +0 -0
  31. data/examples/copyformat.rb +0 -0
  32. data/examples/data_validate.rb +0 -0
  33. data/examples/date_time.rb +0 -0
  34. data/examples/defined_name.rb +0 -0
  35. data/examples/demo.rb +0 -0
  36. data/examples/diag_border.rb +0 -0
  37. data/examples/formats.rb +0 -0
  38. data/examples/formula_result.rb +0 -0
  39. data/examples/header.rb +0 -0
  40. data/examples/hide_sheet.rb +0 -0
  41. data/examples/hyperlink.rb +0 -0
  42. data/examples/images.rb +0 -0
  43. data/examples/indent.rb +0 -0
  44. data/examples/merge1.rb +0 -0
  45. data/examples/merge2.rb +0 -0
  46. data/examples/merge3.rb +0 -0
  47. data/examples/merge4.rb +0 -0
  48. data/examples/merge5.rb +0 -0
  49. data/examples/merge6.rb +0 -0
  50. data/examples/outline.rb +0 -0
  51. data/examples/outline_collapsed.rb +0 -0
  52. data/examples/panes.rb +0 -0
  53. data/examples/properties.rb +0 -0
  54. data/examples/properties_jp.rb +0 -0
  55. data/examples/protection.rb +0 -0
  56. data/examples/regions.rb +0 -0
  57. data/examples/repeat.rb +0 -0
  58. data/examples/republic.png +0 -0
  59. data/examples/right_to_left.rb +0 -0
  60. data/examples/row_wrap.rb +0 -0
  61. data/examples/set_first_sheet.rb +14 -0
  62. data/examples/stats.rb +0 -0
  63. data/examples/stocks.rb +0 -0
  64. data/examples/tab_colors.rb +0 -0
  65. data/examples/utf8.rb +0 -0
  66. data/examples/write_arrays.rb +0 -0
  67. data/html/en/doc_en.html +5941 -0
  68. data/html/images/a_simple.jpg +0 -0
  69. data/html/images/area1.jpg +0 -0
  70. data/html/images/bar1.jpg +0 -0
  71. data/html/images/chart_area.xls +0 -0
  72. data/html/images/column1.jpg +0 -0
  73. data/html/images/data_validation.jpg +0 -0
  74. data/html/images/line1.jpg +0 -0
  75. data/html/images/pie1.jpg +0 -0
  76. data/html/images/regions.jpg +0 -0
  77. data/html/images/scatter1.jpg +0 -0
  78. data/html/images/stats.jpg +0 -0
  79. data/html/images/stock1.jpg +0 -0
  80. data/html/images/stocks.jpg +0 -0
  81. data/html/index.html +16 -0
  82. data/html/style.css +433 -0
  83. data/lib/writeexcel/biffwriter.rb +5 -0
  84. data/lib/writeexcel/caller_info.rb +0 -0
  85. data/lib/writeexcel/chart.rb +8 -219
  86. data/lib/writeexcel/charts/area.rb +0 -0
  87. data/lib/writeexcel/charts/bar.rb +0 -0
  88. data/lib/writeexcel/charts/column.rb +0 -0
  89. data/lib/writeexcel/charts/external.rb +0 -0
  90. data/lib/writeexcel/charts/line.rb +0 -0
  91. data/lib/writeexcel/charts/pie.rb +0 -0
  92. data/lib/writeexcel/charts/scatter.rb +0 -0
  93. data/lib/writeexcel/charts/stock.rb +0 -0
  94. data/lib/writeexcel/colors.rb +4 -0
  95. data/lib/writeexcel/compatibility.rb +0 -0
  96. data/lib/writeexcel/debug_info.rb +0 -0
  97. data/lib/writeexcel/excelformula.y +0 -0
  98. data/lib/writeexcel/excelformulaparser.rb +0 -0
  99. data/lib/writeexcel/format.rb +2 -28
  100. data/lib/writeexcel/formula.rb +4 -70
  101. data/lib/writeexcel/helper.rb +0 -0
  102. data/lib/writeexcel/image.rb +158 -0
  103. data/lib/writeexcel/olewriter.rb +0 -0
  104. data/lib/writeexcel/properties.rb +0 -0
  105. data/lib/writeexcel/storage_lite.rb +0 -0
  106. data/lib/writeexcel/workbook.rb +434 -824
  107. data/lib/writeexcel/worksheet.rb +4194 -4718
  108. data/lib/writeexcel/write_file.rb +0 -0
  109. data/lib/writeexcel.rb +0 -0
  110. data/test/excelfile/Chart1.xls +0 -0
  111. data/test/excelfile/Chart2.xls +0 -0
  112. data/test/excelfile/Chart3.xls +0 -0
  113. data/test/excelfile/Chart4.xls +0 -0
  114. data/test/excelfile/Chart5.xls +0 -0
  115. data/test/helper.rb +0 -0
  116. data/test/perl_output/Chart1.xls.data +0 -0
  117. data/test/perl_output/Chart2.xls.data +0 -0
  118. data/test/perl_output/Chart3.xls.data +0 -0
  119. data/test/perl_output/Chart4.xls.data +0 -0
  120. data/test/perl_output/Chart5.xls.data +0 -0
  121. data/test/perl_output/README +0 -0
  122. data/test/perl_output/a_simple.xls +0 -0
  123. data/test/perl_output/autofilter.xls +0 -0
  124. data/test/perl_output/biff_add_continue_testdata +0 -0
  125. data/test/perl_output/chart_area.xls +0 -0
  126. data/test/perl_output/chart_bar.xls +0 -0
  127. data/test/perl_output/chart_column.xls +0 -0
  128. data/test/perl_output/chart_line.xls +0 -0
  129. data/test/perl_output/chess.xls +0 -0
  130. data/test/perl_output/colors.xls +0 -0
  131. data/test/perl_output/comments1.xls +0 -0
  132. data/test/perl_output/comments2.xls +0 -0
  133. data/test/perl_output/data_validate.xls +0 -0
  134. data/test/perl_output/date_time.xls +0 -0
  135. data/test/perl_output/defined_name.xls +0 -0
  136. data/test/perl_output/demo.xls +0 -0
  137. data/test/perl_output/demo101.bin +0 -0
  138. data/test/perl_output/demo201.bin +0 -0
  139. data/test/perl_output/demo301.bin +0 -0
  140. data/test/perl_output/demo401.bin +0 -0
  141. data/test/perl_output/demo501.bin +0 -0
  142. data/test/perl_output/diag_border.xls +0 -0
  143. data/test/perl_output/f_font_biff +0 -0
  144. data/test/perl_output/f_font_key +0 -0
  145. data/test/perl_output/f_xf_biff +0 -0
  146. data/test/perl_output/file_font_biff +0 -0
  147. data/test/perl_output/file_font_key +0 -0
  148. data/test/perl_output/file_xf_biff +0 -0
  149. data/test/perl_output/formula_result.xls +0 -0
  150. data/test/perl_output/headers.xls +0 -0
  151. data/test/perl_output/hidden.xls +0 -0
  152. data/test/perl_output/hide_zero.xls +0 -0
  153. data/test/perl_output/hyperlink.xls +0 -0
  154. data/test/perl_output/images.xls +0 -0
  155. data/test/perl_output/indent.xls +0 -0
  156. data/test/perl_output/merge1.xls +0 -0
  157. data/test/perl_output/merge2.xls +0 -0
  158. data/test/perl_output/merge3.xls +0 -0
  159. data/test/perl_output/merge4.xls +0 -0
  160. data/test/perl_output/merge5.xls +0 -0
  161. data/test/perl_output/merge6.xls +0 -0
  162. data/test/perl_output/ole_write_header +0 -0
  163. data/test/perl_output/outline.xls +0 -0
  164. data/test/perl_output/outline_collapsed.xls +0 -0
  165. data/test/perl_output/panes.xls +0 -0
  166. data/test/perl_output/protection.xls +0 -0
  167. data/test/perl_output/regions.xls +0 -0
  168. data/test/perl_output/right_to_left.xls +0 -0
  169. data/test/perl_output/set_first_sheet.xls +0 -0
  170. data/test/perl_output/stats.xls +0 -0
  171. data/test/perl_output/stocks.xls +0 -0
  172. data/test/perl_output/tab_colors.xls +0 -0
  173. data/test/perl_output/unicode_cyrillic.xls +0 -0
  174. data/test/perl_output/utf8.xls +0 -0
  175. data/test/perl_output/workbook1.xls +0 -0
  176. data/test/perl_output/workbook2.xls +0 -0
  177. data/test/perl_output/ws_colinfo +0 -0
  178. data/test/perl_output/ws_store_colinfo +0 -0
  179. data/test/perl_output/ws_store_dimensions +0 -0
  180. data/test/perl_output/ws_store_filtermode +0 -0
  181. data/test/perl_output/ws_store_filtermode_off +0 -0
  182. data/test/perl_output/ws_store_filtermode_on +0 -0
  183. data/test/perl_output/ws_store_selection +0 -0
  184. data/test/perl_output/ws_store_window2 +0 -0
  185. data/test/republic.png +0 -0
  186. data/test/test_00_IEEE_double.rb +0 -0
  187. data/test/test_01_add_worksheet.rb +0 -0
  188. data/test/test_02_merge_formats.rb +0 -0
  189. data/test/test_04_dimensions.rb +27 -27
  190. data/test/test_05_rows.rb +0 -0
  191. data/test/test_06_extsst.rb +1 -1
  192. data/test/test_11_date_time.rb +3 -3
  193. data/test/test_12_date_only.rb +7 -14
  194. data/test/test_13_date_seconds.rb +5 -5
  195. data/test/test_21_escher.rb +138 -138
  196. data/test/test_22_mso_drawing_group.rb +0 -0
  197. data/test/test_23_note.rb +4 -4
  198. data/test/test_24_txo.rb +3 -3
  199. data/test/test_25_position_object.rb +1 -1
  200. data/test/test_26_autofilter.rb +3 -3
  201. data/test/test_27_autofilter.rb +1 -1
  202. data/test/test_28_autofilter.rb +2 -2
  203. data/test/test_29_process_jpg.rb +16 -29
  204. data/test/test_30_validation_dval.rb +3 -3
  205. data/test/test_31_validation_dv_strings.rb +6 -6
  206. data/test/test_32_validation_dv_formula.rb +12 -12
  207. data/test/test_40_property_types.rb +0 -0
  208. data/test/test_41_properties.rb +0 -0
  209. data/test/test_42_set_properties.rb +0 -0
  210. data/test/test_50_name_stored.rb +8 -8
  211. data/test/test_51_name_print_area.rb +18 -18
  212. data/test/test_52_name_print_titles.rb +27 -27
  213. data/test/test_53_autofilter.rb +6 -6
  214. data/test/test_60_chart_generic.rb +1 -1
  215. data/test/test_61_chart_subclasses.rb +7 -14
  216. data/test/test_62_chart_formats.rb +0 -0
  217. data/test/test_63_chart_area_formats.rb +0 -0
  218. data/test/test_biff.rb +0 -0
  219. data/test/test_compatibility.rb +0 -0
  220. data/test/test_example_match.rb +31 -0
  221. data/test/test_format.rb +0 -0
  222. data/test/test_formula.rb +0 -0
  223. data/test/test_ole.rb +0 -0
  224. data/test/test_storage_lite.rb +0 -0
  225. data/test/test_workbook.rb +6 -0
  226. data/test/test_worksheet.rb +5 -5
  227. data/utils/add_magic_comment.rb +0 -0
  228. data/writeexcel.gemspec +263 -243
  229. data/writeexcel.rdoc +3 -3
  230. metadata +42 -39
@@ -11,7 +11,6 @@
11
11
  # original written in Perl by John McNamara
12
12
  # converted to Ruby by Hideo Nakamura, cxn03651@msj.biglobe.ne.jp
13
13
  #
14
- require 'digest/md5'
15
14
  require 'nkf'
16
15
  require 'writeexcel/biffwriter'
17
16
  require 'writeexcel/worksheet'
@@ -26,9 +25,11 @@ class Workbook < BIFFWriter
26
25
  require 'writeexcel/properties'
27
26
  require 'writeexcel/helper'
28
27
 
28
+ attr_reader :url_format, :parser, :tempdir, :date_1904
29
+ attr_reader :compatibility, :palette, :sinfo
30
+
29
31
  BOF = 12 # :nodoc:
30
32
  EOF = 4 # :nodoc:
31
- SheetName = "Sheet" # :nodoc:
32
33
 
33
34
  #
34
35
  # _file_ is a filename (as string) or io object where to out spreadsheet data.
@@ -42,7 +43,7 @@ class Workbook < BIFFWriter
42
43
  # worksheet = workbook.add_worksheet
43
44
  # worksheet.write(0, 0, 'Hi Excel!')
44
45
  #
45
- # Here are some other examples of using new() with filenames:
46
+ # Here are some other examples of using new():
46
47
  #
47
48
  # workbook1 = WriteExcel.new(filename)
48
49
  # workbook2 = WriteExcel.new('/tmp/filename.xls')
@@ -57,13 +58,17 @@ class Workbook < BIFFWriter
57
58
  # worksheets and store data.
58
59
  #
59
60
  # If the file cannot be created, due to file permissions or some other reason,
60
- # new will return undef. Therefore, it is good practice to check the return
61
- # value of new before proceeding.
61
+ # new will raise Exception Errno::EXXX.
62
+ #
63
+ # You can also pass a valid IO object to the new() constructor.:
64
+ # require 'stringio'
65
+ #
66
+ # io = StringIO.new
67
+ # workbook = WriteExcel.new(io) # After workbook.close, you can get excel data as io.string
62
68
  #
63
- # workbook = WriteExcel.new('protected.xls')
64
- # die "Problems creating new Excel file:" if workbook.nil?
69
+ # And, you can also pass default format properties.
65
70
  #
66
- # You can also pass a valid IO object to the new() constructor.
71
+ # workbook = WriteExcel.new(filename, :font => 'Courier New', :size => 11)
67
72
  #
68
73
  def initialize(file, default_formats = {})
69
74
  super()
@@ -74,13 +79,9 @@ class Workbook < BIFFWriter
74
79
  @date_1904 = false
75
80
  @selected = 0
76
81
  @xf_index = 0
77
- @fileclosed = false
78
82
  @biffsize = 0
79
- @sheet_name = "Sheet"
80
- @chart_name = "Chart"
81
83
  @sheet_count = 0
82
84
  @chart_count = 0
83
- @url_format = ''
84
85
  @codepage = 0x04E4
85
86
  @country = 1
86
87
  @worksheets = []
@@ -109,8 +110,7 @@ class Workbook < BIFFWriter
109
110
  @mso_clusters = []
110
111
  @mso_size = 0
111
112
 
112
- @hideobj = 0
113
- @compatibility = 0
113
+ @hideobj = false
114
114
 
115
115
  @summary = ''
116
116
  @doc_summary = ''
@@ -118,28 +118,7 @@ class Workbook < BIFFWriter
118
118
 
119
119
  @defined_names = []
120
120
 
121
- # Add the in-built style formats and the default cell format.
122
- add_format(:type => 1) # 0 Normal
123
- add_format(:type => 1) # 1 RowLevel 1
124
- add_format(:type => 1) # 2 RowLevel 2
125
- add_format(:type => 1) # 3 RowLevel 3
126
- add_format(:type => 1) # 4 RowLevel 4
127
- add_format(:type => 1) # 5 RowLevel 5
128
- add_format(:type => 1) # 6 RowLevel 6
129
- add_format(:type => 1) # 7 RowLevel 7
130
- add_format(:type => 1) # 8 ColLevel 1
131
- add_format(:type => 1) # 9 ColLevel 2
132
- add_format(:type => 1) # 10 ColLevel 3
133
- add_format(:type => 1) # 11 ColLevel 4
134
- add_format(:type => 1) # 12 ColLevel 5
135
- add_format(:type => 1) # 13 ColLevel 6
136
- add_format(:type => 1) # 14 ColLevel 7
137
- add_format(default_formats) # 15 Cell XF
138
- add_format(:type => 1, :num_format => 0x2B) # 16 Comma
139
- add_format(:type => 1, :num_format => 0x29) # 17 Comma[0]
140
- add_format(:type => 1, :num_format => 0x2C) # 18 Currency
141
- add_format(:type => 1, :num_format => 0x2A) # 19 Currency[0]
142
- add_format(:type => 1, :num_format => 0x09) # 20 Percent
121
+ setup_built_in_formats(default_formats)
143
122
 
144
123
  # Add the default format for hyperlinks
145
124
  @url_format = add_format(:color => 'blue', :underline => 1)
@@ -153,25 +132,8 @@ class Workbook < BIFFWriter
153
132
 
154
133
  # Set colour palette.
155
134
  set_palette_xl97
156
-
157
- get_checksum_method
158
135
  end
159
136
 
160
- ###############################################################################
161
- #
162
- # get_checksum_method.
163
- #
164
- # Check for modules available to calculate image checksum. Excel uses MD4 but
165
- # MD5 will also work.
166
- #
167
- # ------- cxn03651 add -------
168
- # md5 can use in ruby. so, @checksum_method is always 3.
169
-
170
- def get_checksum_method #:nodoc:
171
- @checksum_method = 3
172
- end
173
- private :get_checksum_method
174
-
175
137
  #
176
138
  # Calls finalization methods and explicitly close the OLEwriter files
177
139
  # handle.
@@ -184,7 +146,7 @@ class Workbook < BIFFWriter
184
146
  # a file you need to call close().
185
147
  #
186
148
  def close
187
- return if @fileclosed # Prevent close() from being called twice.
149
+ return if fileclosed? # Prevent close() from being called twice.
188
150
 
189
151
  @fileclosed = true
190
152
  store_workbook
@@ -234,7 +196,7 @@ class Workbook < BIFFWriter
234
196
  #
235
197
  # Add a new worksheet to the Excel workbook.
236
198
  #
237
- # if _sheetname_ is UTF-16BE format, pass 1 as _encoding_.
199
+ # if _sheetname_ is UTF-16BE format, pass true as _name_utf16be_.
238
200
  #
239
201
  # At least one worksheet should be added to a new workbook. A worksheet is
240
202
  # used to write data into cells:
@@ -259,30 +221,18 @@ class Workbook < BIFFWriter
259
221
  # UTF-16BE worksheet names using an additional optional parameter:
260
222
  #
261
223
  # name = [0x263a].pack('n')
262
- # worksheet = workbook.add_worksheet(name, 1) # Smiley
224
+ # worksheet = workbook.add_worksheet(name, true) # Smiley
263
225
  #
264
- def add_worksheet(sheetname = '', encoding = 0)
226
+ def add_worksheet(sheetname = '', name_utf16be = false)
265
227
  index = @worksheets.size
266
228
 
267
- name, encoding = check_sheetname(sheetname, encoding)
229
+ name, name_utf16be = check_sheetname(sheetname, name_utf16be)
268
230
 
269
- # Porters take note, the following scheme of passing references to Workbook
270
- # data (in the \$self->{_foo} cases) instead of a reference to the Workbook
271
- # itself is a workaround to avoid circular references between Workbook and
272
- # Worksheet objects. Feel free to implement this in any way the suits your
273
- # language.
274
- #
275
231
  init_data = [
232
+ self,
276
233
  name,
277
234
  index,
278
- encoding,
279
- @url_format,
280
- @parser,
281
- @tempdir,
282
- @date_1904,
283
- @compatibility,
284
- nil, # Palette. Not used yet. See add_chart().
285
- @sinfo,
235
+ name_utf16be
286
236
  ]
287
237
  worksheet = Writeexcel::Worksheet.new(*init_data)
288
238
  @worksheets[index] = worksheet # Store ref for iterator
@@ -303,10 +253,10 @@ class Workbook < BIFFWriter
303
253
  #
304
254
  # :type (required)
305
255
  # :name (optional)
306
- # :encoding (optional)
256
+ # :name_utf16be (optional)
307
257
  # :embedded (optional)
308
258
  #
309
- # * type
259
+ # * :type
310
260
  #
311
261
  # This is a required parameter. It defines the type of chart that will be created.
312
262
  #
@@ -327,7 +277,7 @@ class Workbook < BIFFWriter
327
277
  # Set the name for the chart sheet. The name property is optional and
328
278
  # if it isn't supplied will default to Chart1 .. n. The name must be
329
279
  # a valid Excel worksheet name. See add_worksheet() for more details
330
- # on valid sheet names. The name property can be omitted for embedded
280
+ # on valid sheet names. The :name property can be omitted for embedded
331
281
  # charts.
332
282
  #
333
283
  # chart = workbook.add_chart(
@@ -335,17 +285,22 @@ class Workbook < BIFFWriter
335
285
  # :name => 'Results Chart'
336
286
  # )
337
287
  #
288
+ # * :name_utf16be
289
+ #
290
+ # if :name is UTF-16BE format, pass true as :name_utf16be
291
+ #
338
292
  # * :encoding
339
293
  #
340
294
  # if :name is UTF-16BE format, pass 1 as :encoding.
295
+ # This key is obsolete in v0.7 or later. Use :name_utf16be instead.
341
296
  #
342
297
  # * :embedded
343
298
  #
344
- # Specifies that the Chart object will be inserted in a worksheet via
299
+ # Specifies true that the Chart object will be inserted in a worksheet via
345
300
  # the insert_chart() Worksheet method. It is an error to try insert a
346
301
  # Chart that doesn't have this flag set.
347
302
  #
348
- # chart = workbook.add_chart(:type => 'Chart::Line', :embedded => 1)
303
+ # chart = workbook.add_chart(:type => 'Chart::Line', :embedded => true)
349
304
  #
350
305
  # # Configure the chart.
351
306
  # ...
@@ -359,7 +314,7 @@ class Workbook < BIFFWriter
359
314
  #
360
315
  def add_chart(properties)
361
316
  name = ''
362
- encoding = 0
317
+ name_utf16be = false
363
318
  index = @worksheets.size
364
319
 
365
320
  # Type must be specified so we can create the required chart instance.
@@ -371,21 +326,16 @@ class Workbook < BIFFWriter
371
326
 
372
327
  # Check the worksheet name for non-embedded charts.
373
328
  unless embedded
374
- name, encoding =
375
- check_sheetname(properties[:name], properties[:encoding], true)
329
+ properties[:name_utf16be] = true if properties[:encoding] == 1
330
+ name, name_utf16be =
331
+ check_sheetname(properties[:name], properties[:name_utf16be], true)
376
332
  end
377
333
 
378
334
  init_data = [
335
+ self,
379
336
  name,
380
337
  index,
381
- encoding,
382
- @url_format,
383
- @parser,
384
- @tempdir,
385
- @date_1904 ? 1 : 0,
386
- @compatibility,
387
- @palette,
388
- @sinfo
338
+ name_utf16be
389
339
  ]
390
340
 
391
341
  chart = Writeexcel::Chart.factory(type, *init_data)
@@ -414,17 +364,17 @@ class Workbook < BIFFWriter
414
364
  # using add_chart(). Read external_charts.txt in the external_charts
415
365
  # directory of the distro for a full explanation.
416
366
  #
417
- def add_chart_ext(filename, name, encoding = 0)
367
+ def add_chart_ext(filename, chartname, name_utf16be = false)
418
368
  index = @worksheets.size
419
369
  type = 'extarnal'
420
370
 
421
- name, encoding = check_sheetname(name, encoding)
371
+ name, name_utf16be = check_sheetname(chartname, name_utf16be)
422
372
 
423
373
  init_data = [
424
374
  filename,
425
375
  name,
426
376
  index,
427
- encoding,
377
+ name_utf16be,
428
378
  @sinfo
429
379
  ]
430
380
 
@@ -433,130 +383,6 @@ class Workbook < BIFFWriter
433
383
  chart
434
384
  end
435
385
 
436
- ###############################################################################
437
- #
438
- # check_sheetname(name, encoding)
439
- #
440
- # Check for valid worksheet names. We check the length, if it contains any
441
- # invalid characters and if the name is unique in the workbook.
442
- #
443
- def check_sheetname(name, encoding = 0, chart = nil) #:nodoc:
444
- encoding ||= 0
445
-
446
- # Increment the Sheet/Chart number used for default sheet names below.
447
- if chart
448
- @chart_count += 1
449
- else
450
- @sheet_count += 1
451
- end
452
-
453
- # Supply default Sheet/Chart name if none has been defined.
454
- if name.nil? || name == ""
455
- encoding = 0
456
- if chart
457
- name = @chart_name + @chart_count.to_s
458
- else
459
- name = @sheet_name + @sheet_count.to_s
460
- end
461
- end
462
-
463
- ruby_19 { name = convert_to_ascii_if_ascii(name) }
464
- check_sheetname_length(name, encoding)
465
- check_sheetname_even(name) if encoding == 1
466
- check_sheetname_valid_chars(name, encoding)
467
-
468
- # Handle utf8 strings
469
- if is_utf8?(name)
470
- name = utf8_to_16be(name)
471
- encoding = 1
472
- end
473
-
474
- check_sheetname_uniq(name, encoding)
475
- [name, encoding]
476
- end
477
- private :check_sheetname
478
-
479
- def check_sheetname_length(name, encoding) #:nodoc:
480
- # Check that sheetname is <= 31 (1 or 2 byte chars). Excel limit.
481
- limit = encoding != 0 ? 62 : 31
482
- raise "Sheetname $name must be <= 31 chars" if name.bytesize > limit
483
- end
484
- private :check_sheetname_length
485
-
486
- def check_sheetname_even(name) #:nodoc:
487
- # Check that Unicode sheetname has an even number of bytes
488
- if (name.bytesize % 2 != 0)
489
- raise "Odd number of bytes in Unicode worksheet name: #{name}"
490
- end
491
- end
492
- private :check_sheetname_even
493
-
494
- def check_sheetname_valid_chars(name, encoding) #:nodoc:
495
- # Check that sheetname doesn't contain any invalid characters
496
- invalid_char = %r![\[\]:*?/\\]!
497
- if encoding != 1 && name =~ invalid_char
498
- # Check ASCII names
499
- raise "Invalid character []:*?/\\ in worksheet name: #{name}"
500
- else
501
- # Extract any 8bit clean chars from the UTF16 name and validate them.
502
- str = name.dup
503
- while str =~ /../m
504
- hi, lo = $~[0].unpack('aa')
505
- if hi == "\0" and lo =~ invalid_char
506
- raise 'Invalid character []:*?/\\ in worksheet name: ' + name
507
- end
508
- str = $~.post_match
509
- end
510
- end
511
- end
512
- private :check_sheetname_valid_chars
513
-
514
- # Check that the worksheet name doesn't already exist since this is a fatal
515
- # error in Excel 97. The check must also exclude case insensitive matches
516
- # since the names 'Sheet1' and 'sheet1' are equivalent. The tests also have
517
- # to take the encoding into account.
518
- #
519
- def check_sheetname_uniq(name, encoding) #:nodoc:
520
- @worksheets.each do |worksheet|
521
- name_a = name
522
- encd_a = encoding
523
- name_b = worksheet.name
524
- encd_b = worksheet.encoding
525
- error = false
526
-
527
- if encd_a == 0 and encd_b == 0
528
- error = (name_a.downcase == name_b.downcase)
529
- elsif encd_a == 0 and encd_b == 1
530
- name_a = ascii_to_16be(name_a)
531
- error = (name_a.downcase == name_b.downcase)
532
- elsif encd_a == 1 and encd_b == 0
533
- name_b = ascii_to_16be(name_b)
534
- error = (name_a.downcase == name_b.downcase)
535
- elsif encd_a == 1 and encd_b == 1
536
- # TODO : not converted yet.
537
-
538
- # We can't easily do a case insensitive test of the UTF16 names.
539
- # As a special case we check if all of the high bytes are nulls and
540
- # then do an ASCII style case insensitive test.
541
- #
542
- # Strip out the high bytes (funkily).
543
- # my $hi_a = grep {ord} $name_a =~ /(.)./sg;
544
- # my $hi_b = grep {ord} $name_b =~ /(.)./sg;
545
- #
546
- # if ($hi_a or $hi_b) {
547
- # $error = 1 if $name_a eq $name_b;
548
- # }
549
- # else {
550
- # $error = 1 if lc($name_a) eq lc($name_b);
551
- # }
552
- end
553
- if error
554
- raise "Worksheet name '#{name}', with case ignored, is already in use"
555
- end
556
- end
557
- end
558
- private :check_sheetname_uniq
559
-
560
386
  #
561
387
  # The add_format method can be used to create new Format objects which are
562
388
  # used to apply formatting to a cell. You can either define the properties
@@ -625,7 +451,7 @@ class Workbook < BIFFWriter
625
451
  # about to be written. This incurs a memory and speed penalty and may not be
626
452
  # suitable for very large files.
627
453
  #
628
- def compatibility_mode(mode = 1)
454
+ def compatibility_mode(mode = true)
629
455
  unless sheets.empty?
630
456
  raise "compatibility_mode() must be called before add_worksheet()"
631
457
  end
@@ -645,7 +471,7 @@ class Workbook < BIFFWriter
645
471
  # WriteExcel stores dates in the 1900 format by default. If you wish to
646
472
  # change this you can call the set_1904() workbook method. You can query
647
473
  # the current value by calling the get_1904() workbook method. This returns
648
- # 0 for 1900 and 1 for 1904.
474
+ # false for 1900 and true for 1904.
649
475
  #
650
476
  # See also "DATES AND TIME IN EXCEL" for more information about working
651
477
  # with Excel's date system.
@@ -656,7 +482,11 @@ class Workbook < BIFFWriter
656
482
  unless sheets.empty?
657
483
  raise "set_1904() must be called before add_worksheet()"
658
484
  end
659
- @date_1904 = mode
485
+ @date_1904 = (!mode || mode == 0) ? false : true
486
+ end
487
+
488
+ def get_1904
489
+ @date_1904
660
490
  end
661
491
 
662
492
  #
@@ -710,7 +540,7 @@ class Workbook < BIFFWriter
710
540
  # :border => 1
711
541
  # )
712
542
  #
713
- def set_custom_color(index = nil, red = nil, green = nil, blue = nil)
543
+ def set_custom_color(index, red = nil, green = nil, blue = nil)
714
544
  # Match a HTML #xxyyzz style parameter
715
545
  if !red.nil? && red =~ /^#(\w\w)(\w\w)(\w\w)/
716
546
  red = $1.hex
@@ -738,78 +568,9 @@ class Workbook < BIFFWriter
738
568
  index + 8
739
569
  end
740
570
 
741
- ###############################################################################
742
- #
743
- # set_palette_xl97()
744
- #
745
- # Sets the colour palette to the Excel 97+ default.
746
- #
747
- def set_palette_xl97 #:nodoc:
748
- @palette = [
749
- [0x00, 0x00, 0x00, 0x00], # 8
750
- [0xff, 0xff, 0xff, 0x00], # 9
751
- [0xff, 0x00, 0x00, 0x00], # 10
752
- [0x00, 0xff, 0x00, 0x00], # 11
753
- [0x00, 0x00, 0xff, 0x00], # 12
754
- [0xff, 0xff, 0x00, 0x00], # 13
755
- [0xff, 0x00, 0xff, 0x00], # 14
756
- [0x00, 0xff, 0xff, 0x00], # 15
757
- [0x80, 0x00, 0x00, 0x00], # 16
758
- [0x00, 0x80, 0x00, 0x00], # 17
759
- [0x00, 0x00, 0x80, 0x00], # 18
760
- [0x80, 0x80, 0x00, 0x00], # 19
761
- [0x80, 0x00, 0x80, 0x00], # 20
762
- [0x00, 0x80, 0x80, 0x00], # 21
763
- [0xc0, 0xc0, 0xc0, 0x00], # 22
764
- [0x80, 0x80, 0x80, 0x00], # 23
765
- [0x99, 0x99, 0xff, 0x00], # 24
766
- [0x99, 0x33, 0x66, 0x00], # 25
767
- [0xff, 0xff, 0xcc, 0x00], # 26
768
- [0xcc, 0xff, 0xff, 0x00], # 27
769
- [0x66, 0x00, 0x66, 0x00], # 28
770
- [0xff, 0x80, 0x80, 0x00], # 29
771
- [0x00, 0x66, 0xcc, 0x00], # 30
772
- [0xcc, 0xcc, 0xff, 0x00], # 31
773
- [0x00, 0x00, 0x80, 0x00], # 32
774
- [0xff, 0x00, 0xff, 0x00], # 33
775
- [0xff, 0xff, 0x00, 0x00], # 34
776
- [0x00, 0xff, 0xff, 0x00], # 35
777
- [0x80, 0x00, 0x80, 0x00], # 36
778
- [0x80, 0x00, 0x00, 0x00], # 37
779
- [0x00, 0x80, 0x80, 0x00], # 38
780
- [0x00, 0x00, 0xff, 0x00], # 39
781
- [0x00, 0xcc, 0xff, 0x00], # 40
782
- [0xcc, 0xff, 0xff, 0x00], # 41
783
- [0xcc, 0xff, 0xcc, 0x00], # 42
784
- [0xff, 0xff, 0x99, 0x00], # 43
785
- [0x99, 0xcc, 0xff, 0x00], # 44
786
- [0xff, 0x99, 0xcc, 0x00], # 45
787
- [0xcc, 0x99, 0xff, 0x00], # 46
788
- [0xff, 0xcc, 0x99, 0x00], # 47
789
- [0x33, 0x66, 0xff, 0x00], # 48
790
- [0x33, 0xcc, 0xcc, 0x00], # 49
791
- [0x99, 0xcc, 0x00, 0x00], # 50
792
- [0xff, 0xcc, 0x00, 0x00], # 51
793
- [0xff, 0x99, 0x00, 0x00], # 52
794
- [0xff, 0x66, 0x00, 0x00], # 53
795
- [0x66, 0x66, 0x99, 0x00], # 54
796
- [0x96, 0x96, 0x96, 0x00], # 55
797
- [0x00, 0x33, 0x66, 0x00], # 56
798
- [0x33, 0x99, 0x66, 0x00], # 57
799
- [0x00, 0x33, 0x00, 0x00], # 58
800
- [0x33, 0x33, 0x00, 0x00], # 59
801
- [0x99, 0x33, 0x00, 0x00], # 60
802
- [0x99, 0x33, 0x66, 0x00], # 61
803
- [0x33, 0x33, 0x99, 0x00], # 62
804
- [0x33, 0x33, 0x33, 0x00] # 63
805
- ]
806
- end
807
- private :set_palette_xl97
808
-
809
571
  #
810
572
  # Change the default temp directory
811
573
  #
812
- #
813
574
  # For speed and efficiency WriteExcel stores worksheet data in temporary
814
575
  # files prior to assembling the final workbook.
815
576
  #
@@ -964,14 +725,14 @@ class Workbook < BIFFWriter
964
725
  #
965
726
  # The properties that can be set are:
966
727
  #
967
- # * title
968
- # * subject
969
- # * author
970
- # * manager
971
- # * company
972
- # * category
973
- # * keywords
974
- # * comments
728
+ # * :title
729
+ # * :subject
730
+ # * :author
731
+ # * :manager
732
+ # * :company
733
+ # * :category
734
+ # * :keywords
735
+ # * :comments
975
736
  #
976
737
  # User defined properties are not supported due to effort required.
977
738
  #
@@ -990,7 +751,7 @@ class Workbook < BIFFWriter
990
751
  #
991
752
  # workbook.set_properties(
992
753
  # ...,
993
- # :comments => 'Created with Ruby and WriteExcel',
754
+ # :comments => 'Created with Ruby and writeexcel',
994
755
  # ...,
995
756
  # )
996
757
  #
@@ -1042,13 +803,261 @@ class Workbook < BIFFWriter
1042
803
  create_doc_summary_property_set(property_sets(properties, params))
1043
804
 
1044
805
  # Set a flag for when the files is written.
1045
- add_doc_properties = true
806
+ @add_doc_properties = true
807
+ end
808
+
809
+ def str_unique=(val) # :nodoc:
810
+ @sinfo[:str_unique] = val
811
+ end
812
+
813
+ def extsst_buckets # :nodoc:
814
+ @extsst_buckets
815
+ end
816
+
817
+ def extsst_bucket_size # :nodoc:
818
+ @extsst_bucket_size
819
+ end
820
+
821
+ def biff_only=(val) # :nodoc:
822
+ @biff_only = val
823
+ end
824
+
825
+ def summary # :nodoc:
826
+ @summary
827
+ end
828
+
829
+ def localtime=(val) # :nodoc:
830
+ @localtime = val
831
+ end
832
+
833
+ #==========================================
834
+ # Internal method
835
+ #==========================================
836
+
837
+ private
838
+
839
+ # Add the in-built style formats and the default cell format.
840
+ def setup_built_in_formats(default_formats) # :nodoc:
841
+ add_format(:type => 1) # 0 Normal
842
+ add_format(:type => 1) # 1 RowLevel 1
843
+ add_format(:type => 1) # 2 RowLevel 2
844
+ add_format(:type => 1) # 3 RowLevel 3
845
+ add_format(:type => 1) # 4 RowLevel 4
846
+ add_format(:type => 1) # 5 RowLevel 5
847
+ add_format(:type => 1) # 6 RowLevel 6
848
+ add_format(:type => 1) # 7 RowLevel 7
849
+ add_format(:type => 1) # 8 ColLevel 1
850
+ add_format(:type => 1) # 9 ColLevel 2
851
+ add_format(:type => 1) # 10 ColLevel 3
852
+ add_format(:type => 1) # 11 ColLevel 4
853
+ add_format(:type => 1) # 12 ColLevel 5
854
+ add_format(:type => 1) # 13 ColLevel 6
855
+ add_format(:type => 1) # 14 ColLevel 7
856
+ add_format(default_formats) # 15 Cell XF
857
+ add_format(:type => 1, :num_format => 0x2B) # 16 Comma
858
+ add_format(:type => 1, :num_format => 0x29) # 17 Comma[0]
859
+ add_format(:type => 1, :num_format => 0x2C) # 18 Currency
860
+ add_format(:type => 1, :num_format => 0x2A) # 19 Currency[0]
861
+ add_format(:type => 1, :num_format => 0x09) # 20 Percent
862
+ end
863
+
864
+ def fileclosed?
865
+ @fileclosed || false
866
+ end
867
+
868
+ #
869
+ # Check for valid worksheet names. We check the length, if it contains any
870
+ # invalid characters and if the name is unique in the workbook.
871
+ #
872
+ def check_sheetname(name, name_utf16be = false, chart = nil) #:nodoc:
873
+ # name_utf16be parameter may set 0/1 in v0.6.6 or earlier
874
+ name_utf16be = false if name_utf16be == 0
875
+ name_utf16be = true if name_utf16be == 1
876
+
877
+ increment_sheet_chart_count(chart)
878
+ if name.nil? || name == ""
879
+ name_utf16be = false
880
+ name = default_sheet_chart_name(chart)
881
+ end
882
+
883
+ ruby_19 { name = convert_to_ascii_if_ascii(name) }
884
+ check_sheetname_length(name, name_utf16be)
885
+ check_sheetname_even(name) if name_utf16be
886
+ check_sheetname_valid_chars(name, name_utf16be)
887
+
888
+ # Handle utf8 strings
889
+ if is_utf8?(name)
890
+ name = utf8_to_16be(name)
891
+ name_utf16be = true
892
+ end
893
+
894
+ check_sheetname_uniq(name, name_utf16be)
895
+ [name, name_utf16be]
896
+ end
897
+
898
+ # Increment the Sheet/Chart number used for default sheet names below.
899
+ def increment_sheet_chart_count(chart)
900
+ if chart
901
+ @chart_count += 1
902
+ else
903
+ @sheet_count += 1
904
+ end
905
+ end
906
+
907
+ # Supply default Sheet/Chart name if none has been defined.
908
+ def default_sheet_chart_name(chart)
909
+ if chart
910
+ "Chart#{@chart_count}"
911
+ else
912
+ "Sheet#{@sheet_count}"
913
+ end
914
+ end
915
+
916
+ def check_sheetname_length(name, name_utf16be) #:nodoc:
917
+ # Check that sheetname is <= 31 (1 or 2 byte chars). Excel limit.
918
+ limit = name_utf16be ? 62 : 31
919
+ raise "Sheetname $name must be <= 31 chars" if name.bytesize > limit
920
+ end
921
+
922
+ def check_sheetname_even(name) #:nodoc:
923
+ # Check that Unicode sheetname has an even number of bytes
924
+ if (name.bytesize % 2 != 0)
925
+ raise "Odd number of bytes in Unicode worksheet name: #{name}"
926
+ end
927
+ end
928
+
929
+ def check_sheetname_valid_chars(name, name_utf16be) #:nodoc:
930
+ # Check that sheetname doesn't contain any invalid characters
931
+ invalid_char = %r![\[\]:*?/\\]!
932
+ if !name_utf16be && name =~ invalid_char
933
+ # Check ASCII names
934
+ raise "Invalid character []:*?/\\ in worksheet name: #{name}"
935
+ else
936
+ # Extract any 8bit clean chars from the UTF16 name and validate them.
937
+ str = name.dup
938
+ while str =~ /../m
939
+ hi, lo = $~[0].unpack('aa')
940
+ if hi == "\0" and lo =~ invalid_char
941
+ raise 'Invalid character []:*?/\\ in worksheet name: ' + name
942
+ end
943
+ str = $~.post_match
944
+ end
945
+ end
946
+ end
947
+
948
+ # Check that the worksheet name doesn't already exist since this is a fatal
949
+ # error in Excel 97. The check must also exclude case insensitive matches
950
+ # since the names 'Sheet1' and 'sheet1' are equivalent. The tests also have
951
+ # to take the name_utf16be into account.
952
+ #
953
+ def check_sheetname_uniq(name, name_utf16be) #:nodoc:
954
+ @worksheets.each do |worksheet|
955
+ name_a = name
956
+ encd_a = name_utf16be
957
+ name_b = worksheet.name
958
+ encd_b = worksheet.is_name_utf16be?
959
+ error = false
960
+
961
+ if !encd_a and !encd_b
962
+ error = (name_a.downcase == name_b.downcase)
963
+ elsif !encd_a and encd_b
964
+ name_a = ascii_to_16be(name_a)
965
+ error = (name_a.downcase == name_b.downcase)
966
+ elsif encd_a and !encd_b
967
+ name_b = ascii_to_16be(name_b)
968
+ error = (name_a.downcase == name_b.downcase)
969
+ elsif encd_a and encd_b
970
+ error = (name_a.downcase == name_b.downcase)
971
+ # TODO : not converted yet.
972
+
973
+ # We can't easily do a case insensitive test of the UTF16 names.
974
+ # As a special case we check if all of the high bytes are nulls and
975
+ # then do an ASCII style case insensitive test.
976
+ #
977
+ # Strip out the high bytes (funkily).
978
+ # my $hi_a = grep {ord} $name_a =~ /(.)./sg;
979
+ # my $hi_b = grep {ord} $name_b =~ /(.)./sg;
980
+ #
981
+ # if ($hi_a or $hi_b) {
982
+ # $error = 1 if $name_a eq $name_b;
983
+ # }
984
+ # else {
985
+ # $error = 1 if lc($name_a) eq lc($name_b);
986
+ # }
987
+ end
988
+ if error
989
+ raise "Worksheet name '#{name}', with case ignored, is already in use"
990
+ end
991
+ end
992
+ end
993
+
994
+ #
995
+ # Sets the colour palette to the Excel 97+ default.
996
+ #
997
+ def set_palette_xl97 #:nodoc:
998
+ @palette = [
999
+ [0x00, 0x00, 0x00, 0x00], # 8
1000
+ [0xff, 0xff, 0xff, 0x00], # 9
1001
+ [0xff, 0x00, 0x00, 0x00], # 10
1002
+ [0x00, 0xff, 0x00, 0x00], # 11
1003
+ [0x00, 0x00, 0xff, 0x00], # 12
1004
+ [0xff, 0xff, 0x00, 0x00], # 13
1005
+ [0xff, 0x00, 0xff, 0x00], # 14
1006
+ [0x00, 0xff, 0xff, 0x00], # 15
1007
+ [0x80, 0x00, 0x00, 0x00], # 16
1008
+ [0x00, 0x80, 0x00, 0x00], # 17
1009
+ [0x00, 0x00, 0x80, 0x00], # 18
1010
+ [0x80, 0x80, 0x00, 0x00], # 19
1011
+ [0x80, 0x00, 0x80, 0x00], # 20
1012
+ [0x00, 0x80, 0x80, 0x00], # 21
1013
+ [0xc0, 0xc0, 0xc0, 0x00], # 22
1014
+ [0x80, 0x80, 0x80, 0x00], # 23
1015
+ [0x99, 0x99, 0xff, 0x00], # 24
1016
+ [0x99, 0x33, 0x66, 0x00], # 25
1017
+ [0xff, 0xff, 0xcc, 0x00], # 26
1018
+ [0xcc, 0xff, 0xff, 0x00], # 27
1019
+ [0x66, 0x00, 0x66, 0x00], # 28
1020
+ [0xff, 0x80, 0x80, 0x00], # 29
1021
+ [0x00, 0x66, 0xcc, 0x00], # 30
1022
+ [0xcc, 0xcc, 0xff, 0x00], # 31
1023
+ [0x00, 0x00, 0x80, 0x00], # 32
1024
+ [0xff, 0x00, 0xff, 0x00], # 33
1025
+ [0xff, 0xff, 0x00, 0x00], # 34
1026
+ [0x00, 0xff, 0xff, 0x00], # 35
1027
+ [0x80, 0x00, 0x80, 0x00], # 36
1028
+ [0x80, 0x00, 0x00, 0x00], # 37
1029
+ [0x00, 0x80, 0x80, 0x00], # 38
1030
+ [0x00, 0x00, 0xff, 0x00], # 39
1031
+ [0x00, 0xcc, 0xff, 0x00], # 40
1032
+ [0xcc, 0xff, 0xff, 0x00], # 41
1033
+ [0xcc, 0xff, 0xcc, 0x00], # 42
1034
+ [0xff, 0xff, 0x99, 0x00], # 43
1035
+ [0x99, 0xcc, 0xff, 0x00], # 44
1036
+ [0xff, 0x99, 0xcc, 0x00], # 45
1037
+ [0xcc, 0x99, 0xff, 0x00], # 46
1038
+ [0xff, 0xcc, 0x99, 0x00], # 47
1039
+ [0x33, 0x66, 0xff, 0x00], # 48
1040
+ [0x33, 0xcc, 0xcc, 0x00], # 49
1041
+ [0x99, 0xcc, 0x00, 0x00], # 50
1042
+ [0xff, 0xcc, 0x00, 0x00], # 51
1043
+ [0xff, 0x99, 0x00, 0x00], # 52
1044
+ [0xff, 0x66, 0x00, 0x00], # 53
1045
+ [0x66, 0x66, 0x99, 0x00], # 54
1046
+ [0x96, 0x96, 0x96, 0x00], # 55
1047
+ [0x00, 0x33, 0x66, 0x00], # 56
1048
+ [0x33, 0x99, 0x66, 0x00], # 57
1049
+ [0x00, 0x33, 0x00, 0x00], # 58
1050
+ [0x33, 0x33, 0x00, 0x00], # 59
1051
+ [0x99, 0x33, 0x00, 0x00], # 60
1052
+ [0x99, 0x33, 0x66, 0x00], # 61
1053
+ [0x33, 0x33, 0x99, 0x00], # 62
1054
+ [0x33, 0x33, 0x33, 0x00] # 63
1055
+ ]
1046
1056
  end
1047
1057
 
1048
1058
  def property_set(property, params) #:nodoc:
1049
1059
  valid_properties[property][0..1] + [params[property]]
1050
1060
  end
1051
- private :property_set
1052
1061
 
1053
1062
  def property_sets(properties, params) #:nodoc:
1054
1063
  properties.select { |property| params[property.to_sym] }.
@@ -1056,7 +1065,6 @@ class Workbook < BIFFWriter
1056
1065
  property_set(property.to_sym, params)
1057
1066
  end
1058
1067
  end
1059
- private :property_sets
1060
1068
 
1061
1069
  # List of valid input parameters.
1062
1070
  def valid_properties #:nodoc:
@@ -1075,7 +1083,6 @@ class Workbook < BIFFWriter
1075
1083
  :utf8 => 1
1076
1084
  }
1077
1085
  end
1078
- private :valid_properties
1079
1086
 
1080
1087
  def check_valid_params_for_properties(params) #:nodoc:
1081
1088
  params.each_key do |k|
@@ -1084,11 +1091,7 @@ class Workbook < BIFFWriter
1084
1091
  end
1085
1092
  end
1086
1093
  end
1087
- private :check_valid_params_for_properties
1088
1094
 
1089
- ###############################################################################
1090
- #
1091
- # get_property_set_codepage()
1092
1095
  #
1093
1096
  # Get the character codepage used by the strings in a property set. If one of
1094
1097
  # the strings used is utf8 then the codepage is marked as utf8. Otherwise
@@ -1103,11 +1106,7 @@ class Workbook < BIFFWriter
1103
1106
  end
1104
1107
  return 0x04E4 # Default codepage, Latin 1.
1105
1108
  end
1106
- private :get_property_set_codepage
1107
1109
 
1108
- ###############################################################################
1109
- #
1110
- # store_workbook()
1111
1110
  #
1112
1111
  # Assemble worksheets into a workbook and send the BIFF data to an OLE
1113
1112
  # storage.
@@ -1124,7 +1123,7 @@ class Workbook < BIFFWriter
1124
1123
 
1125
1124
  # Calculate the number of selected sheet tabs and set the active sheet.
1126
1125
  @worksheets.each do |sheet|
1127
- @selected += 1 if sheet.selected != 0
1126
+ @selected += 1 if sheet.selected?
1128
1127
  sheet.active = 1 if sheet.index == @sinfo[:activesheet]
1129
1128
  end
1130
1129
 
@@ -1145,13 +1144,7 @@ class Workbook < BIFFWriter
1145
1144
 
1146
1145
  # Add BOUNDSHEET records.
1147
1146
  @worksheets.each do |sheet|
1148
- store_boundsheet(
1149
- sheet.name,
1150
- sheet.offset,
1151
- sheet.sheet_type,
1152
- sheet.hidden,
1153
- sheet.encoding
1154
- )
1147
+ store_boundsheet(sheet)
1155
1148
  end
1156
1149
 
1157
1150
  # NOTE: If any records are added between here and EOF the
@@ -1170,117 +1163,93 @@ class Workbook < BIFFWriter
1170
1163
  store_eof
1171
1164
 
1172
1165
  # Store the workbook in an OLE container
1173
- store_ole_filie
1174
- end
1175
- private :store_workbook
1176
-
1177
- def str_unique=(val) # :nodoc:
1178
- @sinfo[:str_unique] = val
1179
- end
1180
-
1181
- def extsst_buckets # :nodoc:
1182
- @extsst_buckets
1183
- end
1184
-
1185
- def extsst_bucket_size # :nodoc:
1186
- @extsst_bucket_size
1187
- end
1188
-
1189
- def biff_only=(val) # :nodoc:
1190
- @biff_only = val
1191
- end
1192
-
1193
- def summary # :nodoc:
1194
- @summary
1195
- end
1196
-
1197
- def localtime=(val) # :nodoc:
1198
- @localtime = val
1166
+ store_ole_file
1199
1167
  end
1200
1168
 
1201
- ###############################################################################
1202
- #
1203
- # store_ole_filie()
1204
1169
  #
1205
1170
  # Store the workbook in an OLE container using the default handler or using
1206
1171
  # OLE::Storage_Lite if the workbook data is > ~ 7MB.
1207
1172
  #
1208
- def store_ole_filie #:nodoc:
1173
+ def store_ole_file #:nodoc:
1209
1174
  maxsize = 7_087_104
1210
1175
  # maxsize = 1
1211
1176
 
1212
1177
  if !add_doc_properties && @biffsize <= maxsize
1213
- # Write the OLE file using OLEwriter if data <= 7MB
1214
- ole = OLEWriter.new(@fh_out)
1178
+ store_through_ole_writer
1179
+ else
1180
+ store_through_ole_storage_lite
1181
+ end
1182
+ end
1215
1183
 
1216
- # Write the BIFF data without the OLE container for testing.
1217
- ole.biff_only = @biff_only
1184
+ def store_through_ole_writer
1185
+ # Write the OLE file using OLEwriter if data <= 7MB
1186
+ ole = OLEWriter.new(@fh_out)
1218
1187
 
1219
- # Indicate that we created the filehandle and want to close it.
1220
- ole.internal_fh = @internal_fh
1188
+ # Write the BIFF data without the OLE container for testing.
1189
+ ole.biff_only = @biff_only
1221
1190
 
1222
- ole.set_size(@biffsize)
1223
- ole.write_header
1191
+ # Indicate that we created the filehandle and want to close it.
1192
+ ole.internal_fh = @internal_fh
1224
1193
 
1225
- while tmp = get_data
1194
+ ole.set_size(@biffsize)
1195
+ ole.write_header
1196
+
1197
+ while tmp = get_data
1198
+ ole.write(tmp)
1199
+ end
1200
+
1201
+ @worksheets.each do |worksheet|
1202
+ while tmp = worksheet.get_data
1226
1203
  ole.write(tmp)
1227
1204
  end
1205
+ end
1228
1206
 
1229
- @worksheets.each do |worksheet|
1230
- while tmp = worksheet.get_data
1231
- ole.write(tmp)
1232
- end
1233
- end
1207
+ return ole.close
1208
+ end
1234
1209
 
1235
- return ole.close
1236
- else
1237
- # Create the Workbook stream.
1238
- stream = 'Workbook'.unpack('C*').pack('v*')
1239
- workbook = OLEStorageLitePPSFile.new(stream)
1240
- workbook.set_file # use tempfile
1210
+ def store_through_ole_storage_lite
1211
+ # Create the Workbook stream.
1212
+ stream = 'Workbook'.unpack('C*').pack('v*')
1213
+ workbook = OLEStorageLitePPSFile.new(stream)
1214
+ workbook.set_file # use tempfile
1241
1215
 
1242
- while tmp = get_data
1243
- workbook.append(tmp)
1244
- end
1216
+ while tmp = get_data
1217
+ workbook.append(tmp)
1218
+ end
1245
1219
 
1246
- @worksheets.each do |worksheet|
1247
- while tmp = worksheet.get_data
1248
- workbook.append(tmp)
1249
- end
1220
+ @worksheets.each do |worksheet|
1221
+ while tmp = worksheet.get_data
1222
+ workbook.append(tmp)
1250
1223
  end
1224
+ end
1251
1225
 
1252
- streams = []
1253
- streams << workbook
1254
-
1255
- # Create the properties streams, if any.
1256
- if add_doc_properties
1257
- stream = "\5SummaryInformation".unpack('C*').pack('v*')
1258
- summary = OLEStorageLitePPSFile.new(stream, @summary)
1259
- streams << summary
1260
- stream = "\5DocumentSummaryInformation".unpack('C*').pack('v*')
1261
- summary = OLEStorageLitePPSFile.new(stream, @doc_summary)
1262
- streams << summary
1263
- end
1264
- # Create the OLE root document and add the substreams.
1265
- localtime = @localtime.to_a[0..5]
1266
- localtime[4] -= 1 # month
1267
- localtime[5] -= 1900
1268
- ole_root = OLEStorageLitePPSRoot.new(
1269
- localtime,
1270
- localtime,
1271
- streams
1272
- )
1273
- ole_root.save(@file)
1226
+ streams = []
1227
+ streams << workbook
1274
1228
 
1275
- # Close the filehandle if it was created internally.
1276
- return @fh_out.close if @internal_fh != 0
1229
+ # Create the properties streams, if any.
1230
+ if add_doc_properties
1231
+ stream = "\5SummaryInformation".unpack('C*').pack('v*')
1232
+ summary = OLEStorageLitePPSFile.new(stream, @summary)
1233
+ streams << summary
1234
+ stream = "\5DocumentSummaryInformation".unpack('C*').pack('v*')
1235
+ summary = OLEStorageLitePPSFile.new(stream, @doc_summary)
1236
+ streams << summary
1277
1237
  end
1238
+ # Create the OLE root document and add the substreams.
1239
+ localtime = @localtime.to_a[0..5]
1240
+ localtime[4] -= 1 # month
1241
+ localtime[5] -= 1900
1242
+ ole_root = OLEStorageLitePPSRoot.new(
1243
+ localtime,
1244
+ localtime,
1245
+ streams
1246
+ )
1247
+ ole_root.save(@file)
1248
+
1249
+ # Close the filehandle if it was created internally.
1250
+ return @fh_out.close if @internal_fh != 0
1278
1251
  end
1279
- private :store_ole_filie
1280
1252
 
1281
- ###############################################################################
1282
- #
1283
- # calc_sheet_offsets()
1284
1253
  #
1285
1254
  # Calculate Worksheet BOF offsets records for use in the BOUNDSHEET records.
1286
1255
  #
@@ -1318,11 +1287,7 @@ class Workbook < BIFFWriter
1318
1287
 
1319
1288
  @biffsize = offset
1320
1289
  end
1321
- private :calc_sheet_offsets
1322
1290
 
1323
- ###############################################################################
1324
- #
1325
- # calc_mso_sizes()
1326
1291
  #
1327
1292
  # Calculate the MSODRAWINGGROUP sizes and the indexes of the Worksheet
1328
1293
  # MSODRAWING records.
@@ -1348,10 +1313,9 @@ class Workbook < BIFFWriter
1348
1313
  # required by each worksheet.
1349
1314
  #
1350
1315
  @worksheets.each do |sheet|
1351
- next unless sheet.sheet_type == 0x0000
1316
+ next unless sheet.type == 0x0000
1352
1317
 
1353
1318
  num_images = sheet.num_images
1354
- image_mso_size = sheet.image_mso_size
1355
1319
  num_comments = sheet.prepare_comments
1356
1320
  num_charts = sheet.prepare_charts
1357
1321
  num_filters = sheet.filter_count
@@ -1362,7 +1326,7 @@ class Workbook < BIFFWriter
1362
1326
  num_shapes = 1 + num_images + num_comments +
1363
1327
  num_charts + num_filters
1364
1328
  shapes_saved += num_shapes
1365
- mso_size += image_mso_size
1329
+ mso_size += sheet.image_mso_size
1366
1330
 
1367
1331
  # Add a drawing object for each sheet with comments.
1368
1332
  drawings_saved += 1
@@ -1399,11 +1363,7 @@ class Workbook < BIFFWriter
1399
1363
  drawings_saved, clusters
1400
1364
  ]
1401
1365
  end
1402
- private :calc_mso_sizes
1403
1366
 
1404
- ###############################################################################
1405
- #
1406
- # process_images()
1407
1367
  #
1408
1368
  # We need to process each image in each worksheet and extract information.
1409
1369
  # Some of this information is stored and used in the Workbook and some is
@@ -1423,251 +1383,58 @@ class Workbook < BIFFWriter
1423
1383
  images_size = 0
1424
1384
 
1425
1385
  @worksheets.each do |sheet|
1426
- next unless sheet.sheet_type == 0x0000
1386
+ next unless sheet.type == 0x0000
1427
1387
  next if sheet.prepare_images == 0
1428
1388
 
1429
1389
  num_images = 0
1430
1390
  image_mso_size = 0
1431
1391
 
1432
1392
  sheet.images_array.each do |image|
1433
- filename = image[2]
1434
1393
  num_images += 1
1435
-
1436
- #
1437
- # For each Worksheet image we get a structure like this
1438
- # [
1439
- # $row,
1440
- # $col,
1441
- # $name,
1442
- # $x_offset,
1443
- # $y_offset,
1444
- # $scale_x,
1445
- # $scale_y,
1446
- # ]
1447
- #
1448
- # And we add additional information:
1449
- #
1450
- # $image_id,
1451
- # $type,
1452
- # $width,
1453
- # $height;
1454
-
1455
- if images_seen[filename].nil?
1394
+ unless images_seen[image.filename]
1456
1395
  # TODO should also match seen images based on checksum.
1457
-
1458
- # Open the image file and import the data.
1459
- fh = open(filename, "rb")
1460
- raise "Couldn't import #{filename}: #{$!}" unless fh
1461
-
1462
- # Slurp the file into a string and do some size calcs.
1463
- # my $data = do {local $/; <$fh>};
1464
- data = fh.read
1465
- size = data.bytesize
1466
- checksum1 = image_checksum(data, image_id)
1467
- checksum2 = checksum1
1468
- ref_count = 1
1469
-
1470
- # Process the image and extract dimensions.
1471
- # Test for PNGs...
1472
- if data.unpack('x A3')[0] == 'PNG'
1473
- type, width, height = process_png(data)
1474
- # Test for JFIF and Exif JPEGs...
1475
- elsif ( data.unpack('n')[0] == 0xFFD8 &&
1476
- (data.unpack('x6 A4')[0] == 'JFIF' ||
1477
- data.unpack('x6 A4')[0] == 'Exif')
1478
- )
1479
- type, width, height = process_jpg(data, filename)
1480
- # Test for BMPs...
1481
- elsif data.unpack('A2')[0] == 'BM'
1482
- type, width, height = process_bmp(data, filename)
1483
- # The 14 byte header of the BMP is stripped off.
1484
- data[0, 13] = ''
1485
-
1486
- # A checksum of the new image data is also required.
1487
- checksum2 = image_checksum(data, image_id, image_id)
1488
-
1489
- # Adjust size -14 (header) + 16 (extra checksum).
1490
- size += 2
1491
- else
1492
- raise "Unsupported image format for file: #{filename}\n"
1493
- end
1494
-
1495
- # Push the new data back into the Worksheet array;
1496
- image.push(image_id, type, width, height)
1396
+ image.id = image_id
1397
+ image.ref_count = 1
1398
+ image.import
1497
1399
 
1498
1400
  # Also store new data for use in duplicate images.
1499
- previous_images.push([image_id, type, width, height])
1401
+ previous_images.push(image)
1500
1402
 
1501
1403
  # Store information required by the Workbook.
1502
- image_data.push([ref_count, type, data, size,
1503
- checksum1, checksum2])
1404
+ image_data.push(image)
1504
1405
 
1505
1406
  # Keep track of overall data size.
1506
- images_size += size +61 # Size for bstore container.
1507
- image_mso_size += size +69 # Size for dgg container.
1407
+ images_size += image.size + 61 # Size for bstore container.
1408
+ image_mso_size += image.size + 69 # Size for dgg container.
1508
1409
 
1509
- images_seen[filename] = image_id
1410
+ images_seen[image.filename] = image_id
1510
1411
  image_id += 1
1511
- fh.close
1512
1412
  else
1513
1413
  # We've processed this file already.
1514
- index = images_seen[filename] -1
1414
+ index = images_seen[image.filename] -1
1515
1415
 
1516
1416
  # Increase image reference count.
1517
- image_data[index][0] += 1
1417
+ image_data[index].ref_count += 1
1518
1418
 
1519
1419
  # Add previously calculated data back onto the Worksheet array.
1520
- # $image_id, $type, $width, $height
1521
- a_ref = sheet.images_array[index]
1522
- image.concat(previous_images[index])
1420
+ # image_id, type, width, height
1421
+ image.id = previous_images[index].id
1422
+ image.type = previous_images[index].type
1423
+ image.width = previous_images[index].width
1424
+ image.height = previous_images[index].height
1523
1425
  end
1524
1426
  end
1525
1427
 
1526
1428
  # Store information required by the Worksheet.
1527
1429
  sheet.num_images = num_images
1528
1430
  sheet.image_mso_size = image_mso_size
1529
-
1530
1431
  end
1531
1432
 
1532
-
1533
1433
  # Store information required by the Workbook.
1534
1434
  @images_size = images_size
1535
1435
  @images_data = image_data # Store the data for MSODRAWINGGROUP.
1536
1436
  end
1537
- private :process_images
1538
-
1539
- ###############################################################################
1540
- #
1541
- # image_checksum()
1542
- #
1543
- # Generate a checksum for the image using whichever module is available..The
1544
- # available modules are checked in get_checksum_method(). Excel uses an MD4
1545
- # checksum but any other will do. In the event of no checksum module being
1546
- # available we simulate a checksum using the image index.
1547
- #
1548
- def image_checksum(data, index1, index2 = 0) #:nodoc:
1549
- if @checksum_method == 1
1550
- # Digest::MD4
1551
- # return Digest::MD4::md4_hex($data);
1552
- elsif @checksum_method == 2
1553
- # Digest::Perl::MD4
1554
- # return Digest::Perl::MD4::md4_hex($data);
1555
- elsif @checksum_method == 3
1556
- # Digest::MD5
1557
- return Digest::MD5.hexdigest(data)
1558
- else
1559
- # Default
1560
- return sprintf('%016X%016X', index2, index1)
1561
- end
1562
- end
1563
- private :image_checksum
1564
-
1565
- ###############################################################################
1566
- #
1567
- # process_png()
1568
- #
1569
- # Extract width and height information from a PNG file.
1570
- #
1571
- def process_png(data) #:nodoc:
1572
- type = 6 # Excel Blip type (MSOBLIPTYPE).
1573
- width = data[16, 4].unpack("N")[0]
1574
- height = data[20, 4].unpack("N")[0]
1575
-
1576
- [type, width, height]
1577
- end
1578
- private :process_png
1579
-
1580
- ###############################################################################
1581
- #
1582
- # process_bmp()
1583
- #
1584
- # Extract width and height information from a BMP file.
1585
- #
1586
- # Most of these checks came from the old Worksheet::_process_bitmap() method.
1587
- #
1588
- def process_bmp(data, filename) #:nodoc:
1589
- type = 7 # Excel Blip type (MSOBLIPTYPE).
1590
-
1591
- # Check that the file is big enough to be a bitmap.
1592
- if data.bytesize <= 0x36
1593
- raise "#{filename} doesn't contain enough data."
1594
- end
1595
-
1596
- # Read the bitmap width and height. Verify the sizes.
1597
- width, height = data.unpack("x18 V2")
1598
-
1599
- if width > 0xFFFF
1600
- raise "#{filename}: largest image width #{width} supported is 65k."
1601
- end
1602
-
1603
- if height > 0xFFFF
1604
- raise "#{filename}: largest image height supported is 65k."
1605
- end
1606
-
1607
- # Read the bitmap planes and bpp data. Verify them.
1608
- planes, bitcount = data.unpack("x26 v2")
1609
-
1610
- if bitcount != 24
1611
- raise "#{filename} isn't a 24bit true color bitmap."
1612
- end
1613
-
1614
- if planes != 1
1615
- raise "#{filename}: only 1 plane supported in bitmap image."
1616
- end
1617
-
1618
- # Read the bitmap compression. Verify compression.
1619
- compression = data.unpack("x30 V")
1620
-
1621
- if compression != 0
1622
- raise "#{filename}: compression not supported in bitmap image."
1623
- end
1624
-
1625
- [type, width, height]
1626
- end
1627
- private :process_bmp
1628
-
1629
- ###############################################################################
1630
- #
1631
- # process_jpg()
1632
- #
1633
- # Extract width and height information from a JPEG file.
1634
- #
1635
- def process_jpg(data, filename) # :nodoc:
1636
- type = 5 # Excel Blip type (MSOBLIPTYPE).
1637
-
1638
- offset = 2
1639
- data_length = data.bytesize
1640
-
1641
- # Search through the image data to find the 0xFFC0 marker. The height and
1642
- # width are contained in the data for that sub element.
1643
- while offset < data_length
1644
- marker = data[offset, 2].unpack("n")
1645
- marker = marker[0]
1646
- length = data[offset+2, 2].unpack("n")
1647
- length = length[0]
1648
-
1649
- if marker == 0xFFC0 || marker == 0xFFC2
1650
- height = data[offset+5, 2].unpack("n")
1651
- height = height[0]
1652
- width = data[offset+7, 2].unpack("n")
1653
- width = width[0]
1654
- break
1655
- end
1656
-
1657
- offset += length + 2
1658
- break if marker == 0xFFDA
1659
- end
1660
-
1661
- if height.nil?
1662
- raise "#{filename}: no size data found in jpeg image.\n"
1663
- end
1664
-
1665
- [type, width, height]
1666
- end
1667
1437
 
1668
- ###############################################################################
1669
- #
1670
- # store_all_fonts()
1671
1438
  #
1672
1439
  # Store the Excel FONT records.
1673
1440
  #
@@ -1754,11 +1521,7 @@ class Workbook < BIFFWriter
1754
1521
  end
1755
1522
  end
1756
1523
  end
1757
- private :store_all_fonts
1758
1524
 
1759
- ###############################################################################
1760
- #
1761
- # store_all_num_formats()
1762
1525
  #
1763
1526
  # Store user defined numerical formats i.e. FORMAT records
1764
1527
  #
@@ -1793,11 +1556,7 @@ class Workbook < BIFFWriter
1793
1556
  end
1794
1557
  end
1795
1558
  end
1796
- private :store_all_num_formats
1797
1559
 
1798
- ###############################################################################
1799
- #
1800
- # store_all_xfs()
1801
1560
  #
1802
1561
  # Write all XF records.
1803
1562
  #
@@ -1807,11 +1566,7 @@ class Workbook < BIFFWriter
1807
1566
  append(xf)
1808
1567
  end
1809
1568
  end
1810
- private :store_all_xfs
1811
1569
 
1812
- ###############################################################################
1813
- #
1814
- # store_all_styles()
1815
1570
  #
1816
1571
  # Write all STYLE records.
1817
1572
  #
@@ -1838,11 +1593,7 @@ class Workbook < BIFFWriter
1838
1593
  store_style(type, xf_index)
1839
1594
  end
1840
1595
  end
1841
- private :store_all_styles
1842
1596
 
1843
- ###############################################################################
1844
- #
1845
- # store_names()
1846
1597
  #
1847
1598
  # Write the NAME record to define the print area and the repeat rows and cols.
1848
1599
  #
@@ -1890,7 +1641,6 @@ class Workbook < BIFFWriter
1890
1641
  end
1891
1642
  end
1892
1643
  end
1893
- private :create_autofilter_name_records
1894
1644
 
1895
1645
  def create_print_area_name_records(sorted_worksheets) #:nodoc:
1896
1646
  sorted_worksheets.each do |worksheet|
@@ -1910,7 +1660,6 @@ class Workbook < BIFFWriter
1910
1660
  end
1911
1661
  end
1912
1662
  end
1913
- private :create_print_area_name_records
1914
1663
 
1915
1664
  def create_print_title_name_records(sorted_worksheets) #:nodoc:
1916
1665
  sorted_worksheets.each do |worksheet|
@@ -1964,7 +1713,6 @@ class Workbook < BIFFWriter
1964
1713
  end
1965
1714
  end
1966
1715
  end
1967
- private :create_print_title_name_records
1968
1716
 
1969
1717
  ###############################################################################
1970
1718
  ###############################################################################
@@ -1973,9 +1721,6 @@ class Workbook < BIFFWriter
1973
1721
  #
1974
1722
 
1975
1723
 
1976
- ###############################################################################
1977
- #
1978
- # store_window1()
1979
1724
  #
1980
1725
  # Write Excel BIFF WINDOW1 record.
1981
1726
  #
@@ -2005,20 +1750,23 @@ class Workbook < BIFFWriter
2005
1750
 
2006
1751
  append(header, data)
2007
1752
  end
2008
- private :store_window1
2009
1753
 
2010
- ###############################################################################
2011
- #
2012
- # store_boundsheet()
2013
- # my $sheetname = $_[0]; # Worksheet name
2014
- # my $offset = $_[1]; # Location of worksheet BOF
2015
- # my $type = $_[2]; # Worksheet type
2016
- # my $hidden = $_[3]; # Worksheet hidden flag
2017
- # my $encoding = $_[4]; # Sheet name encoding
2018
1754
  #
2019
1755
  # Writes Excel BIFF BOUNDSHEET record.
2020
1756
  #
2021
- def store_boundsheet(sheetname, offset, type, hidden, encoding) #:nodoc:
1757
+ # sheetname # Worksheet name
1758
+ # offset # Location of worksheet BOF
1759
+ # type # Worksheet type
1760
+ # hidden # Worksheet hidden flag
1761
+ # encoding # Sheet name encoding
1762
+ #
1763
+ def store_boundsheet(sheet) #:nodoc:
1764
+ sheetname = sheet.name
1765
+ offset = sheet.offset
1766
+ type = sheet.type
1767
+ hidden = sheet.hidden? ? 1 : 0
1768
+ encoding = sheet.is_name_utf16be? ? 1 : 0
1769
+
2022
1770
  record = 0x0085 # Record identifier
2023
1771
  length = 0x08 + sheetname.bytesize # Number of bytes to follow
2024
1772
 
@@ -2037,16 +1785,13 @@ class Workbook < BIFFWriter
2037
1785
 
2038
1786
  append(header, data, sheetname)
2039
1787
  end
2040
- private :store_boundsheet
2041
1788
 
2042
- ###############################################################################
2043
- #
2044
- # store_style()
2045
- # type = $_[0] # Built-in style
2046
- # xf_index = $_[1] # Index to style XF
2047
1789
  #
2048
1790
  # Write Excel BIFF STYLE records.
2049
1791
  #
1792
+ # type # Built-in style
1793
+ # xf_index # Index to style XF
1794
+ #
2050
1795
  def store_style(type, xf_index) #:nodoc:
2051
1796
  record = 0x0293 # Record identifier
2052
1797
  length = 0x0004 # Bytes to follow
@@ -2060,17 +1805,14 @@ class Workbook < BIFFWriter
2060
1805
 
2061
1806
  append(header, data)
2062
1807
  end
2063
- private :store_style
2064
1808
 
2065
- ###############################################################################
2066
- #
2067
- # store_num_format()
2068
- # my $format = $_[0]; # Custom format string
2069
- # my $ifmt = $_[1]; # Format index code
2070
- # my $encoding = $_[2]; # Char encoding for format string
2071
1809
  #
2072
1810
  # Writes Excel FORMAT record for non "built-in" numerical formats.
2073
1811
  #
1812
+ # format # Custom format string
1813
+ # ifmt # Format index code
1814
+ # encoding # Char encoding for format string
1815
+ #
2074
1816
  def store_num_format(format, ifmt, encoding) #:nodoc:
2075
1817
  format = format.to_s unless format.respond_to?(:to_str)
2076
1818
  record = 0x041E # Record identifier
@@ -2108,11 +1850,7 @@ class Workbook < BIFFWriter
2108
1850
 
2109
1851
  append(header, data, format)
2110
1852
  end
2111
- private :store_num_format
2112
1853
 
2113
- ###############################################################################
2114
- #
2115
- # store_1904()
2116
1854
  #
2117
1855
  # Write Excel 1904 record to indicate the date system in use.
2118
1856
  #
@@ -2127,11 +1865,7 @@ class Workbook < BIFFWriter
2127
1865
 
2128
1866
  append(header, data)
2129
1867
  end
2130
- private :store_1904
2131
1868
 
2132
- ###############################################################################
2133
- #
2134
- # store_supbook()
2135
1869
  #
2136
1870
  # Write BIFF record SUPBOOK to indicate that the workbook contains external
2137
1871
  # references, in our case, formula, print area and print title refs.
@@ -2148,11 +1882,7 @@ class Workbook < BIFFWriter
2148
1882
 
2149
1883
  append(header, data)
2150
1884
  end
2151
- private :store_supbook
2152
1885
 
2153
- ###############################################################################
2154
- #
2155
- # store_externsheet()
2156
1886
  #
2157
1887
  # Writes the Excel BIFF EXTERNSHEET record. These references are used by
2158
1888
  # formulas. TODO NAME record is required to define the print area and the
@@ -2233,22 +1963,19 @@ class Workbook < BIFFWriter
2233
1963
  append(header, data)
2234
1964
  end
2235
1965
 
2236
- ###############################################################################
2237
- #
2238
- # store_name_short()
2239
- # index = shift # Sheet index
2240
- # type = shift
2241
- # ext_ref = shift # TODO
2242
- # rowmin = $_[0] # Start row
2243
- # rowmax = $_[1] # End row
2244
- # colmin = $_[2] # Start column
2245
- # colmax = $_[3] # end column
2246
- # hidden = $_[4] # Name is hidden
2247
- #
2248
1966
  #
2249
1967
  # Store the NAME record in the short format that is used for storing the print
2250
1968
  # area, repeat rows only and repeat columns only.
2251
1969
  #
1970
+ # index # Sheet index
1971
+ # type
1972
+ # ext_ref # TODO
1973
+ # rowmin # Start row
1974
+ # rowmax # End row
1975
+ # colmin # Start column
1976
+ # colmax # end column
1977
+ # hidden # Name is hidden
1978
+ #
2252
1979
  def store_name_short(index, type, ext_ref, rowmin, rowmax, colmin, colmax, hidden = nil) #:nodoc:
2253
1980
  record = 0x0018 # Record identifier
2254
1981
  length = 0x001b # Number of bytes to follow
@@ -2292,25 +2019,21 @@ class Workbook < BIFFWriter
2292
2019
 
2293
2020
  append(header, data)
2294
2021
  end
2295
- private :store_name_short
2296
2022
 
2297
- ###############################################################################
2298
- #
2299
- # store_name_long()
2300
- # my $index = shift; # Sheet index
2301
- # my $type = shift;
2302
- # my $ext_ref = shift; # TODO
2303
- # my $rowmin = $_[0]; # Start row
2304
- # my $rowmax = $_[1]; # End row
2305
- # my $colmin = $_[2]; # Start column
2306
- # my $colmax = $_[3]; # end column
2307
- #
2308
2023
  #
2309
2024
  # Store the NAME record in the long format that is used for storing the repeat
2310
2025
  # rows and columns when both are specified. This share a lot of code with
2311
2026
  # store_name_short() but we use a separate method to keep the code clean.
2312
2027
  # Code abstraction for reuse can be carried too far, and I should know. ;-)
2313
2028
  #
2029
+ # index # Sheet index
2030
+ # type
2031
+ # ext_ref # TODO
2032
+ # rowmin # Start row
2033
+ # rowmax # End row
2034
+ # colmin # Start column
2035
+ # colmax # end column
2036
+ #
2314
2037
  def store_name_long(index, type, ext_ref, rowmin, rowmax, colmin, colmax) #:nodoc:
2315
2038
  record = 0x0018 # Record identifier
2316
2039
  length = 0x002a # Number of bytes to follow
@@ -2368,11 +2091,7 @@ class Workbook < BIFFWriter
2368
2091
 
2369
2092
  append(header, data)
2370
2093
  end
2371
- private :store_name_long
2372
2094
 
2373
- ###############################################################################
2374
- #
2375
- # store_palette()
2376
2095
  #
2377
2096
  # Stores the PALETTE biff record.
2378
2097
  #
@@ -2391,11 +2110,7 @@ class Workbook < BIFFWriter
2391
2110
 
2392
2111
  append(header, data)
2393
2112
  end
2394
- private :store_palette
2395
2113
 
2396
- ###############################################################################
2397
- #
2398
- # store_codepage()
2399
2114
  #
2400
2115
  # Stores the CODEPAGE biff record.
2401
2116
  #
@@ -2406,11 +2121,7 @@ class Workbook < BIFFWriter
2406
2121
 
2407
2122
  store_common(record, length, cv)
2408
2123
  end
2409
- private :store_codepage
2410
2124
 
2411
- ###############################################################################
2412
- #
2413
- # store_country()
2414
2125
  #
2415
2126
  # Stores the COUNTRY biff record.
2416
2127
  #
@@ -2422,22 +2133,17 @@ class Workbook < BIFFWriter
2422
2133
 
2423
2134
  store_common(record, length, country_default, country_win_ini)
2424
2135
  end
2425
- private :store_country
2426
2136
 
2427
- ###############################################################################
2428
- #
2429
- # store_hideobj()
2430
2137
  #
2431
2138
  # Stores the HIDEOBJ biff record.
2432
2139
  #
2433
2140
  def store_hideobj #:nodoc:
2434
2141
  record = 0x008D # Record identifier
2435
2142
  length = 0x0002 # Number of bytes to follow
2436
- hide = @hideobj # Option to hide objects
2143
+ hide = @hideobj ? 1 : 0 # Option to hide objects
2437
2144
 
2438
2145
  store_common(record, length, hide)
2439
2146
  end
2440
- private :store_hideobj
2441
2147
 
2442
2148
  def store_common(record, length, *data) #:nodoc:
2443
2149
  header = [record, length].pack("vv")
@@ -2445,11 +2151,7 @@ class Workbook < BIFFWriter
2445
2151
 
2446
2152
  append(header, add_data)
2447
2153
  end
2448
- private :store_common
2449
2154
 
2450
- ###############################################################################
2451
- #
2452
- # calculate_extern_sizes()
2453
2155
  #
2454
2156
  # We need to calculate the space required by the SUPBOOK, EXTERNSHEET and NAME
2455
2157
  # records so that it can be added to the BOUNDSHEET offsets.
@@ -2525,11 +2227,7 @@ class Workbook < BIFFWriter
2525
2227
  def add_ext_refs(ext_refs, key) #:nodoc:
2526
2228
  ext_refs[key] = ext_refs.keys.size
2527
2229
  end
2528
- private :add_ext_refs
2529
2230
 
2530
- ###############################################################################
2531
- #
2532
- # calculate_shared_string_sizes()
2533
2231
  #
2534
2232
  # Handling of the SST continue blocks is complicated by the need to include an
2535
2233
  # additional continuation byte depending on whether the string is split between
@@ -2652,7 +2350,6 @@ class Workbook < BIFFWriter
2652
2350
 
2653
2351
  length
2654
2352
  end
2655
- private :calculate_shared_string_sizes
2656
2353
 
2657
2354
  def split_string_setup(encoding, split_string, continue_limit, written, continue) #:nodoc:
2658
2355
  # We need to avoid the case where a string is continued in the first
@@ -2684,11 +2381,7 @@ class Workbook < BIFFWriter
2684
2381
  end
2685
2382
  [header_length, space_remaining, align, split_string]
2686
2383
  end
2687
- private :split_string_setup
2688
2384
 
2689
- ###############################################################################
2690
- #
2691
- # store_shared_strings()
2692
2385
  #
2693
2386
  # Write all of the workbooks strings into an indexed array.
2694
2387
  #
@@ -2840,11 +2533,7 @@ class Workbook < BIFFWriter
2840
2533
  end
2841
2534
  end
2842
2535
  end
2843
- private :store_shared_strings
2844
2536
 
2845
- ###############################################################################
2846
- #
2847
- # calculate_extsst_size
2848
2537
  #
2849
2538
  # The number of buckets used in the EXTSST is between 0 and 128. The number of
2850
2539
  # strings per bucket (bucket size) has a minimum value of 8 and a theoretical
@@ -2869,9 +2558,6 @@ class Workbook < BIFFWriter
2869
2558
  6 + 8 * buckets
2870
2559
  end
2871
2560
 
2872
- ###############################################################################
2873
- #
2874
- # store_extsst
2875
2561
  #
2876
2562
  # Write EXTSST table using the offsets calculated in store_shared_strings().
2877
2563
  #
@@ -2891,15 +2577,11 @@ class Workbook < BIFFWriter
2891
2577
 
2892
2578
  append(header, data)
2893
2579
  end
2894
- private :store_extsst
2895
2580
 
2896
2581
  #
2897
2582
  # Methods related to comments and MSO objects.
2898
2583
  #
2899
2584
 
2900
- ###############################################################################
2901
- #
2902
- # add_mso_drawing_group()
2903
2585
  #
2904
2586
  # Write the MSODRAWINGGROUP record that keeps track of the Escher drawing
2905
2587
  # objects in the file such as images, comments and filters.
@@ -2914,7 +2596,7 @@ class Workbook < BIFFWriter
2914
2596
  data += store_mso_dgg(*@mso_clusters)
2915
2597
  data += store_mso_bstore_container
2916
2598
  @images_data.each do |image|
2917
- data += store_mso_images(*image)
2599
+ data += store_mso_images(image)
2918
2600
  end
2919
2601
  data += store_mso_opt
2920
2602
  data += store_mso_split_menu_colors
@@ -2926,13 +2608,9 @@ class Workbook < BIFFWriter
2926
2608
 
2927
2609
  header + data # For testing only.
2928
2610
  end
2929
- private :add_mso_drawing_group
2930
2611
 
2931
- ###############################################################################
2932
- #
2933
- # add_mso_drawing_group_continue()
2934
2612
  #
2935
- # See first the WriteExcel::BIFFwriter::_add_continue() method.
2613
+ # See first BIFFwriter#add_continue() method.
2936
2614
  #
2937
2615
  # Add specialised CONTINUE headers to large MSODRAWINGGROUP data block.
2938
2616
  # We use the Excel 97 max block size of 8228 - 4 bytes for the header = 8224.
@@ -2985,18 +2663,13 @@ class Workbook < BIFFWriter
2985
2663
  # Turn the base class add_continue() method back on.
2986
2664
  @ignore_continue = 0
2987
2665
  end
2988
- private :add_mso_drawing_group_continue
2989
2666
 
2990
2667
  def devide_string(string, nth) #:nodoc:
2991
2668
  first_string = string[0, nth]
2992
2669
  latter_string = string[nth, string.size - nth]
2993
2670
  [first_string, latter_string]
2994
2671
  end
2995
- private :devide_string
2996
2672
 
2997
- ###############################################################################
2998
- #
2999
- # store_mso_dgg_container()
3000
2673
  #
3001
2674
  # Write the Escher DggContainer record that is part of MSODRAWINGGROUP.
3002
2675
  #
@@ -3009,16 +2682,7 @@ class Workbook < BIFFWriter
3009
2682
 
3010
2683
  add_mso_generic(type, version, instance, data, length)
3011
2684
  end
3012
- private :store_mso_dgg_container
3013
2685
 
3014
- ###############################################################################
3015
- #
3016
- # store_mso_dgg()
3017
- # my $max_spid = $_[0];
3018
- # my $num_clusters = $_[1];
3019
- # my $shapes_saved = $_[2];
3020
- # my $drawings_saved = $_[3];
3021
- # my $clusters = $_[4];
3022
2686
  #
3023
2687
  # Write the Escher Dgg record that is part of MSODRAWINGGROUP.
3024
2688
  #
@@ -3041,11 +2705,7 @@ class Workbook < BIFFWriter
3041
2705
 
3042
2706
  add_mso_generic(type, version, instance, data, length)
3043
2707
  end
3044
- private :store_mso_dgg
3045
2708
 
3046
- ###############################################################################
3047
- #
3048
- # store_mso_bstore_container()
3049
2709
  #
3050
2710
  # Write the Escher BstoreContainer record that is part of MSODRAWINGGROUP.
3051
2711
  #
@@ -3060,47 +2720,22 @@ class Workbook < BIFFWriter
3060
2720
 
3061
2721
  add_mso_generic(type, version, instance, data, length)
3062
2722
  end
3063
- private :store_mso_bstore_container
3064
2723
 
3065
- ###############################################################################
3066
- #
3067
- # store_mso_images()
3068
- # ref_count = $_[0]
3069
- # image_type = $_[1]
3070
- # image = $_[2]
3071
- # size = $_[3]
3072
- # checksum1 = $_[4]
3073
- # checksum2 = $_[5]
3074
2724
  #
3075
2725
  # Write the Escher BstoreContainer record that is part of MSODRAWINGGROUP.
3076
2726
  #
3077
- def store_mso_images(ref_count, image_type, image, size, checksum1, checksum2) #:nodoc:
2727
+ def store_mso_images(image)
3078
2728
  blip_store_entry = store_mso_blip_store_entry(
3079
- ref_count,
3080
- image_type,
3081
- size,
3082
- checksum1
2729
+ image.ref_count, image.type, image.size, image.checksum1
3083
2730
  )
3084
2731
 
3085
2732
  blip = store_mso_blip(
3086
- image_type,
3087
- image,
3088
- size,
3089
- checksum1,
3090
- checksum2
2733
+ image.type, image.data, image.size, image.checksum1, image.checksum2
3091
2734
  )
3092
2735
 
3093
2736
  blip_store_entry + blip
3094
2737
  end
3095
- private :store_mso_images
3096
2738
 
3097
- ###############################################################################
3098
- #
3099
- # store_mso_blip_store_entry()
3100
- # ref_count = $_[0]
3101
- # image_type = $_[1]
3102
- # size = $_[2]
3103
- # checksum1 = $_[3]
3104
2739
  #
3105
2740
  # Write the Escher BlipStoreEntry record that is part of MSODRAWINGGROUP.
3106
2741
  #
@@ -3123,16 +2758,7 @@ class Workbook < BIFFWriter
3123
2758
 
3124
2759
  add_mso_generic(type, version, instance, data, length)
3125
2760
  end
3126
- private :store_mso_blip_store_entry
3127
2761
 
3128
- ###############################################################################
3129
- #
3130
- # store_mso_blip()
3131
- # image_type = $_[0]
3132
- # image_data = $_[1]
3133
- # size = $_[2]
3134
- # checksum1 = $_[3]
3135
- # checksum2 = $_[4]
3136
2762
  #
3137
2763
  # Write the Escher Blip record that is part of MSODRAWINGGROUP.
3138
2764
  #
@@ -3155,11 +2781,7 @@ class Workbook < BIFFWriter
3155
2781
 
3156
2782
  add_mso_generic(type, version, instance, data, length)
3157
2783
  end
3158
- private :store_mso_blip
3159
2784
 
3160
- ###############################################################################
3161
- #
3162
- # store_mso_opt()
3163
2785
  #
3164
2786
  # Write the Escher Opt record that is part of MSODRAWINGGROUP.
3165
2787
  #
@@ -3174,11 +2796,7 @@ class Workbook < BIFFWriter
3174
2796
 
3175
2797
  add_mso_generic(type, version, instance, data, length)
3176
2798
  end
3177
- private :store_mso_opt
3178
2799
 
3179
- ###############################################################################
3180
- #
3181
- # store_mso_split_menu_colors()
3182
2800
  #
3183
2801
  # Write the Escher SplitMenuColors record that is part of MSODRAWINGGROUP.
3184
2802
  #
@@ -3193,22 +2811,14 @@ class Workbook < BIFFWriter
3193
2811
 
3194
2812
  add_mso_generic(type, version, instance, data, length)
3195
2813
  end
3196
- private :store_mso_split_menu_colors
3197
2814
 
3198
2815
  def cleanup #:nodoc:
3199
2816
  super
3200
2817
  sheets.each { |sheet| sheet.cleanup }
3201
2818
  end
3202
- private :cleanup
3203
-
3204
- private
3205
2819
 
3206
2820
  def add_doc_properties
3207
- @add_doc_properties
3208
- end
3209
-
3210
- def add_doc_properties=(val)
3211
- @add_doc_properties = val
2821
+ @add_doc_properties ||= false
3212
2822
  end
3213
2823
 
3214
2824
  def formats