spreadsheet 0.6.3.1 → 0.6.4

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,35 @@
1
+ === 0.6.4 / 2009-07-03
2
+
3
+ * 5 Bugfixes
4
+
5
+ * Fixes the issue reported by Harley Mackenzie in
6
+ http://rubyforge.org/tracker/index.php?func=detail&aid=24119&group_id=678&atid=2677
7
+ where in some edge-cases numbers were stored incorrectly
8
+
9
+ * Fixes the issue reported and fixed by someone23 in
10
+ http://rubyforge.org/tracker/index.php?func=detail&aid=25732&group_id=678&atid=2677
11
+ where using Row-updater methods with blocks caused LocalJumpErrors
12
+
13
+ * Fixes the issue reported and fixed by Corey Burrows in
14
+ http://rubyforge.org/tracker/index.php?func=detail&aid=25784&group_id=678&atid=2677
15
+ where "Setting the height of a row, either in Excel directly, or via the
16
+ Spreadsheet::Row#height= method results in a row that Excel displays with
17
+ the maximum row height (409)."
18
+
19
+ * Fixes the issue reported by Don Park in
20
+ http://rubyforge.org/tracker/index.php?func=detail&aid=25968&group_id=678&atid=2677
21
+ where some Workbooks could not be parsed due to the OLE-entry being all
22
+ uppercase
23
+
24
+ * Fixes the issue reported by Iwan Buetti in
25
+ http://rubyforge.org/tracker/index.php?func=detail&aid=24414&group_id=678&atid=2677
26
+ where parsing some Workbooks failed with an Invalid date error.
27
+
28
+
29
+ * 1 major enhancement
30
+
31
+ * Spreadsheet now runs on Ruby 1.9
32
+
1
33
  === 0.6.3.1 / 2009-02-13
2
34
 
3
35
  * 3 Bugfixes
data/Manifest.txt CHANGED
@@ -10,6 +10,7 @@ lib/parseexcel/parseexcel.rb
10
10
  lib/parseexcel/parser.rb
11
11
  lib/spreadsheet.rb
12
12
  lib/spreadsheet/column.rb
13
+ lib/spreadsheet/compatibility.rb
13
14
  lib/spreadsheet/datatypes.rb
14
15
  lib/spreadsheet/encodings.rb
15
16
  lib/spreadsheet/excel.rb
data/lib/spreadsheet.rb CHANGED
@@ -42,7 +42,7 @@ module Spreadsheet
42
42
 
43
43
  ##
44
44
  # The version of Spreadsheet you are using.
45
- VERSION = '0.6.3.1'
45
+ VERSION = '0.6.4'
46
46
 
47
47
  ##
48
48
  # Default client Encoding. Change this value if your application uses a
@@ -0,0 +1,23 @@
1
+ module Spreadsheet
2
+ module Compatibility
3
+ ##
4
+ # One of the most incisive changes in terms of meta-programming in Ruby 1.9
5
+ # is the switch from representing instance-variable names as Strings to
6
+ # presenting them as Symbols. ivar_name provides compatibility.
7
+ if RUBY_VERSION >= '1.9'
8
+ def ivar_name symbol
9
+ :"@#{symbol}"
10
+ end
11
+ def method_name symbol
12
+ symbol.to_sym
13
+ end
14
+ else
15
+ def ivar_name symbol
16
+ "@#{symbol}"
17
+ end
18
+ def method_name symbol
19
+ symbol.to_s
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,8 +1,11 @@
1
+ require 'spreadsheet/compatibility'
2
+
1
3
  module Spreadsheet
2
4
  ##
3
5
  # This module defines convenience-methods for the definition of Spreadsheet
4
6
  # attributes (boolean, colors and enumerations)
5
7
  module Datatypes
8
+ include Compatibility
6
9
  def Datatypes.append_features mod
7
10
  super
8
11
  mod.module_eval do
@@ -21,7 +24,7 @@ class << self
21
24
  def boolean *args
22
25
  args.each do |key|
23
26
  define_method key do
24
- name = "@#{key}"
27
+ name = ivar_name key
25
28
  !!(instance_variable_get(name) if instance_variables.include?(name))
26
29
  end
27
30
  define_method "#{key}?" do
@@ -29,7 +32,7 @@ class << self
29
32
  end
30
33
  define_method "#{key}=" do |arg|
31
34
  arg = false if arg == 0
32
- instance_variable_set("@#{key}", !!arg)
35
+ instance_variable_set(ivar_name(key), !!arg)
33
36
  end
34
37
  define_method "#{key}!" do
35
38
  send "#{key}=", true
@@ -45,7 +48,7 @@ class << self
45
48
  define_method "#{key}=" do |name|
46
49
  name = name.to_s.downcase.to_sym
47
50
  if COLORS.include?(name)
48
- instance_variable_set "@#{key}", name
51
+ instance_variable_set ivar_name(key), name
49
52
  else
50
53
  raise ArgumentError, "unknown color '#{name}'"
51
54
  end
@@ -74,7 +77,7 @@ class << self
74
77
  aliases.store value, value
75
78
  end
76
79
  define_method key do
77
- name = "@#{key}"
80
+ name = ivar_name key
78
81
  value = instance_variable_get(name) if instance_variables.include? name
79
82
  value || values.first
80
83
  end
@@ -84,14 +87,14 @@ class << self
84
87
  aliases.fetch arg.to_s.downcase.gsub(/[ \-]/, '_').to_sym, arg
85
88
  end
86
89
  if values.any? do |val| val === arg end
87
- instance_variable_set("@#{key}", arg)
90
+ instance_variable_set(ivar_name(key), arg)
88
91
  else
89
92
  valid = values.collect do |val| val.inspect end.join ', '
90
93
  raise ArgumentError,
91
94
  "Invalid value '#{arg.inspect}' for #{key}. Valid values are: #{valid}"
92
95
  end
93
96
  else
94
- instance_variable_set "@#{key}", values.first
97
+ instance_variable_set ivar_name(key), values.first
95
98
  end
96
99
  end
97
100
  end
@@ -4,10 +4,16 @@ module Spreadsheet
4
4
  module Encodings
5
5
  if RUBY_VERSION >= '1.9'
6
6
  def client string, internal='UTF-16LE'
7
+ string.force_encoding internal
7
8
  string.encode Spreadsheet.client_encoding
8
9
  end
9
- def internal string, internal='UTF-16LE'
10
- string.encode internal
10
+ def internal string, client=Spreadsheet.client_encoding
11
+ string.force_encoding client
12
+ string.encode('UTF-16LE').force_encoding('ASCII-8BIT')
13
+ end
14
+ def utf8 string, client=Spreadsheet.client_encoding
15
+ string.force_encoding client
16
+ string.encode('UTF-8')
11
17
  end
12
18
  else
13
19
  require 'iconv'
@@ -17,9 +23,14 @@ module Spreadsheet
17
23
  iconv = @@iconvs[key] ||= Iconv.new(Spreadsheet.client_encoding, internal)
18
24
  iconv.iconv string
19
25
  end
20
- def internal string, internal='UTF-16LE'
21
- key = [internal, Spreadsheet.client_encoding]
22
- iconv = @@iconvs[key] ||= Iconv.new(internal, Spreadsheet.client_encoding)
26
+ def internal string, client=Spreadsheet.client_encoding
27
+ key = ['UTF-16LE', client]
28
+ iconv = @@iconvs[key] ||= Iconv.new('UTF-16LE', client)
29
+ iconv.iconv string
30
+ end
31
+ def utf8 string, client=Spreadsheet.client_encoding
32
+ key = ['UTF-8', client]
33
+ iconv = @@iconvs[key] ||= Iconv.new('UTF-8', client)
23
34
  iconv.iconv string
24
35
  end
25
36
  end
@@ -1,9 +1,13 @@
1
+ require 'spreadsheet/compatibility'
2
+
1
3
  module Spreadsheet
2
4
  module Excel
3
5
  ##
4
6
  # This module is used to keep track of offsets in modified Excel documents.
5
7
  # Considered internal and subject to change without notice.
6
8
  module Offset
9
+ include Compatibility
10
+ attr_reader :changes, :offsets
7
11
  def initialize *args
8
12
  super
9
13
  @changes = {}
@@ -11,18 +15,18 @@ module Offset
11
15
  end
12
16
  def Offset.append_features mod
13
17
  super
14
- attr_reader :changes, :offsets
15
18
  mod.module_eval do
16
19
  class << self
20
+ include Compatibility
17
21
  def offset *keys
18
22
  keys.each do |key|
19
- attr_reader key unless instance_methods.include? key.to_s
23
+ attr_reader key unless instance_methods.include? method_name(key)
20
24
  define_method "#{key}=" do |value|
21
25
  @changes.store key, true
22
- instance_variable_set "@#{key}", value
26
+ instance_variable_set ivar_name(key), value
23
27
  end
24
28
  define_method "set_#{key}" do |value, pos, len|
25
- instance_variable_set "@#{key}", value
29
+ instance_variable_set ivar_name(key), value
26
30
  @offsets.store key, [pos, len]
27
31
  havename = "have_set_#{key}"
28
32
  send(havename, value, pos, len) if respond_to? havename
@@ -487,7 +487,7 @@ class Reader
487
487
  size, = work.unpack "x#{pos}V"
488
488
  pos += 4
489
489
  data = work[pos, size].chomp "\000\000"
490
- link.url = client data, 'UTF-16LE'
490
+ link.url = client data
491
491
  pos += size
492
492
  else
493
493
  # 6.53.3 Hyperlink to a Local File
@@ -532,7 +532,7 @@ class Reader
532
532
  total, size = work.unpack "x#{pos}V2"
533
533
  pos += 10
534
534
  if total > 0
535
- link.url = client work[pos, size], 'UTF-16LE'
535
+ link.url = client work[pos, size]
536
536
  pos += size
537
537
  end
538
538
  end
@@ -770,9 +770,9 @@ class Reader
770
770
  when :datemode # ○ DATEMODE ➜ 6.25
771
771
  flag, _ = work.unpack 'v'
772
772
  if flag == 1
773
- @workbook.date_base = Date.new 1904, 1, 1
773
+ @workbook.date_base = DateTime.new 1904, 1, 1
774
774
  else
775
- @workbook.date_base = Date.new 1899, 12, 31
775
+ @workbook.date_base = DateTime.new 1899, 12, 31
776
776
  end
777
777
  when :continue # ○ CONTINUE ➜ 6.22
778
778
  case previous_op
@@ -1095,9 +1095,18 @@ class Reader
1095
1095
  worksheet.set_row_address index, attrs
1096
1096
  end
1097
1097
  def setup io
1098
+ ## Reading from StringIO fails without forced encoding
1099
+ if io.respond_to?(:string) && (str = io.string) \
1100
+ && str.respond_to?(:force_encoding)
1101
+ str.force_encoding 'ASCII-8BIT'
1102
+ end
1103
+ ##
1104
+ io.rewind
1098
1105
  @ole = Ole::Storage.open io
1099
1106
  @workbook = Workbook.new io, {}
1100
- @book = @ole.file.open("Book") rescue @ole.file.open("Workbook")
1107
+ %w{Book Workbook BOOK WORKBOOK book workbook}.any? do |name|
1108
+ @book = @ole.file.open(name) rescue false
1109
+ end
1101
1110
  @data = @book.read
1102
1111
  read_bof
1103
1112
  @workbook.ole = @book
@@ -45,18 +45,16 @@ class Row < Spreadsheet::Row
45
45
  private
46
46
  def _date data # :nodoc:
47
47
  return data if data.is_a?(Date)
48
- date = @worksheet.date_base + data.to_i
49
- if date > LEAP_ERROR
50
- date -= 1
51
- end
52
- date
48
+ datetime = _datetime data
49
+ Date.new datetime.year, datetime.month, datetime.day
53
50
  end
54
51
  def _datetime data # :nodoc:
55
52
  return data if data.is_a?(DateTime)
56
- date = _date data
53
+ base = @worksheet.date_base
54
+ date = base + data.to_f
57
55
  hour = (data % 1) * 24
58
56
  min = (hour % 1) * 60
59
- sec = ((min % 1) * 60).round
57
+ sec = ((min % 1) * 60).round
60
58
  min = min.floor
61
59
  hour = hour.floor
62
60
  if sec > 59
@@ -69,6 +67,9 @@ class Row < Spreadsheet::Row
69
67
  if hour > 23
70
68
  date += 1
71
69
  end
70
+ if LEAP_ERROR > base
71
+ date -= 1
72
+ end
72
73
  DateTime.new(date.year, date.month, date.day, hour, min, sec)
73
74
  end
74
75
  def enriched_data idx, data # :nodoc:
@@ -61,7 +61,7 @@ class Workbook < Spreadsheet::Workbook
61
61
  end
62
62
  end
63
63
  def date_base
64
- @date_base ||= Date.new 1899, 12, 31
64
+ @date_base ||= DateTime.new 1899, 12, 31
65
65
  end
66
66
  def shared_string idx
67
67
  @sst[idx.to_i].content
@@ -36,11 +36,12 @@ module Biff8
36
36
  header, data, _ = _unicode_string string, count_length
37
37
  header << data
38
38
  end
39
+ @@bytesize = RUBY_VERSION >= '1.9' ? :bytesize : :size
39
40
  ##
40
41
  # Encode _string_ into a Biff8 Unicode String Header and Body.
41
42
  def _unicode_string string, count_length=1
42
43
  data = internal string
43
- size = data.size / 2
44
+ size = data.send(@@bytesize) / 2
44
45
  fmt = count_length == 1 ? 'C2' : 'vC'
45
46
  data, wide = compress_unicode_string data
46
47
  opts = wide
@@ -640,7 +640,7 @@ class Workbook < Spreadsheet::Writer
640
640
  @sst[worksheet][str]
641
641
  end
642
642
  def xf_index workbook, format
643
- if fmt = @formats[workbook].find do |fmt| fmt.format == format end
643
+ if fmt = @formats[workbook].find do |fm| fm.format == format end
644
644
  fmt.xf_index
645
645
  else
646
646
  0
@@ -48,8 +48,9 @@ class Worksheet
48
48
  date = DateTime.new date.year, date.month, date.day,
49
49
  date.hour, date.min, date.sec
50
50
  end
51
- value = date - @workbook.date_base
52
- if date > LEAP_ERROR
51
+ base = @workbook.date_base
52
+ value = date - base
53
+ if LEAP_ERROR > base
53
54
  value += 1
54
55
  end
55
56
  value
@@ -86,9 +87,19 @@ class Worksheet
86
87
  unicode_string @worksheet.name
87
88
  end
88
89
  def need_number? cell
89
- (cell.is_a?(Numeric) && cell.abs > 0x1fffffff) \
90
- || (cell.is_a?(Float) \
91
- && !/^[\000\001]\000{3}/.match([cell * 100].pack(EIGHT_BYTE_DOUBLE)))
90
+ if cell.is_a?(Numeric) && cell.abs > 0x1fffffff
91
+ true
92
+ elsif cell.is_a?(Float)
93
+ higher = cell * 100
94
+ if higher == higher.to_i
95
+ need_number? higher.to_i
96
+ else
97
+ test1, test2 = [cell * 100].pack(EIGHT_BYTE_DOUBLE).unpack('V2')
98
+ test1 > 0 || need_number?(test2)
99
+ end
100
+ else
101
+ false
102
+ end
92
103
  end
93
104
  def row_blocks
94
105
  # All cells in an Excel document are divided into blocks of 32 consecutive
@@ -501,15 +512,17 @@ class Worksheet
501
512
 
502
513
  ].pack('V2')
503
514
  tail = []
515
+ ## call internal to get the correct internal encoding in Ruby 1.9
516
+ nullstr = internal "\000"
504
517
  unless link == link.url
505
- desc = internal(link).dup << "\000\000"
518
+ desc = internal(link).dup << nullstr
506
519
  tail.push [desc.size / 2].pack('V'), desc
507
520
  end
508
521
  if link.target_frame
509
- frme = internal(link.target_frame).dup << "\000\000"
522
+ frme = internal(link.target_frame).dup << nullstr
510
523
  tail.push [frme.size / 2].pack('V'), frme
511
524
  end
512
- url = internal(link.url).dup << "\000\000"
525
+ url = internal(link.url).dup << nullstr
513
526
  tail.push [
514
527
  # 6.53.2 Hyperlink containing a URL (Uniform Resource Locator)
515
528
  # These data fields occur for links which are not local files or files
@@ -526,7 +539,7 @@ class Worksheet
526
539
  # string.
527
540
  ].pack('H32V'), url
528
541
  if link.fragment
529
- frag = internal(link.fragment).dup << "\000\000"
542
+ frag = internal(link.fragment).dup << nullstr
530
543
  tail.push [frag.size / 2].pack('V'), frag
531
544
  end
532
545
  write_op opcode(:hlink), cell_range, guid, options, *tail
@@ -691,9 +704,9 @@ class Worksheet
691
704
  end
692
705
  opts |= 0x00000100
693
706
  height = if height == ROW_HEIGHT
694
- height * TWIPS
707
+ (height * TWIPS).to_i | 0x8000
695
708
  else
696
- ( height * TWIPS ) | 0x8000
709
+ height * TWIPS
697
710
  end
698
711
  # TODO: Row spacing
699
712
  data = [
@@ -1,3 +1,4 @@
1
+ # encoding: utf-8
1
2
  require 'spreadsheet/datatypes'
2
3
  require 'spreadsheet/encodings'
3
4
 
@@ -73,17 +74,18 @@ module Spreadsheet
73
74
  end
74
75
  def key # :nodoc:
75
76
  key = @name.dup
76
- key << '_' << size.to_s
77
- key << '_' << weight.to_s
78
- key << '_italic' if italic?
79
- key << '_strikeout' if strikeout?
80
- key << '_outline' if outline?
81
- key << '_shadow' if shadow?
82
- key << '_' << escapement.to_s
83
- key << '_' << underline.to_s
84
- key << '_' << color.to_s
85
- key << '_' << family.to_s
86
- key << '_' << encoding.to_s
77
+ underscore = client('_', 'UTF-8')
78
+ key << underscore << client(size.to_s, 'US-ASCII')
79
+ key << client('_', 'UTF-8') << client(weight.to_s, 'US-ASCII')
80
+ key << client('_italic', 'UTF-8') if italic?
81
+ key << client('_strikeout', 'UTF-8') if strikeout?
82
+ key << client('_outline', 'UTF-8') if outline?
83
+ key << client('_shadow', 'UTF-8') if shadow?
84
+ key << underscore << client(escapement.to_s, 'US-ASCII')
85
+ key << underscore << client(underline.to_s, 'US-ASCII')
86
+ key << underscore << client(color.to_s, 'US-ASCII')
87
+ key << underscore << client(family.to_s, 'US-ASCII')
88
+ key << underscore << client(encoding.to_s, 'US-ASCII')
87
89
  end
88
90
  end
89
91
  end
@@ -1,3 +1,4 @@
1
+ # encoding: utf-8
1
2
  require 'spreadsheet/datatypes'
2
3
  require 'spreadsheet/encodings'
3
4
  require 'spreadsheet/font'
@@ -155,22 +156,22 @@ module Spreadsheet
155
156
  ##
156
157
  # Is the cell formatted as a Date?
157
158
  def date?
158
- !!/[YMD]/.match(@number_format.to_s)
159
+ !!Regexp.new(client("[YMD]", 'UTF-8')).match(@number_format.to_s)
159
160
  end
160
161
  ##
161
162
  # Is the cell formatted as a Date or Time?
162
163
  def date_or_time?
163
- !!/[hmsYMD]/.match(@number_format.to_s)
164
+ !!Regexp.new(client("[hmsYMD]", 'UTF-8')).match(@number_format.to_s)
164
165
  end
165
166
  ##
166
167
  # Is the cell formatted as a DateTime?
167
168
  def datetime?
168
- !!/([YMD].*[HS])|([HS].*[YMD])/.match(@number_format.to_s)
169
+ !!Regexp.new(client("([YMD].*[HS])|([HS].*[YMD])", 'UTF-8')).match(@number_format.to_s)
169
170
  end
170
171
  ##
171
172
  # Is the cell formatted as a Time?
172
173
  def time?
173
- !!/[hms]/.match(@number_format.to_s)
174
+ !!Regexp.new(client("[hms]", 'UTF-8')).match(@number_format.to_s)
174
175
  end
175
176
  end
176
177
  end
@@ -1,4 +1,5 @@
1
1
  require 'uri'
2
+ require 'spreadsheet/encodings'
2
3
 
3
4
  module Spreadsheet
4
5
  ##
@@ -17,6 +18,7 @@ module Spreadsheet
17
18
  # Filename introduced in VFAT. You probably will not need this,
18
19
  # but if you do, here is where you can find it.
19
20
  class Link < String
21
+ include Encodings
20
22
  attr_accessor :target_frame, :url, :dos, :fragment
21
23
  def initialize url='', description=url, fragment=nil
22
24
  super description
@@ -28,7 +30,7 @@ module Spreadsheet
28
30
  def href
29
31
  href = (@url || @dos).to_s.dup
30
32
  if @fragment
31
- href << '#' << @fragment
33
+ href << client('#') << @fragment
32
34
  end
33
35
  href
34
36
  end
@@ -33,11 +33,18 @@ module Spreadsheet
33
33
  end
34
34
  def updater *keys
35
35
  keys.each do |key|
36
- define_method key do |*args|
37
- res = super
38
- @worksheet.row_updated @idx, self if @worksheet
39
- res
40
- end
36
+ ## Passing blocks to methods defined with define_method is not possible
37
+ # in Ruby 1.8:
38
+ # http://groups.google.com/group/ruby-talk-google/msg/778184912b769e5f
39
+ # use class_eval as suggested by someone else in
40
+ # http://rubyforge.org/tracker/index.php?func=detail&aid=25732&group_id=678&atid=2677
41
+ class_eval <<-SRC, __FILE__, __LINE__
42
+ def #{key}(*args)
43
+ res = super(*args)
44
+ @worksheet.row_updated @idx, self if @worksheet
45
+ res
46
+ end
47
+ SRC
41
48
  end
42
49
  end
43
50
  end
@@ -232,8 +232,8 @@ module Spreadsheet
232
232
  ##
233
233
  # Renumbers all Rows starting at _idx_ and calls #row_updated for each of
234
234
  # them.
235
- def updated_from idx
236
- idx.upto(@rows.size - 1) do |idx|
235
+ def updated_from index
236
+ index.upto(@rows.size - 1) do |idx|
237
237
  row = row(idx)
238
238
  row.idx = idx
239
239
  row_updated idx, row
@@ -264,7 +264,6 @@ module Spreadsheet
264
264
  compact = @rows.compact
265
265
  @dimensions[2] = compact.collect do |row| row.first_used end.compact.min || 0
266
266
  @dimensions[3] = compact.collect do |row| row.first_unused end.max || 0
267
- puts caller if @dimensions.nil?
268
267
  @dimensions
269
268
  end
270
269
  def shorten ary # :nodoc:
@@ -8,6 +8,7 @@ module Spreadsheet
8
8
  end
9
9
  def write workbook
10
10
  if @io_or_path.respond_to? :seek
11
+ @io_or_path.binmode
11
12
  write_workbook workbook, @io_or_path
12
13
  else
13
14
  File.open(@io_or_path, "wb+") do |fh|
@@ -15,6 +15,7 @@ class TestWorksheet < Test::Unit::TestCase
15
15
  assert_equal false, sheet.need_number?(0.1)
16
16
  assert_equal false, sheet.need_number?(0.01)
17
17
  assert_equal true, sheet.need_number?(0.001)
18
+ assert_equal true, sheet.need_number?(10000000.0)
18
19
  end
19
20
  end
20
21
  end
data/test/font.rb CHANGED
@@ -4,7 +4,7 @@
4
4
  $: << File.expand_path('../lib', File.dirname(__FILE__))
5
5
 
6
6
  require 'test/unit'
7
- require 'spreadsheet/font'
7
+ require 'spreadsheet'
8
8
 
9
9
  module Spreadsheet
10
10
  class TestFont < Test::Unit::TestCase
data/test/integration.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # encoding: utf-8
2
3
  # TestIntegration -- Spreadheet -- 08.10.2007 -- hwyss@ywesee.com
3
4
 
4
5
  $: << File.expand_path('../lib', File.dirname(__FILE__))
@@ -9,7 +10,23 @@ require 'fileutils'
9
10
 
10
11
  module Spreadsheet
11
12
  class TestIntegration < Test::Unit::TestCase
12
- @@iconv = Iconv.new('UTF-16LE', 'UTF-8')
13
+ if RUBY_VERSION >= '1.9'
14
+ class IconvStub
15
+ def initialize to, from
16
+ @to, @from = to, from
17
+ end
18
+ def iconv str
19
+ dp = str.dup
20
+ dp.force_encoding @from
21
+ dp.encode @to
22
+ end
23
+ end
24
+ @@iconv = IconvStub.new('UTF-16LE', 'UTF-8')
25
+ @@bytesize = :bytesize
26
+ else
27
+ @@iconv = Iconv.new('UTF-16LE', 'UTF-8')
28
+ @@bytesize = :size
29
+ end
13
30
  def setup
14
31
  @var = File.expand_path 'var', File.dirname(__FILE__)
15
32
  FileUtils.mkdir_p @var
@@ -66,6 +83,7 @@ module Spreadsheet
66
83
  assert_equal 25, book.formats.size
67
84
  assert_equal 5, book.fonts.size
68
85
  str1 = book.shared_string 0
86
+ other = @@iconv.iconv('Shared String')
69
87
  assert_equal @@iconv.iconv('Shared String'), str1
70
88
  str2 = book.shared_string 1
71
89
  assert_equal @@iconv.iconv('Another Shared String'), str2
@@ -305,7 +323,7 @@ module Spreadsheet
305
323
  assert_equal str2, sheet[1,1]
306
324
  assert_equal str2, sheet.cell(1,1)
307
325
  row = sheet.row 2
308
- assert_equal 510, row[0].size
326
+ assert_equal 510, row[0].send(@@bytesize)
309
327
  assert_equal str3, row[0]
310
328
  assert_equal str3, sheet[2,0]
311
329
  assert_equal str3, sheet.cell(2,0)
@@ -313,7 +331,7 @@ module Spreadsheet
313
331
  assert_nil sheet[2,1]
314
332
  assert_nil sheet.cell(2,1)
315
333
  row = sheet.row 3
316
- assert_equal 510, row[0].size
334
+ assert_equal 510, row[0].send(@@bytesize)
317
335
  assert_equal str4, row[0]
318
336
  assert_equal str4, sheet[3,0]
319
337
  assert_equal str4, sheet.cell(3,0)
@@ -378,7 +396,7 @@ module Spreadsheet
378
396
  assert_equal str2, sheet[1,1]
379
397
  assert_equal str2, sheet.cell(1,1)
380
398
  row = sheet.row 2
381
- assert_equal 255, row[0].size
399
+ assert_equal 255, row[0].send(@@bytesize)
382
400
  assert_equal str3, row[0]
383
401
  assert_equal str3, sheet[2,0]
384
402
  assert_equal str3, sheet.cell(2,0)
@@ -386,7 +404,7 @@ module Spreadsheet
386
404
  assert_nil sheet[2,1]
387
405
  assert_nil sheet.cell(2,1)
388
406
  row = sheet.row 3
389
- assert_equal 255, row[0].size
407
+ assert_equal 255, row[0].send(@@bytesize)
390
408
  assert_equal str4, row[0]
391
409
  assert_equal str4, sheet[3,0]
392
410
  assert_equal str4, sheet.cell(3,0)
@@ -451,7 +469,7 @@ module Spreadsheet
451
469
  assert_equal str2, sheet[1,1]
452
470
  assert_equal str2, sheet.cell(1,1)
453
471
  row = sheet.row 2
454
- assert_equal 255, row[0].size
472
+ assert_equal 255, row[0].send(@@bytesize)
455
473
  assert_equal str3, row[0]
456
474
  assert_equal str3, sheet[2,0]
457
475
  assert_equal str3, sheet.cell(2,0)
@@ -459,7 +477,7 @@ module Spreadsheet
459
477
  assert_nil sheet[2,1]
460
478
  assert_nil sheet.cell(2,1)
461
479
  row = sheet.row 3
462
- assert_equal 255, row[0].size
480
+ assert_equal 255, row[0].send(@@bytesize)
463
481
  assert_equal str4, row[0]
464
482
  assert_equal str4, sheet[3,0]
465
483
  assert_equal str4, sheet.cell(3,0)
@@ -501,9 +519,13 @@ module Spreadsheet
501
519
  assert_equal 3, sheets.size
502
520
  sheet = book.worksheet 0
503
521
  assert_instance_of Excel::Worksheet, sheet
504
- assert_equal sheet, book.worksheet("S\000h\000e\000e\000t\0001\000")
522
+ str = "S\000h\000e\000e\000t\0001\000"
523
+ if RUBY_VERSION >= '1.9'
524
+ str.force_encoding 'UTF-16LE' if name.respond_to?(:force_encoding)
525
+ end
526
+ assert_equal sheet, book.worksheet(str)
505
527
  end
506
- def test_datetime
528
+ def test_read_datetime
507
529
  path = File.join @data, 'test_datetime.xls'
508
530
  book = Spreadsheet.open path
509
531
  assert_instance_of Excel::Workbook, book
@@ -582,9 +604,9 @@ module Spreadsheet
582
604
  assert_equal 12, sheet.column_count
583
605
  useds = [0,0,0,0,0,0,0,0,0,0,0]
584
606
  unuseds = [2,2,1,1,1,2,1,11,1,2,12]
585
- sheet.each do |row|
586
- assert_equal useds.shift, row.first_used
587
- assert_equal unuseds.shift, row.first_unused
607
+ sheet.each do |rw|
608
+ assert_equal useds.shift, rw.first_used
609
+ assert_equal unuseds.shift, rw.first_unused
588
610
  end
589
611
  assert unuseds.empty?, "not all rows were visited in Spreadsheet#each"
590
612
  row = sheet.row 0
@@ -691,9 +713,9 @@ module Spreadsheet
691
713
  assert_equal 12, sheet.column_count
692
714
  useds = [0,0,0,0,0,0,0,0,0,0,0]
693
715
  unuseds = [2,2,1,1,1,2,1,11,1,2,12]
694
- sheet.each do |row|
695
- assert_equal useds.shift, row.first_used
696
- assert_equal unuseds.shift, row.first_unused
716
+ sheet.each do |rw|
717
+ assert_equal useds.shift, rw.first_used
718
+ assert_equal unuseds.shift, rw.first_unused
697
719
  end
698
720
  assert unuseds.empty?, "not all rows were visited in Spreadsheet#each"
699
721
  row = sheet.row 0
@@ -844,7 +866,11 @@ module Spreadsheet
844
866
  str3 = @@iconv.iconv str3
845
867
  str4 = @@iconv.iconv str4
846
868
  assert_nothing_raised do book = Spreadsheet.open path end
847
- assert_equal 'UTF-16LE', book.encoding
869
+ if RUBY_VERSION >= '1.9'
870
+ assert_equal 'UTF-16LE', book.encoding.name
871
+ else
872
+ assert_equal 'UTF-16LE', book.encoding
873
+ end
848
874
  assert_equal str1, book.shared_string(0)
849
875
  assert_equal str2, book.shared_string(1)
850
876
  test = nil
@@ -873,8 +899,9 @@ module Spreadsheet
873
899
  assert_equal 2, book.worksheets.size
874
900
  sheet = book.worksheets.first
875
901
  assert_instance_of Spreadsheet::Excel::Worksheet, sheet
876
- assert_equal "W\000o\000r\000k\000s\000h\000e\000e\000t\0001\000",
877
- sheet.name
902
+ name = "W\000o\000r\000k\000s\000h\000e\000e\000t\0001\000"
903
+ name.force_encoding 'UTF-16LE' if name.respond_to?(:force_encoding)
904
+ assert_equal name, sheet.name
878
905
  assert_not_nil sheet.offset
879
906
  assert_not_nil col = sheet.column(1)
880
907
  assert_equal true, col.default_format.font.italic?
@@ -968,8 +995,9 @@ module Spreadsheet
968
995
  assert_equal 40, sheet1.row(11).height
969
996
  assert_instance_of Spreadsheet::Excel::Worksheet, sheet
970
997
  sheet = book.worksheets.last
971
- assert_equal "m\000y\000 \000n\000a\000m\000e\000",
972
- sheet.name
998
+ name = "m\000y\000 \000n\000a\000m\000e\000"
999
+ name.force_encoding 'UTF-16LE' if name.respond_to?(:force_encoding)
1000
+ assert_equal name, sheet.name
973
1001
  assert_not_nil sheet.offset
974
1002
  end
975
1003
  def test_write_new_workbook__utf16
@@ -999,12 +1027,12 @@ module Spreadsheet
999
1027
  sheet1.row(6).set_format 0, fmt
1000
1028
  sheet1[6,1] = Date.new 2008, 10, 10
1001
1029
  sheet1[6,2] = Date.new 2008, 10, 12
1002
- fmt = Format.new :number_format => "D\0D\0.\0M\0M\0.\0Y\0Y\0Y\0Y\0"
1030
+ fmt = Format.new :number_format => @@iconv.iconv("DD.MM.YYYY")
1003
1031
  sheet1.row(6).set_format 1, fmt
1004
1032
  sheet1.update_row 7, nil, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0
1005
1033
  sheet1.row(8).default_format = fmt
1006
1034
  sheet1[8,0] = @@iconv.iconv 'formatted when empty'
1007
- sheet2 = book.create_worksheet :name => "m\0y\0 \0n\0a\0m\0e\0"
1035
+ sheet2 = book.create_worksheet :name => @@iconv.iconv("my name")
1008
1036
  book.write path
1009
1037
  Spreadsheet.client_encoding = 'UTF-8'
1010
1038
  str1 = 'Shared String'
@@ -1012,7 +1040,11 @@ module Spreadsheet
1012
1040
  str3 = '1234567890 ' * 1000
1013
1041
  str4 = '9876543210 ' * 1000
1014
1042
  assert_nothing_raised do book = Spreadsheet.open path end
1015
- assert_equal 'UTF-16LE', book.encoding
1043
+ if RUBY_VERSION >= '1.9'
1044
+ assert_equal 'UTF-16LE', book.encoding.name
1045
+ else
1046
+ assert_equal 'UTF-16LE', book.encoding
1047
+ end
1016
1048
  assert_equal str1, book.shared_string(0)
1017
1049
  assert_equal str2, book.shared_string(1)
1018
1050
  test = book.shared_string 2
@@ -1153,5 +1185,54 @@ module Spreadsheet
1153
1185
  assert_equal smallnum - 0.1, book.worksheet(0)[0,3]
1154
1186
  assert_equal(-smallnum - 0.1, book.worksheet(0)[1,3])
1155
1187
  end
1188
+ def test_bigfloat
1189
+ # reported in http://rubyforge.org/tracker/index.php?func=detail&aid=24119&group_id=678&atid=2677
1190
+ bigfloat = 10000000.0
1191
+ book = Spreadsheet::Workbook.new
1192
+ sheet = book.create_worksheet
1193
+ sheet[0,0] = bigfloat
1194
+ sheet[0,1] = bigfloat + 0.1
1195
+ sheet[0,2] = bigfloat - 0.1
1196
+ sheet[1,0] = -bigfloat
1197
+ sheet[1,1] = -bigfloat + 0.1
1198
+ sheet[1,2] = -bigfloat - 0.1
1199
+ path = File.join @var, 'test_big-float.xls'
1200
+ book.write path
1201
+ assert_nothing_raised do
1202
+ book = Spreadsheet.open path
1203
+ end
1204
+ sheet = book.worksheet(0)
1205
+ assert_equal bigfloat, sheet[0,0]
1206
+ assert_equal bigfloat + 0.1, sheet[0,1]
1207
+ assert_equal bigfloat - 0.1, sheet[0,2]
1208
+ assert_equal(-bigfloat, sheet[1,0])
1209
+ assert_equal(-bigfloat + 0.1, sheet[1,1])
1210
+ assert_equal(-bigfloat - 0.1, sheet[1,2])
1211
+ end
1212
+ def test_datetime__off_by_one
1213
+ # reported in http://rubyforge.org/tracker/index.php?func=detail&aid=24414&group_id=678&atid=2677
1214
+ datetime1 = DateTime.new(2008)
1215
+ datetime2 = DateTime.new(2008, 1, 1, 1, 0, 1)
1216
+ date1 = Date.new(2008)
1217
+ date2 = Date.new(2009)
1218
+ book = Spreadsheet::Workbook.new
1219
+ sheet = book.create_worksheet
1220
+ sheet[0,0] = datetime1
1221
+ sheet[0,1] = datetime2
1222
+ sheet[1,0] = date1
1223
+ sheet[1,1] = date2
1224
+ path = File.join @var, 'test_datetime.xls'
1225
+ book.write path
1226
+ assert_nothing_raised do
1227
+ book = Spreadsheet.open path
1228
+ end
1229
+ sheet = book.worksheet(0)
1230
+ assert_equal datetime1, sheet[0,0]
1231
+ assert_equal datetime2, sheet[0,1]
1232
+ assert_equal date1, sheet[1,0]
1233
+ assert_equal date2, sheet[1,1]
1234
+ assert_equal date1, sheet.row(0).date(0)
1235
+ assert_equal datetime1, sheet.row(1).datetime(0)
1236
+ end
1156
1237
  end
1157
1238
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spreadsheet
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.3.1
4
+ version: 0.6.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hannes Wyss
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-02-13 00:00:00 +01:00
12
+ date: 2009-07-03 00:00:00 +02:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -58,6 +58,7 @@ files:
58
58
  - lib/parseexcel/parser.rb
59
59
  - lib/spreadsheet.rb
60
60
  - lib/spreadsheet/column.rb
61
+ - lib/spreadsheet/compatibility.rb
61
62
  - lib/spreadsheet/datatypes.rb
62
63
  - lib/spreadsheet/encodings.rb
63
64
  - lib/spreadsheet/excel.rb