writeexcel 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. data/README +26 -31
  2. data/examples/a_simple.rb +42 -42
  3. data/examples/{autofilters.rb → autofilter.rb} +264 -266
  4. data/examples/bigfile.rb +29 -0
  5. data/examples/chart_area.rb +120 -0
  6. data/examples/chart_bar.rb +119 -0
  7. data/examples/chart_column.rb +119 -0
  8. data/examples/chart_line.rb +119 -0
  9. data/examples/chart_pie.rb +107 -0
  10. data/examples/chart_scatter.rb +120 -0
  11. data/examples/chart_stock.rb +147 -0
  12. data/examples/copyformat.rb +51 -51
  13. data/examples/data_validate.rb +278 -278
  14. data/examples/date_time.rb +86 -86
  15. data/examples/defined_name.rb +31 -0
  16. data/examples/demo.rb +120 -118
  17. data/examples/diag_border.rb +35 -35
  18. data/examples/formats.rb +489 -489
  19. data/examples/header.rb +136 -136
  20. data/examples/hidden.rb +28 -28
  21. data/examples/hyperlink.rb +42 -42
  22. data/examples/images.rb +52 -52
  23. data/examples/merge1.rb +39 -39
  24. data/examples/merge2.rb +44 -44
  25. data/examples/merge3.rb +65 -65
  26. data/examples/merge4.rb +82 -82
  27. data/examples/merge5.rb +79 -79
  28. data/examples/properties.rb +33 -0
  29. data/examples/properties_jp.rb +32 -0
  30. data/examples/protection.rb +46 -46
  31. data/examples/regions.rb +52 -52
  32. data/examples/repeat.rb +42 -42
  33. data/examples/stats.rb +75 -75
  34. data/examples/stocks.rb +80 -80
  35. data/examples/tab_colors.rb +30 -30
  36. data/examples/write_arrays.rb +82 -0
  37. data/lib/writeexcel.rb +1134 -18
  38. data/lib/writeexcel/biffwriter.rb +273 -260
  39. data/lib/writeexcel/chart.rb +2306 -217
  40. data/lib/writeexcel/charts/area.rb +152 -0
  41. data/lib/writeexcel/charts/bar.rb +177 -0
  42. data/lib/writeexcel/charts/column.rb +156 -0
  43. data/lib/writeexcel/charts/external.rb +61 -0
  44. data/lib/writeexcel/charts/line.rb +152 -0
  45. data/lib/writeexcel/charts/pie.rb +169 -0
  46. data/lib/writeexcel/charts/scatter.rb +192 -0
  47. data/lib/writeexcel/charts/stock.rb +211 -0
  48. data/lib/writeexcel/excelformulaparser.rb +208 -195
  49. data/lib/writeexcel/format.rb +1697 -1108
  50. data/lib/writeexcel/formula.rb +1050 -986
  51. data/lib/writeexcel/olewriter.rb +322 -322
  52. data/lib/writeexcel/properties.rb +251 -250
  53. data/lib/writeexcel/storage_lite.rb +968 -0
  54. data/lib/writeexcel/workbook.rb +3294 -2630
  55. data/lib/writeexcel/worksheet.rb +9012 -6377
  56. data/test/excelfile/Chart1.xls +0 -0
  57. data/test/excelfile/Chart2.xls +0 -0
  58. data/test/excelfile/Chart3.xls +0 -0
  59. data/test/excelfile/Chart4.xls +0 -0
  60. data/test/excelfile/Chart5.xls +0 -0
  61. data/test/perl_output/Chart1.xls.data +0 -0
  62. data/test/perl_output/Chart2.xls.data +0 -0
  63. data/test/perl_output/Chart3.xls.data +0 -0
  64. data/test/perl_output/Chart4.xls.data +0 -0
  65. data/test/perl_output/Chart5.xls.data +0 -0
  66. data/test/perl_output/a_simple.xls +0 -0
  67. data/test/perl_output/autofilter.xls +0 -0
  68. data/test/perl_output/chart_area.xls +0 -0
  69. data/test/perl_output/chart_bar.xls +0 -0
  70. data/test/perl_output/chart_column.xls +0 -0
  71. data/test/perl_output/chart_line.xls +0 -0
  72. data/test/perl_output/data_validate.xls +0 -0
  73. data/test/perl_output/date_time.xls +0 -0
  74. data/test/perl_output/demo.xls +0 -0
  75. data/test/perl_output/demo101.bin +0 -0
  76. data/test/perl_output/demo201.bin +0 -0
  77. data/test/perl_output/demo301.bin +0 -0
  78. data/test/perl_output/demo401.bin +0 -0
  79. data/test/perl_output/demo501.bin +0 -0
  80. data/test/perl_output/diag_border.xls +0 -0
  81. data/test/perl_output/headers.xls +0 -0
  82. data/test/perl_output/hyperlink.xls +0 -0
  83. data/test/perl_output/images.xls +0 -0
  84. data/test/perl_output/merge1.xls +0 -0
  85. data/test/perl_output/merge2.xls +0 -0
  86. data/test/perl_output/merge3.xls +0 -0
  87. data/test/perl_output/merge4.xls +0 -0
  88. data/test/perl_output/merge5.xls +0 -0
  89. data/test/perl_output/protection.xls +0 -0
  90. data/test/perl_output/regions.xls +0 -0
  91. data/test/perl_output/stats.xls +0 -0
  92. data/test/perl_output/stocks.xls +0 -0
  93. data/test/perl_output/tab_colors.xls +0 -0
  94. data/test/perl_output/unicode_cyrillic.xls +0 -0
  95. data/test/perl_output/workbook1.xls +0 -0
  96. data/test/perl_output/workbook2.xls +0 -0
  97. data/test/tc_all.rb +32 -31
  98. data/test/tc_biff.rb +104 -104
  99. data/test/tc_chart.rb +22 -22
  100. data/test/tc_example_match.rb +1944 -1280
  101. data/test/tc_format.rb +1254 -1267
  102. data/test/tc_formula.rb +63 -63
  103. data/test/tc_ole.rb +110 -110
  104. data/test/tc_storage_lite.rb +149 -0
  105. data/test/tc_workbook.rb +140 -115
  106. data/test/tc_worksheet.rb +115 -115
  107. data/test/test_00_IEEE_double.rb +14 -14
  108. data/test/test_01_add_worksheet.rb +12 -12
  109. data/test/test_02_merge_formats.rb +58 -58
  110. data/test/test_04_dimensions.rb +397 -397
  111. data/test/test_05_rows.rb +182 -182
  112. data/test/test_06_extsst.rb +80 -80
  113. data/test/test_11_date_time.rb +484 -484
  114. data/test/test_12_date_only.rb +506 -506
  115. data/test/test_13_date_seconds.rb +486 -486
  116. data/test/test_21_escher.rb +642 -629
  117. data/test/test_22_mso_drawing_group.rb +750 -739
  118. data/test/test_23_note.rb +78 -78
  119. data/test/test_24_txo.rb +80 -80
  120. data/test/test_25_position_object.rb +82 -0
  121. data/test/test_26_autofilter.rb +327 -327
  122. data/test/test_27_autofilter.rb +144 -144
  123. data/test/test_28_autofilter.rb +174 -174
  124. data/test/test_29_process_jpg.rb +681 -131
  125. data/test/test_30_validation_dval.rb +82 -82
  126. data/test/test_31_validation_dv_strings.rb +131 -131
  127. data/test/test_32_validation_dv_formula.rb +211 -211
  128. data/test/test_40_property_types.rb +191 -191
  129. data/test/test_41_properties.rb +238 -238
  130. data/test/test_42_set_properties.rb +442 -419
  131. data/test/test_50_name_stored.rb +305 -0
  132. data/test/test_51_name_print_area.rb +363 -0
  133. data/test/test_52_name_print_titles.rb +460 -0
  134. data/test/test_53_autofilter.rb +209 -0
  135. data/test/test_60_chart_generic.rb +576 -0
  136. data/test/test_61_chart_subclasses.rb +97 -0
  137. data/test/test_62_chart_formats.rb +270 -0
  138. data/test/test_63_chart_area_formats.rb +647 -0
  139. data/test/test_chartex.rb +35 -0
  140. data/test/ts_all.rb +46 -34
  141. data/writeexcel.gemspec +18 -0
  142. data/writeexcel.rdoc +583 -0
  143. metadata +162 -108
@@ -0,0 +1,305 @@
1
+ ##########################################################################
2
+ # test_50_name_stored.rb
3
+ #
4
+ # Tests for the Excel EXTERNSHEET and NAME records created by print_are()..
5
+ #
6
+ # reverse('ゥ'), September 2008, John McNamara, jmcnamara@cpan.org
7
+ #
8
+ # original written in Perl by John McNamara
9
+ # converted to Ruby by Hideo Nakamura, cxn03651@msj.biglobe.ne.jp
10
+ #
11
+ #########################################################################
12
+ $LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"
13
+ require 'test/unit'
14
+ require 'rubygems'
15
+ require 'writeexcel'
16
+ require 'stringio'
17
+
18
+ class TC_Name_Stored < Test::Unit::TestCase
19
+ def setup
20
+ @test_file = StringIO.new
21
+ @workbook = WriteExcel.new(@test_file)
22
+ @worksheet = @workbook.add_worksheet
23
+ end
24
+
25
+ def test_print_area_name_with_simple_range
26
+ caption = " \tNAME for worksheet1.print_area('A1:B12')"
27
+ name = [0x06].pack('C')
28
+ encoding = 0
29
+ sheet_index = 1
30
+ formula = ['3B000000000B0000000100'].pack('H*')
31
+
32
+ result = @workbook.store_name(
33
+ name,
34
+ encoding,
35
+ sheet_index,
36
+ formula
37
+ )
38
+ target = [%w(
39
+ 18 00 1B 00 20 00 00 01 0B 00 00 00 01 00 00 00
40
+ 00 00 00 06 3B 00 00 00 00 0B 00 00 00 01 00
41
+ ).join('')].pack('H*')
42
+
43
+ result = _unpack_name(result)
44
+ target = _unpack_name(target)
45
+ assert_equal(result, target)
46
+ end
47
+
48
+ def test_print_area_name_with_simple_range_in_sheet_3
49
+ caption = " \tNAME for worksheet3.print_area('G7:H8')"
50
+ name = [0x06].pack('C')
51
+ encoding = 0
52
+ sheet_index = 3
53
+ formula = ['3B02000600070006000700'].pack('H*')
54
+
55
+ result = @workbook.store_name(
56
+ name,
57
+ encoding,
58
+ sheet_index,
59
+ formula
60
+ )
61
+
62
+ target = [%w(
63
+ 18 00 1B 00 20 00 00 01 0B 00 00 00 03 00 00 00
64
+ 00 00 00 06 3B 02 00 06 00 07 00 06 00 07 00
65
+ ).join('')].pack('H*')
66
+
67
+ result = _unpack_name(result)
68
+ target = _unpack_name(target)
69
+ assert_equal(result, target)
70
+ end
71
+
72
+ def test_for_repeat_rows_name
73
+ caption = " \tNAME for worksheet1.repeat_rows(0, 9)"
74
+ name = [0x07].pack('C')
75
+ encoding = 0
76
+ sheet_index = 1
77
+ formula = ['3B0000000009000000FF00'].pack('H*')
78
+
79
+ result = @workbook.store_name(
80
+ name,
81
+ encoding,
82
+ sheet_index,
83
+ formula
84
+ )
85
+
86
+ target = [%w(
87
+ 18 00 1B 00 20 00 00 01 0B 00 00 00 01 00 00 00
88
+ 00 00 00 07 3B 00 00 00 00 09 00 00 00 FF 00
89
+ ).join('')].pack('H*')
90
+
91
+ result = _unpack_name(result)
92
+ target = _unpack_name(target)
93
+ assert_equal(result, target)
94
+ end
95
+
96
+ def test_for_repeat_rows_name_on_sheet_3
97
+ caption = " \tNAME for worksheet3.repeat_rows(6, 7)"
98
+ name = [0x07].pack('C')
99
+ encoding = 0
100
+ sheet_index = 1
101
+ formula = ['3B0000000009000000FF00'].pack('H*')
102
+
103
+ result = @workbook.store_name(
104
+ name,
105
+ encoding,
106
+ sheet_index,
107
+ formula
108
+ )
109
+
110
+ target = [%w(
111
+ 18 00 1B 00 20 00 00 01 0B 00 00 00 01 00 00 00
112
+ 00 00 00 07 3B 00 00 00 00 09 00 00 00 FF 00
113
+ ).join('')].pack('H*')
114
+
115
+ result = _unpack_name(result)
116
+ target = _unpack_name(target)
117
+ assert_equal(result, target)
118
+ end
119
+
120
+ def test_for_repeat_columns_name
121
+ caption = " \tNAME for worksheet1.repeat_columns('A:J')"
122
+ name = [0x07].pack('C')
123
+ encoding = 0
124
+ sheet_index = 1
125
+ formula = ['3B00000000FFFF00000900'].pack('H*')
126
+
127
+ result = @workbook.store_name(
128
+ name,
129
+ encoding,
130
+ sheet_index,
131
+ formula
132
+ )
133
+
134
+ target = [%w(
135
+ 18 00 1B 00 20 00 00 01 0B 00 00 00 01 00 00 00
136
+ 00 00 00 07 3B 00 00 00 00 FF FF 00 00 09 00
137
+ ).join('')].pack('H*')
138
+
139
+ result = _unpack_name(result)
140
+ target = _unpack_name(target)
141
+ assert_equal(result, target)
142
+ end
143
+
144
+ def test_for_repeat_rows_and_repeat_columns_together_name
145
+ caption = " \tNAME for repeat_rows(1, 2) repeat_columns(3, 4)"
146
+ name = [0x07].pack('C')
147
+ encoding = 0
148
+ sheet_index = 1
149
+ formula = ['2917003B00000000FFFF030004003B0000010002000000FF0010'].pack('H*')
150
+
151
+ result = @workbook.store_name(
152
+ name,
153
+ encoding,
154
+ sheet_index,
155
+ formula
156
+ )
157
+
158
+ target = [%w(
159
+ 18 00 2A 00 20 00 00 01 1A 00 00 00 01 00 00 00
160
+ 00 00 00 07 29 17 00 3B 00 00 00 00 FF FF 03 00
161
+ 04 00 3B 00 00 01 00 02 00 00 00 FF 00 10
162
+ ).join('')].pack('H*')
163
+
164
+ result = _unpack_name(result)
165
+ target = _unpack_name(target)
166
+ assert_equal(result, target)
167
+ end
168
+
169
+ def test_for_print_area_name_with_simple_range
170
+ caption = " \tNAME for worksheet1.autofilter('A1:C5')"
171
+ name = [0x0D].pack('C')
172
+ encoding = 0
173
+ sheet_index = 1
174
+ formula = ['3B00000000040000000200'].pack('H*')
175
+
176
+ result = @workbook.store_name(
177
+ name,
178
+ encoding,
179
+ sheet_index,
180
+ formula
181
+ )
182
+
183
+ target = [%w(
184
+ 18 00 1B 00 21 00 00 01 0B 00 00 00 01 00 00 00
185
+ 00 00 00 0D 3B 00 00 00 00 04 00 00 00 02 00
186
+ ).join('')].pack('H*')
187
+
188
+ result = _unpack_name(result)
189
+ target = _unpack_name(target)
190
+ assert_equal(result, target)
191
+ end
192
+
193
+ def test_for_define_name_global_name
194
+ caption = " \tNAME for worksheet1.define_name('Foo', ...)"
195
+ name = 'Foo'
196
+ encoding = 0
197
+ sheet_index = 0
198
+ formula = ['3A000007000100'].pack('H*')
199
+
200
+ result = @workbook.store_name(
201
+ name,
202
+ encoding,
203
+ sheet_index,
204
+ formula
205
+ )
206
+
207
+ target = [%w(
208
+ 18 00 19 00 00 00 00 03 07 00 00 00 00 00 00 00
209
+ 00 00 00 46 6F 6F 3A 00 00 07 00 01 00
210
+ ).join('')].pack('H*')
211
+
212
+ result = _unpack_name(result)
213
+ target = _unpack_name(target)
214
+ assert_equal(result, target)
215
+ end
216
+
217
+ ###############################################################################
218
+ #
219
+ # Unpack the binary data into a format suitable for printing in tests.
220
+ #
221
+ def unpack_record(data)
222
+ data.unpack('C*').map! {|c| sprintf("%02X", c) }.join(' ')
223
+ end
224
+
225
+ ###############################################################################
226
+ #
227
+ # _unpack_name()
228
+ #
229
+ # Unpack 1 or more NAME structures into a AoH for easier comparison.
230
+ #
231
+ def _unpack_name(data)
232
+ names = Array.new
233
+ while data.length > 0
234
+ name = Hash.new
235
+
236
+ name['record'] = data[0, 2].unpack('v')[0]
237
+ data[0, 2] = ''
238
+ name['length'] = data[0, 2].unpack('v')[0]
239
+ data[0, 2] = ''
240
+ name['flags'] = data[0, 2].unpack('v')[0]
241
+ data[0, 2] = ''
242
+ name['shortcut'] = data[0, 1].unpack('C')[0]
243
+ data[0, 1] = ''
244
+ name['str_len'] = data[0, 1].unpack('C')[0]
245
+ data[0, 1] = ''
246
+ name['formula_len'] = data[0, 2].unpack('v')[0]
247
+ data[0, 2] = ''
248
+ name['itals'] = data[0, 2].unpack('v')[0]
249
+ data[0, 2] = ''
250
+ name['sheet_index'] = data[0, 2].unpack('v')[0]
251
+ data[0, 2] = ''
252
+ name['menu_len'] = data[0, 1].unpack('C')[0]
253
+ data[0, 1] = ''
254
+ name['desc_len'] = data[0, 1].unpack('C')[0]
255
+ data[0, 1] = ''
256
+ name['help_len'] = data[0, 1].unpack('C')[0]
257
+ data[0, 1] = ''
258
+ name['status_len'] = data[0, 1].unpack('C')[0]
259
+ data[0, 1] = ''
260
+ name['encoding'] = data[0, 1].unpack('C')[0]
261
+ data[0, 1] = ''
262
+
263
+ # Decode the individual flag fields.
264
+ flag = Hash.new
265
+ flag['hidden'] = name['flags'] & 0x0001
266
+ flag['function'] = name['flags'] & 0x0002
267
+ flag['vb'] = name['flags'] & 0x0004
268
+ flag['macro'] = name['flags'] & 0x0008
269
+ flag['complex'] = name['flags'] & 0x0010
270
+ flag['builtin'] = name['flags'] & 0x0020
271
+ flag['group'] = name['flags'] & 0x0FC0
272
+ flag['binary'] = name['flags'] & 0x1000
273
+ name['flags'] = flag
274
+
275
+ # Decode the string part of the NAME structure.
276
+ if name['encoding'] == 1
277
+ # UTF-16 name. Leave in hex.
278
+ name['string'] = data[0, 2 * name['str_len']].unpack('H*')[0].upcase
279
+ data[0, 2 * name['str_len']] = ''
280
+ elsif flag['builtin'] != 0
281
+ # 1 digit builtin name. Leave in hex.
282
+ name['string'] = data[0, name['str_len']].unpack('H*')[0].upcase
283
+ data[0, name['str_len']] = ''
284
+ else
285
+ # ASCII name.
286
+ name['string'] = data[0, name['str_len']].unpack('C*').pack('C*')
287
+ data[0, name['str_len']] = ''
288
+ end
289
+
290
+ # Keep the formula as a hex string.
291
+ name['formula'] = data[0, name['formula_len']].unpack('H*')[0].upcase
292
+ data[0, name['formula_len']] = ''
293
+
294
+ names << name
295
+ end
296
+ names
297
+ end
298
+
299
+ def assert_hash_equal?(result, target)
300
+ assert_equal(result.keys.sort, target.keys.sort)
301
+ result.each_key do |key|
302
+ assert_equal(result[key], target[key])
303
+ end
304
+ end
305
+ end
@@ -0,0 +1,363 @@
1
+ ##########################################################################
2
+ # test_51_name_print_area.rb
3
+ #
4
+ # Tests for the Excel EXTERNSHEET and NAME records created by print_are()..
5
+ #
6
+ # reverse('ゥ'), September 2008, John McNamara, jmcnamara@cpan.org
7
+ #
8
+ # original written in Perl by John McNamara
9
+ # converted to Ruby by Hideo Nakamura, cxn03651@msj.biglobe.ne.jp
10
+ #
11
+ #########################################################################
12
+ $LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"
13
+ require 'test/unit'
14
+ require 'rubygems'
15
+ require 'writeexcel'
16
+ require 'stringio'
17
+
18
+ class TC_Name_Print_Area < Test::Unit::TestCase
19
+ def setup
20
+ @test_file = StringIO.new
21
+ @workbook = WriteExcel.new(@test_file)
22
+ @workbook.not_using_tmpfile
23
+ end
24
+
25
+ def test_print_area_name_for_a_simple_range
26
+ worksheet1 = @workbook.add_worksheet
27
+ area = 'A1:B12'
28
+
29
+ worksheet1.print_area(area)
30
+
31
+ # Test the EXTERNSHEET record.
32
+ @workbook.calculate_extern_sizes
33
+ @workbook.store_externsheet
34
+
35
+ target = [%w(
36
+ 17 00 08 00 01 00 00 00 00 00 00 00
37
+ ).join('')].pack('H*')
38
+
39
+ caption = " \tExternsheet"
40
+ result = _unpack_externsheet(@workbook.data)
41
+ target = _unpack_externsheet(target)
42
+ assert_equal(target, result)
43
+
44
+ # Test the NAME record.
45
+ @workbook.clear_data_for_test
46
+ @workbook.store_names
47
+
48
+ target = [%w(
49
+ 18 00 1B 00 20 00 00 01 0B 00 00 00 01 00 00 00
50
+ 00 00 00 06 3B 00 00 00 00 0B 00 00 00 01 00
51
+ ).join('')].pack('H*')
52
+
53
+ caption = " \t+ Name ( Sheet1!#{area} )";
54
+ result = _unpack_name(@workbook.data)
55
+ target = _unpack_name(target)
56
+ assert_equal(target, result)
57
+ end
58
+
59
+ def test_print_area_name_for_a_simple_row
60
+ worksheet1 = @workbook.add_worksheet
61
+ area = 'A1:IV1'
62
+
63
+ worksheet1.print_area(area)
64
+
65
+ # Test the EXTERNSHEET record.
66
+ @workbook.calculate_extern_sizes
67
+ @workbook.store_externsheet
68
+
69
+ target = [%w(
70
+ 17 00 08 00 01 00 00 00 00 00 00 00
71
+ ).join('')].pack('H*')
72
+
73
+ caption = " \tExternsheet"
74
+ result = _unpack_externsheet(@workbook.data)
75
+ target = _unpack_externsheet(target)
76
+ assert_equal(target, result)
77
+
78
+ # Test the NAME record.
79
+ @workbook.clear_data_for_test
80
+ @workbook.store_names
81
+
82
+ target = [%w(
83
+ 18 00 1B 00 20 00 00 01 0B 00 00 00 01 00 00 00
84
+ 00 00 00 06 3B 00 00 00 00 00 00 00 00 FF 00
85
+ ).join('')].pack('H*')
86
+
87
+ caption = " \t+ Name ( Sheet1!#{area} )";
88
+ result = _unpack_name(@workbook.data)
89
+ target = _unpack_name(target)
90
+ assert_equal(target, result)
91
+ end
92
+
93
+ def test_print_area_name_for_a_simple_column
94
+ worksheet1 = @workbook.add_worksheet
95
+ area = 'A1:A65536'
96
+
97
+ worksheet1.print_area(area)
98
+
99
+ # Test the EXTERNSHEET record.
100
+ @workbook.calculate_extern_sizes
101
+ @workbook.store_externsheet
102
+
103
+ target = [%w(
104
+ 17 00 08 00 01 00 00 00 00 00 00 00
105
+ ).join('')].pack('H*')
106
+
107
+ caption = " \tExternsheet"
108
+ result = _unpack_externsheet(@workbook.data)
109
+ target = _unpack_externsheet(target)
110
+ assert_equal(target, result)
111
+
112
+ # Test the NAME record.
113
+ @workbook.clear_data_for_test
114
+ @workbook.store_names
115
+
116
+ target = [%w(
117
+ 18 00 1B 00 20 00 00 01 0B 00 00 00 01 00 00 00
118
+ 00 00 00 06 3B 00 00 00 00 FF FF 00 00 00 00
119
+ ).join('')].pack('H*')
120
+
121
+ caption = " \t+ Name ( Sheet1!#{area} )";
122
+ result = _unpack_name(@workbook.data)
123
+ target = _unpack_name(target)
124
+ assert_equal(target, result)
125
+ end
126
+
127
+ def test_print_area_name_for_a_multiple_column
128
+ worksheet1 = @workbook.add_worksheet
129
+ area = 'A:H'
130
+
131
+ worksheet1.print_area(area)
132
+
133
+ # Test the EXTERNSHEET record.
134
+ @workbook.calculate_extern_sizes
135
+ @workbook.store_externsheet
136
+
137
+ target = [%w(
138
+ 17 00 08 00 01 00 00 00 00 00 00 00
139
+ ).join('')].pack('H*')
140
+
141
+ caption = " \tExternsheet"
142
+ result = _unpack_externsheet(@workbook.data)
143
+ target = _unpack_externsheet(target)
144
+ assert_equal(target, result)
145
+
146
+ # Test the NAME record.
147
+ @workbook.clear_data_for_test
148
+ @workbook.store_names
149
+
150
+ target = [%w(
151
+ 18 00 1B 00 20 00 00 01 0B 00 00 00 01 00 00 00
152
+ 00 00 00 06 3B 00 00 00 00 FF FF 00 00 07 00
153
+ ).join('')].pack('H*')
154
+
155
+ caption = " \t+ Name ( Sheet1!#{area} )";
156
+ result = _unpack_name(@workbook.data)
157
+ target = _unpack_name(target)
158
+ assert_equal(target, result)
159
+ end
160
+
161
+ def test_ranges_on_multiple_sheets
162
+ worksheet1 = @workbook.add_worksheet
163
+ worksheet2 = @workbook.add_worksheet
164
+ worksheet3 = @workbook.add_worksheet
165
+
166
+ worksheet1.print_area('A1:B2')
167
+ worksheet2.print_area('D4:E5')
168
+ worksheet3.print_area('G7:H8')
169
+
170
+ # Test the EXTERNSHEET record.
171
+ @workbook.calculate_extern_sizes
172
+ @workbook.store_externsheet
173
+
174
+ target = [%w(
175
+ 17 00 14 00 03 00 00 00 00 00 00 00 00 00 01 00
176
+ 01 00 00 00 02 00 02 00
177
+ ).join('')].pack('H*')
178
+
179
+ caption = " \tExternsheet"
180
+ result = _unpack_externsheet(@workbook.data)
181
+ target = _unpack_externsheet(target)
182
+ assert_equal(target, result)
183
+
184
+ # Test the NAME record.
185
+ @workbook.clear_data_for_test
186
+ @workbook.store_names
187
+
188
+ target = [%w(
189
+ 18 00 1B 00 20 00 00 01 0B 00 00 00 01 00 00 00
190
+ 00 00 00 06 3B 00 00 00 00 01 00 00 00 01 00
191
+
192
+ 18 00 1B 00 20 00 00 01 0B 00 00 00 02 00 00 00
193
+ 00 00 00 06 3B 01 00 03 00 04 00 03 00 04 00
194
+
195
+ 18 00 1B 00 20 00 00 01 0B 00 00 00 03 00 00 00
196
+ 00 00 00 06 3B 02 00 06 00 07 00 06 00 07 00
197
+ ).join('')].pack('H*')
198
+
199
+ caption = " \t+ Name ( Sheet1!A1:B2, Sheet2!D4:E5, Sheet3!G7:H8 )";
200
+ result = _unpack_name(@workbook.data)
201
+ target = _unpack_name(target)
202
+ assert_equal(target, result)
203
+ end
204
+
205
+ def test_ranges_on_multiple_sheets_with_sheets_spaced_out
206
+ worksheet1 = @workbook.add_worksheet
207
+ worksheet2 = @workbook.add_worksheet
208
+ worksheet3 = @workbook.add_worksheet
209
+ worksheet4 = @workbook.add_worksheet
210
+ worksheet5 = @workbook.add_worksheet
211
+
212
+ worksheet1.print_area('A1:B2')
213
+ worksheet3.print_area('D4:E5')
214
+ worksheet5.print_area('G7:H8')
215
+
216
+ # Test the EXTERNSHEET record.
217
+ @workbook.calculate_extern_sizes
218
+ @workbook.store_externsheet
219
+
220
+ target = [%w(
221
+ 17 00 14 00 03 00 00 00 00 00 00 00 00 00 02 00
222
+ 02 00 00 00 04 00 04 00
223
+ ).join('')].pack('H*')
224
+
225
+ caption = " \tExternsheet"
226
+ result = _unpack_externsheet(@workbook.data)
227
+ target = _unpack_externsheet(target)
228
+ assert_equal(target, result)
229
+
230
+ # Test the NAME record.
231
+ @workbook.clear_data_for_test
232
+ @workbook.store_names
233
+
234
+ target = [%w(
235
+ 18 00 1B 00 20 00 00 01 0B 00 00 00 01 00 00 00
236
+ 00 00 00 06 3B 00 00 00 00 01 00 00 00 01 00
237
+
238
+ 18 00 1B 00 20 00 00 01 0B 00 00 00 03 00 00 00
239
+ 00 00 00 06 3B 01 00 03 00 04 00 03 00 04 00
240
+
241
+ 18 00 1B 00 20 00 00 01 0B 00 00 00 05 00 00 00
242
+ 00 00 00 06 3B 02 00 06 00 07 00 06 00 07 00
243
+ ).join('')].pack('H*')
244
+
245
+ caption = " \t+ Name ( Sheet1!A1:B2, Sheet3!D4:E5, Sheet5!G7:H8 )";
246
+ result = _unpack_name(@workbook.data)
247
+ target = _unpack_name(target)
248
+ assert_equal(target, result)
249
+ end
250
+
251
+ ###############################################################################
252
+ #
253
+ # Unpack the binary data into a format suitable for printing in tests.
254
+ #
255
+ def unpack_record(data)
256
+ data.unpack('C*').map! {|c| sprintf("%02X", c) }.join(' ')
257
+ end
258
+
259
+ ###############################################################################
260
+ #
261
+ # _unpack_externsheet()
262
+ #
263
+ # Unpack the EXTERNSHEET recordfor easier comparison.
264
+ #
265
+ def _unpack_externsheet(data)
266
+ externsheet = Hash.new
267
+
268
+ externsheet['record'] = data[0, 2].unpack('v')[0]
269
+ data[0, 2] = ''
270
+ externsheet['length'] = data[0, 2].unpack('v')[0]
271
+ data[0, 2] = ''
272
+ externsheet['count'] = data[0, 2].unpack('v')[0]
273
+ data[0, 2] = ''
274
+ externsheet['array'] = [];
275
+
276
+ externsheet['count'].times do
277
+ externsheet['array'] << data[0, 6].unpack('vvv')
278
+ data[0, 6] = ''
279
+ end
280
+ externsheet
281
+ end
282
+
283
+ ###############################################################################
284
+ #
285
+ # _unpack_name()
286
+ #
287
+ # Unpack 1 or more NAME structures into a AoH for easier comparison.
288
+ #
289
+ def _unpack_name(data)
290
+ names = Array.new
291
+ while data.length > 0
292
+ name = Hash.new
293
+
294
+ name['record'] = data[0, 2].unpack('v')[0]
295
+ data[0, 2] = ''
296
+ name['length'] = data[0, 2].unpack('v')[0]
297
+ data[0, 2] = ''
298
+ name['flags'] = data[0, 2].unpack('v')[0]
299
+ data[0, 2] = ''
300
+ name['shortcut'] = data[0, 1].unpack('C')[0]
301
+ data[0, 1] = ''
302
+ name['str_len'] = data[0, 1].unpack('C')[0]
303
+ data[0, 1] = ''
304
+ name['formula_len'] = data[0, 2].unpack('v')[0]
305
+ data[0, 2] = ''
306
+ name['itals'] = data[0, 2].unpack('v')[0]
307
+ data[0, 2] = ''
308
+ name['sheet_index'] = data[0, 2].unpack('v')[0]
309
+ data[0, 2] = ''
310
+ name['menu_len'] = data[0, 1].unpack('C')[0]
311
+ data[0, 1] = ''
312
+ name['desc_len'] = data[0, 1].unpack('C')[0]
313
+ data[0, 1] = ''
314
+ name['help_len'] = data[0, 1].unpack('C')[0]
315
+ data[0, 1] = ''
316
+ name['status_len'] = data[0, 1].unpack('C')[0]
317
+ data[0, 1] = ''
318
+ name['encoding'] = data[0, 1].unpack('C')[0]
319
+ data[0, 1] = ''
320
+
321
+ # Decode the individual flag fields.
322
+ flag = Hash.new
323
+ flag['hidden'] = name['flags'] & 0x0001
324
+ flag['function'] = name['flags'] & 0x0002
325
+ flag['vb'] = name['flags'] & 0x0004
326
+ flag['macro'] = name['flags'] & 0x0008
327
+ flag['complex'] = name['flags'] & 0x0010
328
+ flag['builtin'] = name['flags'] & 0x0020
329
+ flag['group'] = name['flags'] & 0x0FC0
330
+ flag['binary'] = name['flags'] & 0x1000
331
+ name['flags'] = flag
332
+
333
+ # Decode the string part of the NAME structure.
334
+ if name['encoding'] == 1
335
+ # UTF-16 name. Leave in hex.
336
+ name['string'] = data[0, 2 * name['str_len']].unpack('H*')[0].upcase
337
+ data[0, 2 * name['str_len']] = ''
338
+ elsif flag['builtin'] != 0
339
+ # 1 digit builtin name. Leave in hex.
340
+ name['string'] = data[0, name['str_len']].unpack('H*')[0].upcase
341
+ data[0, name['str_len']] = ''
342
+ else
343
+ # ASCII name.
344
+ name['string'] = data[0, name['str_len']].unpack('C*').pack('C*')
345
+ data[0, name['str_len']] = ''
346
+ end
347
+
348
+ # Keep the formula as a hex string.
349
+ name['formula'] = data[0, name['formula_len']].unpack('H*')[0].upcase
350
+ data[0, name['formula_len']] = ''
351
+
352
+ names << name
353
+ end
354
+ names
355
+ end
356
+
357
+ def assert_hash_equal?(result, target)
358
+ assert_equal(result.keys.sort, target.keys.sort)
359
+ result.each_key do |key|
360
+ assert_equal(result[key], target[key])
361
+ end
362
+ end
363
+ end