writeexcel 0.3.5 → 0.4.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 (122) hide show
  1. data/.gitattributes +1 -0
  2. data/README.rdoc +12 -6
  3. data/VERSION +1 -1
  4. data/charts/chartex.rb +316 -315
  5. data/charts/demo1.rb +1 -0
  6. data/charts/demo2.rb +1 -0
  7. data/charts/demo3.rb +117 -116
  8. data/charts/demo4.rb +119 -118
  9. data/charts/demo5.rb +48 -47
  10. data/examples/a_simple.rb +1 -0
  11. data/examples/autofilter.rb +1 -0
  12. data/examples/bigfile.rb +30 -29
  13. data/examples/chart_area.rb +121 -120
  14. data/examples/chart_bar.rb +120 -119
  15. data/examples/chart_column.rb +120 -119
  16. data/examples/chart_line.rb +120 -119
  17. data/examples/chart_pie.rb +108 -107
  18. data/examples/chart_scatter.rb +121 -120
  19. data/examples/chart_stock.rb +148 -147
  20. data/examples/chess.rb +1 -0
  21. data/examples/colors.rb +1 -0
  22. data/examples/comments1.rb +1 -0
  23. data/examples/comments2.rb +3 -2
  24. data/examples/copyformat.rb +1 -0
  25. data/examples/data_validate.rb +1 -0
  26. data/examples/date_time.rb +1 -0
  27. data/examples/defined_name.rb +1 -0
  28. data/examples/demo.rb +1 -0
  29. data/examples/diag_border.rb +1 -0
  30. data/examples/formats.rb +1 -0
  31. data/examples/formula_result.rb +1 -0
  32. data/examples/header.rb +1 -0
  33. data/examples/hide_sheet.rb +1 -0
  34. data/examples/hyperlink.rb +1 -0
  35. data/examples/images.rb +1 -0
  36. data/examples/indent.rb +1 -0
  37. data/examples/merge1.rb +1 -0
  38. data/examples/merge2.rb +1 -0
  39. data/examples/merge3.rb +1 -0
  40. data/examples/merge4.rb +1 -0
  41. data/examples/merge5.rb +1 -0
  42. data/examples/merge6.rb +67 -66
  43. data/examples/outline.rb +1 -0
  44. data/examples/outline_collapsed.rb +1 -0
  45. data/examples/panes.rb +1 -0
  46. data/examples/properties.rb +1 -0
  47. data/examples/properties_jp.rb +1 -0
  48. data/examples/protection.rb +1 -0
  49. data/examples/regions.rb +1 -0
  50. data/examples/repeat.rb +1 -0
  51. data/examples/right_to_left.rb +1 -0
  52. data/examples/row_wrap.rb +1 -0
  53. data/examples/stats.rb +1 -0
  54. data/examples/stocks.rb +1 -0
  55. data/examples/tab_colors.rb +1 -0
  56. data/examples/write_arrays.rb +1 -0
  57. data/lib/writeexcel.rb +6 -1
  58. data/lib/writeexcel/biffwriter.rb +21 -20
  59. data/lib/writeexcel/chart.rb +25 -12
  60. data/lib/writeexcel/charts/area.rb +153 -152
  61. data/lib/writeexcel/charts/bar.rb +178 -177
  62. data/lib/writeexcel/charts/column.rb +157 -156
  63. data/lib/writeexcel/charts/external.rb +62 -61
  64. data/lib/writeexcel/charts/line.rb +153 -152
  65. data/lib/writeexcel/charts/pie.rb +170 -169
  66. data/lib/writeexcel/charts/scatter.rb +4 -3
  67. data/lib/writeexcel/charts/stock.rb +212 -211
  68. data/lib/writeexcel/compatibility.rb +320 -0
  69. data/lib/writeexcel/excelformulaparser.rb +587 -586
  70. data/lib/writeexcel/format.rb +12 -13
  71. data/lib/writeexcel/formula.rb +30 -28
  72. data/lib/writeexcel/helper.rb +23 -0
  73. data/lib/writeexcel/olewriter.rb +5 -16
  74. data/lib/writeexcel/properties.rb +43 -54
  75. data/lib/writeexcel/storage_lite.rb +981 -968
  76. data/lib/writeexcel/workbook.rb +94 -73
  77. data/lib/writeexcel/worksheet.rb +230 -210
  78. data/test/helper.rb +19 -0
  79. data/test/test_00_IEEE_double.rb +1 -0
  80. data/test/test_01_add_worksheet.rb +1 -0
  81. data/test/test_02_merge_formats.rb +3 -5
  82. data/test/test_04_dimensions.rb +3 -5
  83. data/test/test_05_rows.rb +6 -6
  84. data/test/test_06_extsst.rb +8 -8
  85. data/test/test_11_date_time.rb +3 -5
  86. data/test/test_12_date_only.rb +3 -5
  87. data/test/test_13_date_seconds.rb +4 -6
  88. data/test/test_21_escher.rb +3 -5
  89. data/test/test_22_mso_drawing_group.rb +20 -22
  90. data/test/test_23_note.rb +5 -7
  91. data/test/test_24_txo.rb +3 -5
  92. data/test/test_25_position_object.rb +84 -79
  93. data/test/test_26_autofilter.rb +3 -13
  94. data/test/test_27_autofilter.rb +3 -13
  95. data/test/test_28_autofilter.rb +3 -13
  96. data/test/test_29_process_jpg.rb +5 -0
  97. data/test/test_30_validation_dval.rb +3 -5
  98. data/test/test_31_validation_dv_strings.rb +3 -5
  99. data/test/test_32_validation_dv_formula.rb +3 -5
  100. data/test/test_40_property_types.rb +10 -9
  101. data/test/test_41_properties.rb +1 -0
  102. data/test/test_42_set_properties.rb +14 -15
  103. data/test/test_50_name_stored.rb +299 -302
  104. data/test/test_51_name_print_area.rb +357 -360
  105. data/test/test_52_name_print_titles.rb +454 -457
  106. data/test/test_53_autofilter.rb +203 -206
  107. data/test/test_60_chart_generic.rb +5 -0
  108. data/test/test_61_chart_subclasses.rb +95 -94
  109. data/test/test_62_chart_formats.rb +272 -267
  110. data/test/test_63_chart_area_formats.rb +649 -644
  111. data/test/test_biff.rb +12 -38
  112. data/test/test_compatibility.rb +627 -0
  113. data/test/test_example_match.rb +3 -18
  114. data/test/test_format.rb +46 -105
  115. data/test/test_formula.rb +1 -0
  116. data/test/test_ole.rb +3 -4
  117. data/test/test_storage_lite.rb +125 -146
  118. data/test/test_workbook.rb +2 -23
  119. data/test/test_worksheet.rb +4 -5
  120. data/utils/add_magic_comment.rb +80 -0
  121. data/writeexcel.gemspec +8 -2
  122. metadata +10 -4
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  ###############################################################################
2
3
  #
3
4
  # Worksheet - A writer class for Excel Worksheets.
@@ -29,12 +30,13 @@ class MaxSizeError < StandardError #:nodoc:
29
30
  # worksheet2 = workbook.add_worksheet
30
31
  #
31
32
  class Worksheet < BIFFWriter
33
+ require 'writeexcel/helper'
34
+ private :convert_to_ascii_if_ascii
32
35
 
33
36
  RowMax = 65536 # :nodoc:
34
37
  ColMax = 256 # :nodoc:
35
38
  StrMax = 0 # :nodoc:
36
39
  Buffer = 4096 # :nodoc:
37
- NonAscii = /[^!"#\$%&'\(\)\*\+,\-\.\/\:\;<=>\?@0-9A-Za-z_\[\\\]^` ~\0\n]/ # :nodoc:
38
40
 
39
41
  ###############################################################################
40
42
  #
@@ -190,9 +192,7 @@ def initialize(name, index, encoding, url_format, parser, tempdir,
190
192
  # Add data to the beginning of the workbook (note the reverse order)
191
193
  # and to the end of the workbook.
192
194
  #
193
- def close(*sheetnames) #:nodoc:
194
- num_sheets = sheetnames.size
195
-
195
+ def close #:nodoc:
196
196
  ################################################
197
197
  # Prepend in reverse order!!
198
198
  #
@@ -303,6 +303,10 @@ def close(*sheetnames) #:nodoc:
303
303
  store_bof(0x0010)
304
304
  end
305
305
 
306
+ def cleanup
307
+ super
308
+ end
309
+
306
310
  ###############################################################################
307
311
  #
308
312
  # _compatibility_mode()
@@ -452,8 +456,8 @@ def set_first_sheet
452
456
  # itself. In Excel a cell's locked property is on by default.
453
457
  #
454
458
  # # Set some format properties
455
- # unlocked = workbook.add_format(locked => 0)
456
- # hidden = workbook.add_format(hidden => 1)
459
+ # unlocked = workbook.add_format(:locked => 0)
460
+ # hidden = workbook.add_format(:hidden => 1)
457
461
  #
458
462
  # # Enable worksheet protection
459
463
  # worksheet.protect
@@ -1653,15 +1657,17 @@ def set_margin_bottom(margin = 1.00)
1653
1657
  # distribution.
1654
1658
  #
1655
1659
  def set_header(string = '', margin = 0.50, encoding = 0)
1660
+ string = convert_to_ascii_if_ascii(string)
1661
+
1656
1662
  limit = encoding != 0 ? 255 *2 : 255
1657
1663
 
1658
1664
  # Handle utf8 strings
1659
- if string =~ NonAscii
1660
- string = NKF.nkf('-w16B0 -m0 -W', string)
1665
+ if string.encoding == Encoding::UTF_8
1666
+ string = string.encode('UTF-16BE')
1661
1667
  encoding = 1
1662
1668
  end
1663
1669
 
1664
- if string.length >= limit
1670
+ if string.bytesize >= limit
1665
1671
  # carp 'Header string must be less than 255 characters';
1666
1672
  return
1667
1673
  end
@@ -1678,15 +1684,17 @@ def set_header(string = '', margin = 0.50, encoding = 0)
1678
1684
  # there.
1679
1685
  #
1680
1686
  def set_footer(string = '', margin = 0.50, encoding = 0)
1687
+ string = convert_to_ascii_if_ascii(string)
1688
+
1681
1689
  limit = encoding != 0 ? 255 *2 : 255
1682
1690
 
1683
1691
  # Handle utf8 strings
1684
- if string =~ NonAscii
1685
- string = NKF.nkf('-w16B0 -m0 -W', string)
1692
+ if string.encoding == Encoding::UTF_8
1693
+ string = string.encode('UTF-16BE')
1686
1694
  encoding = 1
1687
1695
  end
1688
1696
 
1689
- if string.length >= limit
1697
+ if string.bytesize >= limit
1690
1698
  # carp 'Header string must be less than 255 characters';
1691
1699
  return
1692
1700
  end
@@ -2048,7 +2056,7 @@ def extract_filter_tokens(expression = nil) #:nodoc:
2048
2056
  end
2049
2057
  end
2050
2058
 
2051
- return tokens
2059
+ tokens
2052
2060
  end
2053
2061
  # private :extract_filter_tokens
2054
2062
 
@@ -2133,7 +2141,7 @@ def parse_filter_tokens(expression, tokens) #:nodoc:
2133
2141
  end
2134
2142
 
2135
2143
  if (tokens[2] == '%')
2136
- operator = operator + 1
2144
+ operator += 1
2137
2145
  end
2138
2146
 
2139
2147
  token = value
@@ -2175,7 +2183,7 @@ def parse_filter_tokens(expression, tokens) #:nodoc:
2175
2183
  operator = 22
2176
2184
  end
2177
2185
 
2178
- return [operator, token]
2186
+ [operator, token]
2179
2187
  end
2180
2188
  private :parse_filter_tokens
2181
2189
 
@@ -2205,8 +2213,8 @@ def parse_filter_tokens(expression, tokens) #:nodoc:
2205
2213
  # worksheet.write('A1', '01209')
2206
2214
  #
2207
2215
  # # Write a zero padded number using a format: 01209
2208
- # my $format1 = $workbook.add_format(num_format => '00000')
2209
- # $worksheet.write('A2', '01209', $format1)
2216
+ # my $format1 = $workbook.add_format(:num_format => '00000')
2217
+ # $worksheet.write('A2', '01209', format1)
2210
2218
  #
2211
2219
  # # Write explicitly as a string: 01209
2212
2220
  # $worksheet.write_string('A3', '01209')
@@ -2235,8 +2243,8 @@ def parse_filter_tokens(expression, tokens) #:nodoc:
2235
2243
  # behaviour. To avoid this you can use the text format @:
2236
2244
  #
2237
2245
  # # Format as a string (01209)
2238
- # format2 = workbook.add_format(num_format => '@')
2239
- # worksheet.write_string('A5', '01209', $format2)
2246
+ # format2 = workbook.add_format(:num_format => '@')
2247
+ # worksheet.write_string('A5', '01209', format2)
2240
2248
  #
2241
2249
  # The keep_leading_zeros() property is off by default. The keep
2242
2250
  #_leading_zeros() method takes 0 or 1 as an argument. It defaults to 1 if
@@ -2264,12 +2272,12 @@ def keep_leading_zeros(val = true)
2264
2272
  # Individual comments can be made visible using the visible parameter of the
2265
2273
  # write_comment method (see above):
2266
2274
  #
2267
- # worksheet.write_comment('C3', 'Hello', visible => 1)
2275
+ # worksheet.write_comment('C3', 'Hello', :visible => 1)
2268
2276
  #
2269
2277
  # If all of the cell comments have been made visible you can hide individual
2270
2278
  # comments as follows:
2271
2279
  #
2272
- # worksheet.write_comment('C3', 'Hello', visible => 0)
2280
+ # worksheet.write_comment('C3', 'Hello', :visible => 0)
2273
2281
  #
2274
2282
  #
2275
2283
  def show_comments(val = nil)
@@ -2628,7 +2636,7 @@ def write_number(*args)
2628
2636
  append(header, data, xl_double)
2629
2637
  end
2630
2638
 
2631
- return 0
2639
+ 0
2632
2640
  end
2633
2641
 
2634
2642
  #
@@ -2669,7 +2677,7 @@ def write_number(*args)
2669
2677
  # number. To get around this you can use the Excel text format @:
2670
2678
  #
2671
2679
  # # Format as a string. Doesn't change to a number when edited
2672
- # format1 = workbook.add_format(num_format => '@')
2680
+ # format1 = workbook.add_format(:num_format => '@')
2673
2681
  # worksheet.write_string('A2', '01209', format1)
2674
2682
  #
2675
2683
  def write_string(*args)
@@ -2686,14 +2694,18 @@ def write_string(*args)
2686
2694
  row = args[0] # Zero indexed row
2687
2695
  col = args[1] # Zero indexed column
2688
2696
  str = args[2].to_s
2689
- strlen = str.length
2697
+ strlen = str.bytesize
2690
2698
  xf = xf_record_index(row, col, args[3]) # The cell format
2691
2699
  encoding = 0x0
2692
2700
  str_error = 0
2693
2701
 
2702
+ str = convert_to_ascii_if_ascii(str)
2703
+
2694
2704
  # Handle utf8 strings
2695
- if str =~ NonAscii
2696
- return write_utf16le_string(row, col, NKF.nkf('-w16L0 -m0 -W', str), args[3])
2705
+ if str.encoding == Encoding::UTF_8
2706
+ str_utf16le = NKF.nkf('-w16L0 -m0 -W', str)
2707
+ str_utf16le.force_encoding('UTF-16LE')
2708
+ return write_utf16le_string(row, col, str_utf16le, args[3])
2697
2709
  end
2698
2710
 
2699
2711
  # Check that row and col are valid and store max and min values
@@ -2729,7 +2741,7 @@ def write_string(*args)
2729
2741
  append(header, data)
2730
2742
  end
2731
2743
 
2732
- return str_error
2744
+ str_error
2733
2745
  end
2734
2746
 
2735
2747
  #
@@ -2802,7 +2814,7 @@ def write_blank(*args)
2802
2814
  append(header, data)
2803
2815
  end
2804
2816
 
2805
- return 0
2817
+ 0
2806
2818
  end
2807
2819
 
2808
2820
  #
@@ -3131,7 +3143,7 @@ def write_formula(*args)
3131
3143
  # croak $@ # Re-raise the error
3132
3144
  # }
3133
3145
 
3134
- formlen = formula.length # Length of the binary string
3146
+ formlen = formula.bytesize # Length of the binary string
3135
3147
  length = 0x16 + formlen # Length of the record data
3136
3148
 
3137
3149
  header = [record, length].pack("vv")
@@ -3153,7 +3165,7 @@ def write_formula(*args)
3153
3165
  append(header, data, formula, string)
3154
3166
  end
3155
3167
 
3156
- return 0
3168
+ 0
3157
3169
  end
3158
3170
 
3159
3171
  #
@@ -3258,7 +3270,7 @@ def write_row(*args)
3258
3270
  col += 1
3259
3271
  end
3260
3272
  end
3261
- return error
3273
+ error
3262
3274
  end
3263
3275
 
3264
3276
 
@@ -3358,7 +3370,7 @@ def write_col(*args)
3358
3370
  row += 1
3359
3371
  end
3360
3372
  end
3361
- return error
3373
+ error
3362
3374
  end
3363
3375
 
3364
3376
  #
@@ -3398,7 +3410,7 @@ def write_col(*args)
3398
3410
  # several optional key/value pairs to control the format of the comment.
3399
3411
  # For example:
3400
3412
  #
3401
- # worksheet.write_comment('C3', 'Hello', visible => 1, author => 'Ruby')
3413
+ # worksheet.write_comment('C3', 'Hello', :visible => 1, :author => 'Ruby')
3402
3414
  #
3403
3415
  # Most of these options are quite specific and in general the default comment
3404
3416
  # behaviour will be all that you need. However, should you need greater
@@ -3770,15 +3782,15 @@ def cell_to_rowcol(cell) #:nodoc:
3770
3782
 
3771
3783
  while (!chars.empty?)
3772
3784
  char = chars.pop # LS char first
3773
- col = col + (char[0] - "A"[0] +1) * (26**expn)
3774
- expn = expn + 1
3785
+ col += (char.ord - "A".ord + 1) * (26 ** expn)
3786
+ expn += 1
3775
3787
  end
3776
3788
 
3777
3789
  # Convert 1-index to zero-index
3778
3790
  row -= 1
3779
3791
  col -= 1
3780
3792
 
3781
- return [row, col]
3793
+ [row, col]
3782
3794
  end
3783
3795
  private :cell_to_rowcol
3784
3796
 
@@ -3878,7 +3890,7 @@ def encode_formula_result(value = nil) #:nodoc:
3878
3890
  end
3879
3891
  end
3880
3892
 
3881
- return [num, grbit, is_string]
3893
+ [num, grbit, is_string]
3882
3894
  end
3883
3895
  private :encode_formula_result
3884
3896
 
@@ -3890,24 +3902,26 @@ def encode_formula_result(value = nil) #:nodoc:
3890
3902
  # be calculated by the module and thus must be supplied by the user.
3891
3903
  #
3892
3904
  def get_formula_string(string) #:nodoc:
3905
+ string = convert_to_ascii_if_ascii(string)
3906
+
3893
3907
  record = 0x0207 # Record identifier
3894
3908
  length = 0x00 # Bytes to follow
3895
3909
  # string # Formula string.
3896
- strlen = string.length # Length of the formula string (chars).
3910
+ strlen = string.bytesize # Length of the formula string (chars).
3897
3911
  encoding = 0 # String encoding.
3898
3912
 
3899
- # Handle utf8 strings in perl 5.8.
3900
- if string =~ NonAscii
3901
- string = NKF.nkf('-w16B0 -m0 -W', string)
3913
+ # Handle utf8 strings.
3914
+ if string.encoding == Encoding::UTF_8
3915
+ string = string.encode('UTF-16BE')
3902
3916
  encoding = 1
3903
3917
  end
3904
3918
 
3905
- length = 0x03 + string.length # Length of the record data
3919
+ length = 0x03 + string.bytesize # Length of the record data
3906
3920
 
3907
3921
  header = [record, length].pack("vv")
3908
3922
  data = [strlen, encoding].pack("vC")
3909
3923
 
3910
- return header + data + string
3924
+ header + data + string
3911
3925
  end
3912
3926
  private :get_formula_string
3913
3927
 
@@ -3963,13 +3977,13 @@ def store_formula(formula) #:nodoc:
3963
3977
  # }
3964
3978
 
3965
3979
  # Return the parsed tokens in an anonymous array
3966
- return [*tokens]
3980
+ [*tokens]
3967
3981
  end
3968
3982
 
3969
3983
  #
3970
3984
  # :call-seq:
3971
- # repeat_formula(row, col, formula, format, ([pattern => replace, ...]) -> Fixnum
3972
- # repeat_formula(A1_notation, formula, format, ([pattern => replace, ...]) -> Fixnum
3985
+ # repeat_formula(row, col, formula, format, ([:pattern => replace, ...]) -> Fixnum
3986
+ # repeat_formula(A1_notation, formula, format, ([:pattern => replace, ...]) -> Fixnum
3973
3987
  #
3974
3988
  # Write a formula to the specified row and column (zero indexed) by
3975
3989
  # substituting _pattern_ _replacement_ pairs in the formula created via
@@ -4121,7 +4135,7 @@ def repeat_formula(*args) #:nodoc:
4121
4135
 
4122
4136
 
4123
4137
  # As a temporary and undocumented measure we allow the user to specify the
4124
- # result of the formula by appending a result => $value pair to the end
4138
+ # result of the formula by appending a result => value pair to the end
4125
4139
  # of the arguments.
4126
4140
  value = nil
4127
4141
  if pairs[-2] == 'result'
@@ -4162,7 +4176,7 @@ def repeat_formula(*args) #:nodoc:
4162
4176
  return -2 if check_dimensions(row, col) != 0
4163
4177
 
4164
4178
 
4165
- formlen = formula.length # Length of the binary string
4179
+ formlen = formula.bytesize # Length of the binary string
4166
4180
  length = 0x16 + formlen # Length of the record data
4167
4181
 
4168
4182
  header = [record, length].pack("vv")
@@ -4185,7 +4199,7 @@ def repeat_formula(*args) #:nodoc:
4185
4199
  append(header, data, formula, string)
4186
4200
  end
4187
4201
 
4188
- return 0
4202
+ 0
4189
4203
  end
4190
4204
 
4191
4205
  #
@@ -4282,7 +4296,7 @@ def write_url(*args)
4282
4296
  return -1 if args.size < 3
4283
4297
 
4284
4298
  # Add start row and col to arg list
4285
- return write_url_range(args[0], args[1], *args)
4299
+ write_url_range(args[0], args[1], *args)
4286
4300
  end
4287
4301
 
4288
4302
  #
@@ -4338,7 +4352,7 @@ def write_url_range(*args)
4338
4352
  # Check for internal/external sheet links or default to web link
4339
4353
  return write_url_internal(*args) if url =~ /^internal:/
4340
4354
  return write_url_external(*args) if url =~ /^external:/
4341
- return write_url_web(*args)
4355
+ write_url_web(*args)
4342
4356
  end
4343
4357
 
4344
4358
  ###############################################################################
@@ -4358,6 +4372,8 @@ def write_url_range(*args)
4358
4372
  # See also write_url() above for a general description and return values.
4359
4373
  #
4360
4374
  def write_url_web(row1, col1, row2, col2, url, str = nil, format = nil) #:nodoc:
4375
+ url = convert_to_ascii_if_ascii(url)
4376
+
4361
4377
  record = 0x01B8 # Record identifier
4362
4378
  length = 0x00000 # Bytes to follow
4363
4379
 
@@ -4381,23 +4397,23 @@ def write_url_web(row1, col1, row2, col2, url, str = nil, format = nil) #:
4381
4397
  encoding = 0
4382
4398
 
4383
4399
  # Convert an Utf8 URL type and to a null terminated wchar string.
4384
- if url =~ NonAscii
4385
- url = NKF.nkf('-w16B0 -m0 -W', url)
4386
- url += "\0\0" # URL is null terminated.
4400
+ if url.encoding == Encoding::UTF_8
4401
+ url = url.encode('UTF-16BE')
4402
+ url += "\0\0".force_encoding('UTF-16BE') # URL is null terminated.
4387
4403
  encoding = 1
4388
4404
  end
4389
4405
 
4390
4406
  # Convert an Ascii URL type and to a null terminated wchar string.
4391
4407
  if encoding == 0
4392
- url += "\0"
4408
+ url = url.force_encoding('BINARY') + "\0".force_encoding('BINARY')
4393
4409
  url = url.unpack('c*').pack('v*')
4394
4410
  end
4395
4411
 
4396
4412
  # Pack the length of the URL
4397
- url_len = [url.length].pack("V")
4413
+ url_len = [url.bytesize].pack("V")
4398
4414
 
4399
4415
  # Calculate the data length
4400
- length = 0x34 + url.length
4416
+ length = 0x34 + url.bytesize
4401
4417
 
4402
4418
  # Pack the header data
4403
4419
  header = [record, length].pack("vv")
@@ -4407,7 +4423,7 @@ def write_url_web(row1, col1, row2, col2, url, str = nil, format = nil) #:
4407
4423
  print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
4408
4424
  append( header, data,unknown1,options,unknown2,url_len,url)
4409
4425
 
4410
- return error
4426
+ error
4411
4427
  end
4412
4428
  private :write_url_web
4413
4429
 
@@ -4451,16 +4467,16 @@ def write_url_internal(row1, col1, row2, col2, url, str = nil, format = nil)
4451
4467
  encoding = 0
4452
4468
 
4453
4469
  # Convert an Utf8 URL type and to a null terminated wchar string.
4454
- if str =~ NonAscii
4470
+ if str.encoding == Encoding::UTF_8
4455
4471
  # Quote sheet name if not already, i.e., Sheet!A1 to 'Sheet!A1'.
4456
4472
  url.sub!(/^(.+)!/, "'\1'!") if not url =~ /^'/;
4457
- url = NKF.nkf('-w16L0 -m0 -W', url) + "\0\0" # URL is null terminated.
4473
+ url = url.encode('UTF-16LE') + "\0\0" # URL is null terminated.
4458
4474
  encoding = 1
4459
4475
  end
4460
4476
 
4461
4477
  # Convert an Ascii URL type and to a null terminated wchar string.
4462
4478
  if encoding == 0
4463
- url = url + "\0"
4479
+ url += "\0"
4464
4480
  url = url.unpack('c*').pack('v*')
4465
4481
  end
4466
4482
 
@@ -4468,7 +4484,7 @@ def write_url_internal(row1, col1, row2, col2, url, str = nil, format = nil)
4468
4484
  url_len = [(url.length/2).to_i].pack("V")
4469
4485
 
4470
4486
  # Calculate the data length
4471
- length = 0x24 + url.length
4487
+ length = 0x24 + url.bytesize
4472
4488
 
4473
4489
  # Pack the header data
4474
4490
  header = [record, length].pack("vv")
@@ -4478,7 +4494,7 @@ def write_url_internal(row1, col1, row2, col2, url, str = nil, format = nil)
4478
4494
  print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
4479
4495
  append( header, data, unknown1, options, url_len, url)
4480
4496
 
4481
- return error
4497
+ error
4482
4498
  end
4483
4499
  private :write_url_internal
4484
4500
 
@@ -4535,7 +4551,7 @@ def write_url_external(row1, col1, row2, col2, url, str = nil, format = nil)
4535
4551
 
4536
4552
  unless sheet.nil?
4537
4553
  link_type |= 0x08
4538
- sheet_len = [sheet.length + 0x01].pack("V")
4554
+ sheet_len = [sheet.bytesize + 0x01].pack("V")
4539
4555
  sheet = sheet.split('').join("\0") + "\0\0\0"
4540
4556
  else
4541
4557
  sheet_len = ''
@@ -4548,7 +4564,7 @@ def write_url_external(row1, col1, row2, col2, url, str = nil, format = nil)
4548
4564
  # Calculate the up-level dir count e.g. (..\..\..\ == 3)
4549
4565
  up_count = 0
4550
4566
  while dir_long.sub!(/^\.\.\\/, '')
4551
- up_count = up_count + 1
4567
+ up_count += 1
4552
4568
  end
4553
4569
  up_count = [up_count].pack("v")
4554
4570
 
@@ -4559,9 +4575,9 @@ def write_url_external(row1, col1, row2, col2, url, str = nil, format = nil)
4559
4575
  dir_long = dir_long.split('').join("\0") + "\0"
4560
4576
 
4561
4577
  # Pack the lengths of the dir strings
4562
- dir_short_len = [dir_short.length].pack("V")
4563
- dir_long_len = [dir_long.length].pack("V")
4564
- stream_len = [dir_long.length + 0x06].pack("V")
4578
+ dir_short_len = [dir_short.bytesize].pack("V")
4579
+ dir_long_len = [dir_long.bytesize].pack("V")
4580
+ stream_len = [dir_long.bytesize + 0x06].pack("V")
4565
4581
 
4566
4582
  # Pack the undocumented parts of the hyperlink stream
4567
4583
  unknown1 = ['D0C9EA79F9BACE118C8200AA004BA90B02000000'].pack("H*")
@@ -4586,14 +4602,14 @@ def write_url_external(row1, col1, row2, col2, url, str = nil, format = nil)
4586
4602
  sheet
4587
4603
 
4588
4604
  # Pack the header data
4589
- length = data.length
4605
+ length = data.bytesize
4590
4606
  header = [record, length].pack("vv")
4591
4607
 
4592
4608
  # Write the packed data
4593
4609
  print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
4594
4610
  append(header, data)
4595
4611
 
4596
- return error
4612
+ error
4597
4613
  end
4598
4614
  private :write_url_external
4599
4615
 
@@ -4633,7 +4649,7 @@ def write_url_external_net(row1, col1, row2, col2, url, str, format) #:nod
4633
4649
 
4634
4650
  unless sheet.nil?
4635
4651
  link_type |= 0x08
4636
- sheet_len = [sheet.length + 0x01].pack("V")
4652
+ sheet_len = [sheet.bytesize + 0x01].pack("V")
4637
4653
  sheet = sheet.split('').join("\0") + "\0\0\0"
4638
4654
  else
4639
4655
  sheet_len = ''
@@ -4645,10 +4661,10 @@ def write_url_external_net(row1, col1, row2, col2, url, str, format) #:nod
4645
4661
 
4646
4662
 
4647
4663
  # Make the string null terminated
4648
- dir_long = dir_long + "\0"
4664
+ dir_long += "\0"
4649
4665
 
4650
4666
  # Pack the lengths of the dir string
4651
- dir_long_len = [dir_long.length].pack("V")
4667
+ dir_long_len = [dir_long.bytesize].pack("V")
4652
4668
 
4653
4669
  # Store the long dir name as a wchar string (non-null terminated)
4654
4670
  dir_long = dir_long.split('').join("\0") + "\0"
@@ -4666,14 +4682,14 @@ def write_url_external_net(row1, col1, row2, col2, url, str, format) #:nod
4666
4682
  sheet
4667
4683
 
4668
4684
  # Pack the header data
4669
- length = data.length
4685
+ length = data.bytesize
4670
4686
  header = [record, length].pack("vv")
4671
4687
 
4672
4688
  # Write the packed data
4673
4689
  print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
4674
4690
  append(header, data)
4675
4691
 
4676
- return error
4692
+ error
4677
4693
  end
4678
4694
  private :write_url_external_net
4679
4695
 
@@ -4751,7 +4767,7 @@ def write_date_time(*args)
4751
4767
  write_string(row, col, str, args[3])
4752
4768
  error = -3
4753
4769
  end
4754
- return error
4770
+ error
4755
4771
  end
4756
4772
 
4757
4773
  #
@@ -4868,9 +4884,9 @@ def convert_date_time(date_time_string) #:nodoc:
4868
4884
  days -= leap # Already counted above
4869
4885
 
4870
4886
  # Adjust for Excel erroneously treating 1900 as a leap year.
4871
- days = days + 1 if !@date_1904 and days > 59
4887
+ days += 1 if !@date_1904 and days > 59
4872
4888
 
4873
- return days + seconds
4889
+ days + seconds
4874
4890
  end
4875
4891
 
4876
4892
  ###############################################################################
@@ -4941,7 +4957,7 @@ def check_dimensions(row, col, ignore_row = 0, ignore_col = 0) #:nodoc:
4941
4957
  end
4942
4958
  end
4943
4959
 
4944
- return 0
4960
+ 0
4945
4961
  end
4946
4962
  private :check_dimensions
4947
4963
 
@@ -5318,8 +5334,8 @@ def store_externsheet(sheetname) #:nodoc:
5318
5334
  cch = 1 # The following byte
5319
5335
  rgch = 0x02 # Self reference
5320
5336
  else
5321
- length = 0x02 + sheetname.length
5322
- cch = sheetname.length
5337
+ length = 0x02 + sheetname.bytesize
5338
+ cch = sheetname.bytesize
5323
5339
  rgch = 0x03 # Reference to a sheet in the current workbook
5324
5340
  end
5325
5341
 
@@ -5464,7 +5480,7 @@ def store_header #:nodoc:
5464
5480
  # length # Bytes to follow
5465
5481
 
5466
5482
  str = @header # header string
5467
- cch = str.length # Length of header string
5483
+ cch = str.bytesize # Length of header string
5468
5484
  encoding = @header_encoding # Character encoding
5469
5485
 
5470
5486
 
@@ -5474,7 +5490,7 @@ def store_header #:nodoc:
5474
5490
  # Change the UTF-16 name from BE to LE
5475
5491
  str = str.unpack('v*').pack('n*') if encoding != 0
5476
5492
 
5477
- length = 3 + str.length
5493
+ length = 3 + str.bytesize
5478
5494
 
5479
5495
  header = [record, length].pack('vv')
5480
5496
  data = [cch, encoding].pack('vC')
@@ -5495,7 +5511,7 @@ def store_footer #:nodoc:
5495
5511
  # length; # Bytes to follow
5496
5512
 
5497
5513
  str = @footer # footer string
5498
- cch = str.length # Length of ooter string
5514
+ cch = str.bytesize # Length of ooter string
5499
5515
  encoding = @footer_encoding # Character encoding
5500
5516
 
5501
5517
 
@@ -5505,7 +5521,7 @@ def store_footer #:nodoc:
5505
5521
  # Change the UTF-16 name from BE to LE
5506
5522
  str = str.unpack('v*').pack('n*') if encoding != 0
5507
5523
 
5508
- length = 3 + str.length
5524
+ length = 3 + str.bytesize
5509
5525
 
5510
5526
  header = [record, length].pack('vv')
5511
5527
  data = [cch, encoding].pack('vC')
@@ -5838,7 +5854,7 @@ def store_hbreak #:nodoc:
5838
5854
 
5839
5855
  # Append each page break
5840
5856
  breaks.each do |brk|
5841
- data = data + [brk, 0x0000, 0x00ff].pack("vvv")
5857
+ data += [brk, 0x0000, 0x00ff].pack("vvv")
5842
5858
  end
5843
5859
 
5844
5860
  print "sheet #{@name} : #{__FILE__}(#{__LINE__})\n" if defined?($debug)
@@ -5868,7 +5884,7 @@ def store_vbreak #:nodoc:
5868
5884
 
5869
5885
  # Append each page break
5870
5886
  breaks.each do |brk|
5871
- data = data + [brk, 0x0000, 0x00ff].pack("vvv")
5887
+ data += [brk, 0x0000, 0x00ff].pack("vvv")
5872
5888
  end
5873
5889
 
5874
5890
  print "sheet #{@name} : #{__FILE__}(#{__LINE__})\n" if defined?($debug)
@@ -6026,15 +6042,15 @@ def store_table #:nodoc:
6026
6042
  # Write the cell data in each row and sum their lengths for the
6027
6043
  # cell offsets.
6028
6044
  #
6029
- written_rows.each do |row|
6045
+ written_rows.each do |rw|
6030
6046
  cell_offset = 0
6031
6047
 
6032
- if @table[row]
6033
- @table[row].each do |col|
6034
- next unless col
6048
+ if @table[rw]
6049
+ @table[rw].each do |clm|
6050
+ next unless clm
6035
6051
  print "sheet #{@name} : #{__FILE__}(#{__LINE__}) cell_data\n" if defined?($debug)
6036
- append(col)
6037
- length = col.length
6052
+ append(clm)
6053
+ length = clm.bytesize
6038
6054
  row_offset += length
6039
6055
  cell_offset += length
6040
6056
  end
@@ -6075,7 +6091,7 @@ def store_dbcell(row_offset, cell_offsets) #:nodoc:
6075
6091
  header = [record, length].pack('vv')
6076
6092
  data = [row_offset].pack('V')
6077
6093
  cell_offsets.each do |co|
6078
- data = data + [co].pack('v')
6094
+ data += [co].pack('v')
6079
6095
  end
6080
6096
 
6081
6097
  print "sheet #{@name} : #{__FILE__}(#{__LINE__})\n" if defined?($debug)
@@ -6106,7 +6122,7 @@ def store_index #:nodoc:
6106
6122
  data = [reserved, row_min, row_max, reserved].pack('VVVV')
6107
6123
 
6108
6124
  indices.each do |index|
6109
- data = data + [index + @offset + 20 + length + 4].pack('V')
6125
+ data += [index + @offset + 20 + length + 4].pack('V')
6110
6126
  end
6111
6127
 
6112
6128
  print "sheet #{@name} : #{__FILE__}(#{__LINE__})\n" if defined?($debug)
@@ -6344,22 +6360,22 @@ def position_object(col_start, row_start, x1, y1, width, height) #:nodoc:
6344
6360
 
6345
6361
  # Adjust start column for offsets that are greater than the col width
6346
6362
  while x1 >= size_col(col_start)
6347
- x1 = x1 - size_col(col_start)
6348
- col_start = col_start + 1
6363
+ x1 -= size_col(col_start)
6364
+ col_start += 1
6349
6365
  end
6350
6366
 
6351
6367
  # Adjust start row for offsets that are greater than the row height
6352
6368
  while y1 >= size_row(row_start)
6353
- y1 = y1 - size_row(row_start)
6354
- row_start = row_start + 1
6369
+ y1 -= size_row(row_start)
6370
+ row_start += 1
6355
6371
  end
6356
6372
 
6357
6373
  # Initialise end cell to the same as the start cell
6358
6374
  col_end = col_start
6359
6375
  row_end = row_start
6360
6376
 
6361
- width = width + x1
6362
- height = height + y1
6377
+ width += x1
6378
+ height += y1
6363
6379
 
6364
6380
  # Subtract the underlying cell widths to find the end cell of the image
6365
6381
  while width >= size_col(col_end)
@@ -6393,7 +6409,7 @@ def position_object(col_start, row_start, x1, y1, width, height) #:nodoc:
6393
6409
  x2 = (x2 +0.5).to_i
6394
6410
  y2 = (y2 +0.5).to_i
6395
6411
 
6396
- return [
6412
+ [
6397
6413
  col_start, x1,
6398
6414
  row_start, y1,
6399
6415
  col_end, x2,
@@ -6496,7 +6512,7 @@ def write_utf16be_string(*args)
6496
6512
 
6497
6513
  row = args[0] # Zero indexed row
6498
6514
  col = args[1] # Zero indexed column
6499
- strlen = args[2].length
6515
+ strlen = args[2].bytesize
6500
6516
  str = args[2]
6501
6517
  xf = xf_record_index(row, col, args[3]) # The cell format
6502
6518
  encoding = 0x1
@@ -6511,7 +6527,7 @@ def write_utf16be_string(*args)
6511
6527
  str_error = -3
6512
6528
  end
6513
6529
 
6514
- num_bytes = str.length
6530
+ num_bytes = str.bytesize
6515
6531
  num_chars = (num_bytes / 2).to_i
6516
6532
 
6517
6533
  # Check for a valid 2-byte char string.
@@ -6544,7 +6560,7 @@ def write_utf16be_string(*args)
6544
6560
  append(header, data)
6545
6561
  end
6546
6562
 
6547
- return str_error
6563
+ str_error
6548
6564
  end
6549
6565
 
6550
6566
  ###############################################################################
@@ -6577,7 +6593,7 @@ def write_utf16le_string(*args)
6577
6593
  # Change from UTF16 big-endian to little endian
6578
6594
  str = str.unpack('n*').pack("v*")
6579
6595
 
6580
- return write_utf16be_string(row, col, str, format)
6596
+ write_utf16be_string(row, col, str, format)
6581
6597
  end
6582
6598
 
6583
6599
 
@@ -6694,10 +6710,10 @@ def store_autofilter(index, operator_1, token_1, #:nodoc:
6694
6710
  string_2 = '' if string_2.nil?
6695
6711
 
6696
6712
  data = [index].pack('v')
6697
- data = data + [grbit].pack('v')
6698
- data = data + doper_1 + doper_2 + string_1 + string_2
6713
+ data += [grbit].pack('v')
6714
+ data += doper_1 + doper_2 + string_1 + string_2
6699
6715
 
6700
- length = data.length
6716
+ length = data.bytesize
6701
6717
  header = [record, length].pack('vv')
6702
6718
 
6703
6719
  print "sheet #{@name} : #{__FILE__}(#{__LINE__})\n" if defined?($debug)
@@ -6727,24 +6743,25 @@ def pack_doper(operator, token) #:nodoc:
6727
6743
  !(token.to_s =~ /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/)
6728
6744
  # Excel treats all tokens as strings if the operator is equality, =.
6729
6745
  string = token.to_s
6746
+ string = convert_to_ascii_if_ascii(string)
6730
6747
 
6731
6748
  encoding = 0
6732
- length = string.length
6749
+ length = string.bytesize
6733
6750
 
6734
6751
  # Handle utf8 strings
6735
- if string =~ NonAscii
6736
- string = NKF.nkf('-w16B0 -m0 -W', string)
6752
+ if string.encoding == Encoding::UTF_8
6753
+ string = string.encode('UTF-16BE')
6737
6754
  encodign = 1
6738
6755
  end
6739
6756
 
6740
- string = [encoding].pack('C') + string
6757
+ string = [encoding].pack('C') + string.force_encoding('BINARY')
6741
6758
  doper = pack_string_doper(operator, length)
6742
6759
  else
6743
6760
  string = ''
6744
6761
  doper = pack_number_doper(operator, token)
6745
6762
  end
6746
6763
 
6747
- return [doper, string]
6764
+ [doper, string]
6748
6765
  end
6749
6766
  private :pack_doper
6750
6767
 
@@ -6755,7 +6772,7 @@ def pack_doper(operator, token) #:nodoc:
6755
6772
  # Pack an empty Doper structure.
6756
6773
  #
6757
6774
  def pack_unused_doper #:nodoc:
6758
- return [0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0].pack('C10')
6775
+ [0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0].pack('C10')
6759
6776
  end
6760
6777
  private :pack_unused_doper
6761
6778
 
@@ -6774,11 +6791,10 @@ def pack_blanks_doper(operator, token) #:nodoc:
6774
6791
  operator = 5
6775
6792
  end
6776
6793
 
6777
- doper = [type, # Data type
6794
+ [type, # Data type
6778
6795
  operator,
6779
6796
  0x0000, 0x0000 # Reserved
6780
6797
  ].pack('CCVV')
6781
- return doper
6782
6798
  end
6783
6799
  private :pack_blanks_doper
6784
6800
 
@@ -6789,13 +6805,12 @@ def pack_blanks_doper(operator, token) #:nodoc:
6789
6805
  # Pack an string Doper structure.
6790
6806
  #
6791
6807
  def pack_string_doper(operator, length) #:nodoc:
6792
- doper = [0x06, # Data type
6808
+ [0x06, # Data type
6793
6809
  operator,
6794
6810
  0x0000, #Reserved
6795
6811
  length, # String char length
6796
6812
  0x0, 0x0, 0x0 # Reserved
6797
6813
  ].pack('CCVCCCC')
6798
- return doper
6799
6814
  end
6800
6815
  private :pack_string_doper
6801
6816
 
@@ -6809,8 +6824,7 @@ def pack_number_doper(operator, number) #:nodoc:
6809
6824
  number = [number].pack('d')
6810
6825
  number.reverse! if @byte_order != '' && @byte_order != 0
6811
6826
 
6812
- doper = [0x04, operator].pack('CC') + number
6813
- return doper
6827
+ [0x04, operator].pack('CC') + number
6814
6828
  end
6815
6829
  private :pack_number_doper
6816
6830
 
@@ -6844,7 +6858,7 @@ def prepare_images #:nodoc:
6844
6858
  @images = {}
6845
6859
  @images_array = images
6846
6860
 
6847
- return count
6861
+ count
6848
6862
  end
6849
6863
  # private :prepare_images
6850
6864
 
@@ -6872,7 +6886,7 @@ def prepare_comments #:nodoc:
6872
6886
  @comments = {}
6873
6887
  @comments_array = comments
6874
6888
 
6875
- return count
6889
+ count
6876
6890
  end
6877
6891
  # private :prepare_comments
6878
6892
 
@@ -6972,7 +6986,7 @@ def store_images #:nodoc:
6972
6986
  spid = spid + 1
6973
6987
  data = data +
6974
6988
  store_mso_opt_image(image_id) +
6975
- store_mso_client_anchor(2, *vertices) +
6989
+ store_mso_client_anchor(2, *vertices) +
6976
6990
  store_mso_client_data()
6977
6991
  else
6978
6992
  # Write the child MSODRAWIING record.
@@ -6981,10 +6995,10 @@ def store_images #:nodoc:
6981
6995
  spid = spid + 1
6982
6996
  data = data +
6983
6997
  store_mso_opt_image(image_id) +
6984
- store_mso_client_anchor(2, *vertices) +
6998
+ store_mso_client_anchor(2, *vertices) +
6985
6999
  store_mso_client_data
6986
7000
  end
6987
- length = data.length
7001
+ length = data.bytesize
6988
7002
  header = [record, length].pack("vv")
6989
7003
  print "sheet #{@name} : #{__FILE__}(#{__LINE__})\n" if defined?($debug)
6990
7004
  append(header, data)
@@ -7056,29 +7070,29 @@ def store_charts #:nodoc:
7056
7070
  spgr_length += 128 *num_comments
7057
7071
 
7058
7072
 
7059
- data = store_mso_dg_container(dg_length) +
7060
- store_mso_dg(*ids) +
7061
- store_mso_spgr_container(spgr_length) +
7062
- store_mso_sp_container(40) +
7063
- store_mso_spgr() +
7064
- store_mso_sp(0x0, spid, 0x0005)
7073
+ data = store_mso_dg_container(dg_length) +
7074
+ store_mso_dg(*ids) +
7075
+ store_mso_spgr_container(spgr_length) +
7076
+ store_mso_sp_container(40) +
7077
+ store_mso_spgr() +
7078
+ store_mso_sp(0x0, spid, 0x0005)
7065
7079
  spid += 1
7066
- data = data + store_mso_sp_container(112) +
7067
- store_mso_sp(201, spid, 0x0A00)
7080
+ data += store_mso_sp_container(112) +
7081
+ store_mso_sp(201, spid, 0x0A00)
7068
7082
  spid += 1
7069
- data = data + store_mso_opt_chart() +
7070
- store_mso_client_anchor(0, *vertices) +
7071
- store_mso_client_data()
7083
+ data += store_mso_opt_chart() +
7084
+ store_mso_client_anchor(0, *vertices) +
7085
+ store_mso_client_data()
7072
7086
  else
7073
7087
  # Write the child MSODRAWIING record.
7074
- data = store_mso_sp_container(112) +
7075
- store_mso_sp(201, spid, 0x0A00)
7088
+ data = store_mso_sp_container(112) +
7089
+ store_mso_sp(201, spid, 0x0A00)
7076
7090
  spid += 1
7077
- data = data + store_mso_opt_chart() +
7078
- store_mso_client_anchor(0, *vertices) +
7079
- store_mso_client_data()
7091
+ data += store_mso_opt_chart() +
7092
+ store_mso_client_anchor(0, *vertices) +
7093
+ store_mso_client_data()
7080
7094
  end
7081
- length = data.length
7095
+ length = data.bytesize
7082
7096
  header = [record, length].pack("vv")
7083
7097
  print "sheet #{@name} : #{__FILE__}(#{__LINE__})\n" if defined?($debug)
7084
7098
  append(header, data)
@@ -7151,16 +7165,16 @@ def store_filters #:nodoc:
7151
7165
  row1, row2, col1, col2 = @filter_area
7152
7166
 
7153
7167
  (0 .. num_filters-1).each do |i|
7154
- vertices = [ col1 +i, 0, row1 , 0,
7155
- col1 +i +1, 0, row1 +1, 0]
7168
+ vertices = [ col1 + i, 0, row1 , 0,
7169
+ col1 +i +1, 0, row1 + 1, 0]
7156
7170
 
7157
7171
  if i == 0 and !num_objects.nil?
7158
7172
  # Write the parent MSODRAWIING record.
7159
- dg_length = 168 + 96*(num_filters -1)
7160
- spgr_length = 144 + 96*(num_filters -1)
7173
+ dg_length = 168 + 96 * (num_filters -1)
7174
+ spgr_length = 144 + 96 * (num_filters -1)
7161
7175
 
7162
- dg_length = dg_length + 128 *num_comments
7163
- spgr_length = spgr_length + 128 *num_comments
7176
+ dg_length += 128 * num_comments
7177
+ spgr_length += 128 * num_comments
7164
7178
 
7165
7179
  data = store_mso_dg_container(dg_length) +
7166
7180
  store_mso_dg(*ids) +
@@ -7168,24 +7182,24 @@ def store_filters #:nodoc:
7168
7182
  store_mso_sp_container(40) +
7169
7183
  store_mso_spgr() +
7170
7184
  store_mso_sp(0x0, spid, 0x0005)
7171
- spid = spid + 1
7172
- data = data + store_mso_sp_container(88) +
7185
+ spid += 1
7186
+ data += store_mso_sp_container(88) +
7173
7187
  store_mso_sp(201, spid, 0x0A00) +
7174
7188
  store_mso_opt_filter() +
7175
- store_mso_client_anchor(1, *vertices) +
7189
+ store_mso_client_anchor(1, *vertices) +
7176
7190
  store_mso_client_data()
7177
- spid = spid + 1
7191
+ spid += 1
7178
7192
 
7179
7193
  else
7180
7194
  # Write the child MSODRAWIING record.
7181
7195
  data = store_mso_sp_container(88) +
7182
7196
  store_mso_sp(201, spid, 0x0A00) +
7183
7197
  store_mso_opt_filter() +
7184
- store_mso_client_anchor(1, *vertices) +
7198
+ store_mso_client_anchor(1, *vertices) +
7185
7199
  store_mso_client_data()
7186
- spid = spid + 1
7200
+ spid += 1
7187
7201
  end
7188
- length = data.length
7202
+ length = data.bytesize
7189
7203
  header = [record, length].pack("vv")
7190
7204
  print "sheet #{@name} : #{__FILE__}(#{__LINE__})\n" if defined?($debug)
7191
7205
  append(header, data)
@@ -7243,7 +7257,7 @@ def store_comments #:nodoc:
7243
7257
  visible = comments[i][6]
7244
7258
  color = comments[i][7]
7245
7259
  vertices = comments[i][8]
7246
- str_len = str.length
7260
+ str_len = str.bytesize
7247
7261
  str_len = str_len / 2 if encoding != 0 # Num of chars not bytes.
7248
7262
  formats = [[0, 9], [str_len, 0]]
7249
7263
 
@@ -7270,7 +7284,7 @@ def store_comments #:nodoc:
7270
7284
  store_mso_opt_comment(0x80, visible, color) +
7271
7285
  store_mso_client_anchor(3, *vertices) +
7272
7286
  store_mso_client_data
7273
- length = data.length
7287
+ length = data.bytesize
7274
7288
  header = [record, length].pack("vv")
7275
7289
  print "sheet #{@name} : #{__FILE__}(#{__LINE__})\n" if defined?($debug)
7276
7290
  append(header, data)
@@ -7307,7 +7321,7 @@ def store_mso_dg_container(length) #:nodoc:
7307
7321
  version = 15
7308
7322
  instance = 0
7309
7323
  data = ''
7310
- return add_mso_generic(type, version, instance, data, length)
7324
+ add_mso_generic(type, version, instance, data, length)
7311
7325
  end
7312
7326
  # private :store_mso_dg_container
7313
7327
 
@@ -7324,7 +7338,7 @@ def store_mso_dg(instance, num_shapes, max_spid) #:nodoc:
7324
7338
  length = 8
7325
7339
  data = [num_shapes, max_spid].pack("VV")
7326
7340
 
7327
- return add_mso_generic(type, version, instance, data, length)
7341
+ add_mso_generic(type, version, instance, data, length)
7328
7342
  end
7329
7343
  # private :store_mso_dg
7330
7344
 
@@ -7340,7 +7354,7 @@ def store_mso_spgr_container(length) #:nodoc:
7340
7354
  instance = 0
7341
7355
  data = ''
7342
7356
 
7343
- return add_mso_generic(type, version, instance, data, length)
7357
+ add_mso_generic(type, version, instance, data, length)
7344
7358
  end
7345
7359
  # private :store_mso_spgr_container
7346
7360
 
@@ -7356,7 +7370,7 @@ def store_mso_sp_container(length) #:nodoc:
7356
7370
  instance = 0
7357
7371
  data = ''
7358
7372
 
7359
- return add_mso_generic(type, version, instance, data, length)
7373
+ add_mso_generic(type, version, instance, data, length)
7360
7374
  end
7361
7375
  # private :store_mso_sp_container
7362
7376
 
@@ -7373,7 +7387,7 @@ def store_mso_spgr #:nodoc:
7373
7387
  data = [0, 0, 0, 0].pack("VVVV")
7374
7388
  length = 16
7375
7389
 
7376
- return add_mso_generic(type, version, instance, data, length)
7390
+ add_mso_generic(type, version, instance, data, length)
7377
7391
  end
7378
7392
  # private :store_mso_spgr
7379
7393
 
@@ -7390,7 +7404,7 @@ def store_mso_sp(instance, spid, options) #:nodoc:
7390
7404
  length = 8
7391
7405
  data = [spid, options].pack('VV')
7392
7406
 
7393
- return add_mso_generic(type, version, instance, data, length)
7407
+ add_mso_generic(type, version, instance, data, length)
7394
7408
  end
7395
7409
  # private :store_mso_sp
7396
7410
 
@@ -7423,7 +7437,7 @@ def store_mso_opt_comment(spid, visible = nil, colour = 0x50) #:nodoc:
7423
7437
  [visible].pack('v') +
7424
7438
  ['0A00'].pack('H*')
7425
7439
 
7426
- return add_mso_generic(type, version, instance, data, length)
7440
+ add_mso_generic(type, version, instance, data, length)
7427
7441
  end
7428
7442
  # private :store_mso_opt_comment
7429
7443
 
@@ -7447,7 +7461,7 @@ def store_mso_opt_image(spid) #:nodoc:
7447
7461
  [0x03BF].pack( 'v') +
7448
7462
  [0x00080000].pack( 'V')
7449
7463
 
7450
- return add_mso_generic(type, version, instance, data, length)
7464
+ add_mso_generic(type, version, instance, data, length)
7451
7465
  end
7452
7466
  # private :store_mso_opt_image
7453
7467
 
@@ -7484,7 +7498,7 @@ def store_mso_opt_chart #:nodoc:
7484
7498
  [0x03BF].pack('v') + # Group Shape -> fPrint
7485
7499
  [0x00080000].pack('V')
7486
7500
 
7487
- return add_mso_generic(type, version, instance, data, length)
7501
+ add_mso_generic(type, version, instance, data, length)
7488
7502
  end
7489
7503
  # private :store_mso_opt_chart
7490
7504
 
@@ -7512,7 +7526,7 @@ def store_mso_opt_filter #:nodoc:
7512
7526
  [0x03BF].pack('v') + # Group Shape -> fPrint
7513
7527
  [0x000A0000].pack('V')
7514
7528
 
7515
- return add_mso_generic(type, version, instance, data, length)
7529
+ add_mso_generic(type, version, instance, data, length)
7516
7530
  end
7517
7531
  # private :store_mso_opt_filter
7518
7532
 
@@ -7543,7 +7557,7 @@ def store_mso_client_anchor(flag, col_start, x1, row_start, y1, col_end, x2, row
7543
7557
 
7544
7558
  data = [flag, col_start, x1, row_start, y1, col_end, x2, row_end, y2].pack('v9')
7545
7559
 
7546
- return add_mso_generic(type, version, instance, data, length)
7560
+ add_mso_generic(type, version, instance, data, length)
7547
7561
  end
7548
7562
  # private :store_mso_client_anchor
7549
7563
 
@@ -7560,7 +7574,7 @@ def store_mso_client_data #:nodoc:
7560
7574
  data = ''
7561
7575
  length = 0
7562
7576
 
7563
- return add_mso_generic(type, version, instance, data, length)
7577
+ add_mso_generic(type, version, instance, data, length)
7564
7578
  end
7565
7579
  # private :store_mso_client_data
7566
7580
 
@@ -7594,12 +7608,12 @@ def store_obj_comment(obj_id) #:nodoc:
7594
7608
  sub_record = 0x000D # ftNts
7595
7609
  sub_length = 0x0016
7596
7610
  sub_data = [reserved,reserved,reserved,reserved,reserved,reserved].pack( "VVVVVv")
7597
- data = data + [sub_record, sub_length].pack("vv") + sub_data
7611
+ data += [sub_record, sub_length].pack("vv") + sub_data
7598
7612
 
7599
7613
  # Add ftEnd (end of object) subobject
7600
7614
  sub_record = 0x0000 # ftNts
7601
7615
  sub_length = 0x0000
7602
- data = data + [sub_record, sub_length].pack("vv")
7616
+ data += [sub_record, sub_length].pack("vv")
7603
7617
 
7604
7618
  # Pack the record.
7605
7619
  header = [record, length].pack("vv")
@@ -7640,18 +7654,18 @@ def store_obj_image(obj_id) #:nodoc:
7640
7654
  sub_record = 0x0007 # ftCf
7641
7655
  sub_length = 0x0002
7642
7656
  sub_data = [0xFFFF].pack( 'v')
7643
- data = data + [sub_record, sub_length].pack('vv') + sub_data
7657
+ data += [sub_record, sub_length].pack('vv') + sub_data
7644
7658
 
7645
7659
  # Add ftPioGrbit (Picture option flags) subobject
7646
7660
  sub_record = 0x0008 # ftPioGrbit
7647
7661
  sub_length = 0x0002
7648
7662
  sub_data = [0x0001].pack('v')
7649
- data = data + [sub_record, sub_length].pack('vv') + sub_data
7663
+ data += [sub_record, sub_length].pack('vv') + sub_data
7650
7664
 
7651
7665
  # Add ftEnd (end of object) subobject
7652
7666
  sub_record = 0x0000 # ftNts
7653
7667
  sub_length = 0x0000
7654
- data = data + [sub_record, sub_length].pack('vv')
7668
+ data += [sub_record, sub_length].pack('vv')
7655
7669
 
7656
7670
  # Pack the record.
7657
7671
  header = [record, length].pack('vv')
@@ -7691,7 +7705,7 @@ def store_obj_chart(obj_id) #:nodoc:
7691
7705
  # Add ftEnd (end of object) subobject
7692
7706
  sub_record = 0x0000 # ftNts
7693
7707
  sub_length = 0x0000
7694
- data = data + [sub_record, sub_length].pack('vv')
7708
+ data += [sub_record, sub_length].pack('vv')
7695
7709
 
7696
7710
  # Pack the record.
7697
7711
  header = [record, length].pack('vv')
@@ -7733,7 +7747,7 @@ def store_obj_filter(obj_id, col) #:nodoc:
7733
7747
  sub_record = 0x000C # ftSbs
7734
7748
  sub_length = 0x0014
7735
7749
  sub_data = ['0000000000000000640001000A00000010000100'].pack('H*')
7736
- data = data + [sub_record, sub_length].pack('vv') + sub_data
7750
+ data += [sub_record, sub_length].pack('vv') + sub_data
7737
7751
 
7738
7752
  # Add ftLbsData (List box data) subobject
7739
7753
  sub_record = 0x0013 # ftLbsData
@@ -7747,12 +7761,12 @@ def store_obj_filter(obj_id, col) #:nodoc:
7747
7761
  sub_data = ['00000000010001030000020008005700'].pack('H*')
7748
7762
  end
7749
7763
 
7750
- data = data + [sub_record, sub_length].pack('vv') + sub_data
7764
+ data += [sub_record, sub_length].pack('vv') + sub_data
7751
7765
 
7752
7766
  # Add ftEnd (end of object) subobject
7753
7767
  sub_record = 0x0000 # ftNts
7754
7768
  sub_length = 0x0000
7755
- data = data + [sub_record, sub_length].pack('vv')
7769
+ data += [sub_record, sub_length].pack('vv')
7756
7770
 
7757
7771
  # Pack the record.
7758
7772
  header = [record, length].pack('vv')
@@ -7793,7 +7807,7 @@ def store_mso_client_text_box #:nodoc:
7793
7807
  data = ''
7794
7808
  length = 0
7795
7809
 
7796
- return add_mso_generic(type, version, instance, data, length)
7810
+ add_mso_generic(type, version, instance, data, length)
7797
7811
  end
7798
7812
  # private :store_mso_client_text_box
7799
7813
 
@@ -7843,11 +7857,11 @@ def store_txo_continue_1(string, encoding = 0) #:nodoc:
7843
7857
  # so that UTF16 chars occur in the same block.
7844
7858
  #
7845
7859
  limit = 8218
7846
- while string.length > limit
7860
+ while string.bytesize > limit
7847
7861
  string[0 .. limit] = ""
7848
7862
  tmp_str = string
7849
- data = [encoding].pack("C") + tmp_str
7850
- length = data.length
7863
+ data = [encoding].pack("C") + tmp_str.force_encoding('ASCII-8BIT')
7864
+ length = data.bytesize
7851
7865
  header = [record, length].pack('vv')
7852
7866
 
7853
7867
  print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
@@ -7855,8 +7869,8 @@ def store_txo_continue_1(string, encoding = 0) #:nodoc:
7855
7869
  end
7856
7870
 
7857
7871
  # Pack the record.
7858
- data = [encoding].pack("C") + string
7859
- length = data.length
7872
+ data = [encoding].pack("C") + string.force_encoding('ASCII-8BIT')
7873
+ length = data.bytesize
7860
7874
  header = [record, length].pack('vv')
7861
7875
 
7862
7876
  print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
@@ -7880,10 +7894,10 @@ def store_txo_continue_2(formats) #:nodoc:
7880
7894
  data = ''
7881
7895
 
7882
7896
  formats.each do |a_ref|
7883
- data = data + [a_ref[0], a_ref[1], 0x0].pack('vvV')
7897
+ data += [a_ref[0], a_ref[1], 0x0].pack('vvV')
7884
7898
  end
7885
7899
 
7886
- length = data.length
7900
+ length = data.bytesize
7887
7901
  header = [record, length].pack("vv")
7888
7902
 
7889
7903
  print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
@@ -7904,6 +7918,7 @@ def store_txo_continue_2(formats) #:nodoc:
7904
7918
  # Write the worksheet NOTE record that is part of cell comments.
7905
7919
  #
7906
7920
  def store_note(row, col, obj_id, author = nil, author_enc = nil, visible = nil) #:nodoc:
7921
+ ruby_19 { author = [author].pack('a*') if author.ascii_only? }
7907
7922
  record = 0x001C # Record identifier
7908
7923
  length = 0x000C # Bytes to follow
7909
7924
 
@@ -7920,16 +7935,16 @@ def store_note(row, col, obj_id, author = nil, author_enc = nil, visible = nil)
7920
7935
  end
7921
7936
 
7922
7937
  # Get the number of chars in the author string (not bytes).
7923
- num_chars = author.length
7938
+ num_chars = author.bytesize
7924
7939
  num_chars = num_chars / 2 if author_enc != 0 && !author_enc.nil?
7925
7940
 
7926
7941
  # Null terminate the author string.
7927
- author += "\0"
7942
+ author = author.force_encoding('BINARY') + "\0".force_encoding('BINARY')
7928
7943
 
7929
7944
  # Pack the record.
7930
7945
  data = [row, col, visible, obj_id, num_chars, author_enc].pack("vvvvvC")
7931
7946
 
7932
- length = data.length + author.length
7947
+ length = data.bytesize + author.bytesize
7933
7948
  header = [record, length].pack("vv")
7934
7949
 
7935
7950
  print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
@@ -7945,6 +7960,8 @@ def store_note(row, col, obj_id, author = nil, author_enc = nil, visible = nil)
7945
7960
  # well as calculating the comment object position and vertices.
7946
7961
  #
7947
7962
  def comment_params(row, col, string, options = {}) #:nodoc:
7963
+ string = convert_to_ascii_if_ascii(string)
7964
+
7948
7965
  default_width = 128
7949
7966
  default_height = 74
7950
7967
 
@@ -7974,24 +7991,29 @@ def comment_params(row, col, string, options = {}) #:nodoc:
7974
7991
  params[:height] = default_height if params[:height].nil? || params[:height] == 0
7975
7992
 
7976
7993
  # Check that utf16 strings have an even number of bytes.
7994
+ convert_to_ascii_if_ascii(string)
7977
7995
  if params[:encoding] != 0
7978
- raise "Uneven number of bytes in comment string" if string.length % 2 != 0
7996
+ raise "Uneven number of bytes in comment string" if string.bytesize % 2 != 0
7979
7997
 
7980
7998
  # Change from UTF-16BE to UTF-16LE
7981
7999
  string = string.unpack('n*').pack('v*')
7982
8000
  # Handle utf8 strings
7983
- elsif string =~ NonAscii
8001
+ elsif string.encoding == Encoding::UTF_8
7984
8002
  string = NKF.nkf('-w16L0 -m0 -W', string)
8003
+ string.force_encoding('UTF-16LE')
7985
8004
  params[:encoding] = 1
7986
8005
  end
7987
8006
 
8007
+ params[:author] = convert_to_ascii_if_ascii(params[:author])
8008
+
7988
8009
  if params[:author_encoding] != 0
7989
- raise "Uneven number of bytes in author string" if params[:author].length % 2 != 0
8010
+ raise "Uneven number of bytes in author string" if params[:author].bytesize % 2 != 0
7990
8011
 
7991
8012
  # Change from UTF-16BE to UTF-16LE
7992
8013
  params[:author] = params[:author].unpack('n*').pack('v*')
7993
- elsif params[:author] =~ NonAscii
8014
+ elsif params[:author].encoding == Encoding::UTF_8
7994
8015
  params[:author] = NKF.nkf('-w16L0 -m0 -W', params[:author])
8016
+ params[:author].force_encoding('UTF-16LE')
7995
8017
  params[:author_encoding] = 1
7996
8018
  end
7997
8019
 
@@ -7999,7 +8021,7 @@ def comment_params(row, col, string, options = {}) #:nodoc:
7999
8021
  max_len = 32767
8000
8022
  max_len = max_len * 2 if params[:encoding] != 0
8001
8023
 
8002
- if string.length > max_len
8024
+ if string.bytesize > max_len
8003
8025
  string = string[0 .. max_len]
8004
8026
  end
8005
8027
 
@@ -8074,7 +8096,7 @@ def comment_params(row, col, string, options = {}) #:nodoc:
8074
8096
  params[:height]
8075
8097
  )
8076
8098
 
8077
- return [row, col, string,
8099
+ [row, col, string,
8078
8100
  params[:encoding],
8079
8101
  params[:author],
8080
8102
  params[:author_encoding],
@@ -8889,7 +8911,7 @@ def store_dv(cells, validation_type, criteria_type, #:nodoc:
8889
8911
  dv_count = cells.size
8890
8912
  dv_data = [dv_count].pack('v')
8891
8913
  cells.each do |range|
8892
- dv_data = dv_data + [range[0], range[2], range[1], range[3]].pack('vvvv')
8914
+ dv_data += [range[0], range[2], range[1], range[3]].pack('vvvv')
8893
8915
  end
8894
8916
 
8895
8917
  # Pack the record.
@@ -8902,7 +8924,7 @@ def store_dv(cells, validation_type, criteria_type, #:nodoc:
8902
8924
  formula_2 +
8903
8925
  dv_data
8904
8926
 
8905
- header = [record, data.length].pack('vv')
8927
+ header = [record, data.bytesize].pack('vv')
8906
8928
 
8907
8929
  print "sheet #{@name} : #{__FILE__}(#{__LINE__}) \n" if defined?($debug)
8908
8930
  append(header, data)
@@ -8922,26 +8944,26 @@ def pack_dv_string(string = nil, max_length = 0) #:nodoc:
8922
8944
 
8923
8945
  # The default empty string is "\0".
8924
8946
  if string.nil? || string == ''
8925
- string = "\0"
8947
+ string = "\0".encode('BINARY')
8926
8948
  end
8927
8949
 
8928
8950
  # Excel limits DV captions to 32 chars and messages to 255.
8929
- if string.length > max_length
8951
+ if string.bytesize > max_length
8930
8952
  string = string[0 .. max_length-1]
8931
8953
  end
8932
8954
 
8933
- str_length = string.length
8955
+ str_length = string.bytesize
8956
+
8957
+ string = convert_to_ascii_if_ascii(string)
8934
8958
 
8935
8959
  # Handle utf8 strings
8936
- if string =~ NonAscii
8937
- $KCODE = 'u'
8938
- require 'jcode'
8939
- str_length = string.jlength
8940
- string = NKF.nkf('-w16L0 -m0 -W', string)
8960
+ if string.encoding == Encoding::UTF_8
8961
+ str_length = string.gsub(/[^\Wa-zA-Z_\d]/, ' ').bytesize # jlength
8962
+ string = string.encode('UTF-16LE')
8941
8963
  encoding = 1
8942
8964
  end
8943
8965
 
8944
- return [str_length, encoding].pack('vC') + string
8966
+ [str_length, encoding].pack('vC') + string.force_encoding('BINARY')
8945
8967
  end
8946
8968
  # private :pack_dv_string
8947
8969
 
@@ -9000,8 +9022,6 @@ def pack_dv_formula(formula = nil) #:nodoc:
9000
9022
  # Parse the tokens into a formula string.
9001
9023
  formula = parser.parse_tokens(tokens)
9002
9024
 
9003
- return [formula.length, unused].pack('vv') + formula
9025
+ [formula.length, unused].pack('vv') + formula
9004
9026
  end
9005
- # private :pack_dv_formula
9006
-
9007
9027
  end