spreadsheet 0.6.3.1 → 0.6.4
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.
- data/History.txt +32 -0
- data/Manifest.txt +1 -0
- data/lib/spreadsheet.rb +1 -1
- data/lib/spreadsheet/compatibility.rb +23 -0
- data/lib/spreadsheet/datatypes.rb +9 -6
- data/lib/spreadsheet/encodings.rb +16 -5
- data/lib/spreadsheet/excel/offset.rb +8 -4
- data/lib/spreadsheet/excel/reader.rb +14 -5
- data/lib/spreadsheet/excel/row.rb +8 -7
- data/lib/spreadsheet/excel/workbook.rb +1 -1
- data/lib/spreadsheet/excel/writer/biff8.rb +2 -1
- data/lib/spreadsheet/excel/writer/workbook.rb +1 -1
- data/lib/spreadsheet/excel/writer/worksheet.rb +24 -11
- data/lib/spreadsheet/font.rb +13 -11
- data/lib/spreadsheet/format.rb +5 -4
- data/lib/spreadsheet/link.rb +3 -1
- data/lib/spreadsheet/row.rb +12 -5
- data/lib/spreadsheet/worksheet.rb +2 -3
- data/lib/spreadsheet/writer.rb +1 -0
- data/test/excel/writer/worksheet.rb +1 -0
- data/test/font.rb +1 -1
- data/test/integration.rb +104 -23
- metadata +3 -2
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
data/lib/spreadsheet.rb
CHANGED
@@ -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 =
|
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(
|
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
|
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 =
|
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(
|
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
|
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,
|
10
|
-
string.
|
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,
|
21
|
-
key = [
|
22
|
-
iconv = @@iconvs[key] ||= Iconv.new(
|
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
|
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
|
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
|
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
|
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]
|
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 =
|
773
|
+
@workbook.date_base = DateTime.new 1904, 1, 1
|
774
774
|
else
|
775
|
-
@workbook.date_base =
|
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
|
-
|
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
|
-
|
49
|
-
|
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
|
-
|
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
|
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:
|
@@ -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.
|
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 |
|
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
|
-
|
52
|
-
|
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
|
-
|
90
|
-
|
91
|
-
|
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 <<
|
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 <<
|
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 <<
|
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 <<
|
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
|
-
|
709
|
+
height * TWIPS
|
697
710
|
end
|
698
711
|
# TODO: Row spacing
|
699
712
|
data = [
|
data/lib/spreadsheet/font.rb
CHANGED
@@ -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
|
-
|
77
|
-
key <<
|
78
|
-
key << '
|
79
|
-
key << '
|
80
|
-
key << '
|
81
|
-
key << '
|
82
|
-
key << '
|
83
|
-
key <<
|
84
|
-
key <<
|
85
|
-
key <<
|
86
|
-
key <<
|
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
|
data/lib/spreadsheet/format.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
174
|
+
!!Regexp.new(client("[hms]", 'UTF-8')).match(@number_format.to_s)
|
174
175
|
end
|
175
176
|
end
|
176
177
|
end
|
data/lib/spreadsheet/link.rb
CHANGED
@@ -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
|
data/lib/spreadsheet/row.rb
CHANGED
@@ -33,11 +33,18 @@ module Spreadsheet
|
|
33
33
|
end
|
34
34
|
def updater *keys
|
35
35
|
keys.each do |key|
|
36
|
-
define_method
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
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
|
236
|
-
|
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:
|
data/lib/spreadsheet/writer.rb
CHANGED
data/test/font.rb
CHANGED
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
|
-
|
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].
|
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].
|
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].
|
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].
|
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].
|
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].
|
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
|
-
|
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
|
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 |
|
586
|
-
assert_equal useds.shift,
|
587
|
-
assert_equal unuseds.shift,
|
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 |
|
695
|
-
assert_equal useds.shift,
|
696
|
-
assert_equal unuseds.shift,
|
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
|
-
|
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
|
-
|
877
|
-
|
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
|
-
|
972
|
-
|
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 => "
|
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 => "
|
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
|
-
|
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.
|
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-
|
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
|