writeexcel 0.6.6 → 0.6.7

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 (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