spreadsheet 0.7.1 → 0.7.2
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 +5 -0
- data/lib/spreadsheet.rb +1 -1
- data/lib/spreadsheet/excel/writer/format.rb +0 -1
- data/lib/spreadsheet/excel/writer/n_worksheet.rb +5 -3
- data/lib/spreadsheet/excel/writer/workbook.rb +29 -23
- data/lib/spreadsheet/excel/writer/worksheet.rb +5 -3
- data/lib/spreadsheet/font.rb +14 -2
- data/lib/spreadsheet/format.rb +10 -4
- data/lib/spreadsheet/workbook.rb +6 -2
- data/lib/spreadsheet/worksheet.rb +13 -5
- data/test/excel/writer/workbook.rb +77 -5
- data/test/excel/writer/worksheet.rb +26 -0
- data/test/integration.rb +60 -161
- data/test/workbook.rb +15 -0
- data/test/worksheet.rb +32 -0
- metadata +8 -8
data/History.txt
CHANGED
data/lib/spreadsheet.rb
CHANGED
@@ -30,7 +30,6 @@ class Format < DelegateClass Spreadsheet::Format
|
|
30
30
|
color :diagonal_color, :border
|
31
31
|
color :pattern_fg_color, :pattern_bg
|
32
32
|
color :pattern_bg_color, :pattern_bg
|
33
|
-
attr_accessor :xf_index
|
34
33
|
attr_reader :format
|
35
34
|
def initialize writer, workbook, format=workbook.default_format, opts={}
|
36
35
|
@opts = { :type => :format }.merge opts
|
@@ -118,9 +118,11 @@ class Worksheet
|
|
118
118
|
@io.size
|
119
119
|
end
|
120
120
|
def strings
|
121
|
-
@worksheet.inject
|
122
|
-
|
123
|
-
|
121
|
+
@worksheet.inject(Hash.new(0)) do |memo, row|
|
122
|
+
row.each do |cell|
|
123
|
+
memo[cell] += 1 if (cell.is_a?(String) && !cell.empty?)
|
124
|
+
end
|
125
|
+
memo
|
124
126
|
end
|
125
127
|
end
|
126
128
|
##
|
@@ -64,26 +64,33 @@ class Workbook < Spreadsheet::Writer
|
|
64
64
|
workbook.formats.each do |fmt|
|
65
65
|
formats.push Format.new(self, workbook, fmt)
|
66
66
|
end
|
67
|
+
@formats[workbook] = {
|
68
|
+
:writers => [],
|
69
|
+
:xf_indexes => {}
|
70
|
+
}
|
67
71
|
formats.each_with_index do |fmt, idx|
|
68
|
-
|
72
|
+
@formats[workbook][:writers] << fmt
|
73
|
+
@formats[workbook][:xf_indexes][fmt.format] ||= idx
|
69
74
|
end
|
70
|
-
@formats[workbook] = formats
|
71
75
|
end
|
72
76
|
def complete_sst_update? workbook
|
73
77
|
stored = workbook.sst.collect do |entry| entry.content end
|
74
|
-
|
75
|
-
|
78
|
+
num_total = 0
|
79
|
+
current = worksheets(workbook).inject(Hash.new(0)) do |memo, worksheet|
|
80
|
+
worksheet.strings.each do |k,v|
|
81
|
+
memo[k] += v
|
82
|
+
num_total += v
|
83
|
+
end
|
84
|
+
memo
|
76
85
|
end
|
77
|
-
total = current.size
|
78
|
-
current.uniq!
|
79
86
|
current.delete ''
|
80
|
-
if
|
87
|
+
if !stored.empty? && stored.all?{|x| current.include?(x) }
|
81
88
|
## if all previously stored strings are still needed, we don't have to
|
82
89
|
# rewrite all cells because the sst-index of such string does not change.
|
83
|
-
additions = current - stored
|
84
|
-
[:partial_update,
|
90
|
+
additions = current.keys - stored
|
91
|
+
[:partial_update, num_total, stored + additions]
|
85
92
|
else
|
86
|
-
[:complete_update,
|
93
|
+
[:complete_update, num_total, current.keys]
|
87
94
|
end
|
88
95
|
end
|
89
96
|
def font_index workbook, font_key
|
@@ -349,8 +356,8 @@ class Workbook < Spreadsheet::Writer
|
|
349
356
|
end
|
350
357
|
def write_fonts workbook, writer
|
351
358
|
fonts = @fonts[workbook] = {}
|
352
|
-
@formats[workbook].each do |
|
353
|
-
|
359
|
+
@formats[workbook][:writers].map{|format| format.font }.compact.uniq.each do |font|
|
360
|
+
unless fonts.include?(font.key)
|
354
361
|
fonts.store font.key, fonts.size
|
355
362
|
write_font workbook, writer, font
|
356
363
|
end
|
@@ -482,12 +489,15 @@ class Workbook < Spreadsheet::Writer
|
|
482
489
|
# 0 4 Total number of strings in the workbook (see below)
|
483
490
|
# 4 4 Number of following strings (nm)
|
484
491
|
# 8 var. List of nm Unicode strings, 16-bit string length (➜ 3.4)
|
485
|
-
|
486
|
-
|
492
|
+
num_total = 0
|
493
|
+
strings = worksheets(workbook).inject(Hash.new(0)) do |memo, worksheet|
|
494
|
+
worksheet.strings.each do |k,v|
|
495
|
+
memo[k] += v
|
496
|
+
num_total += v
|
497
|
+
end
|
498
|
+
memo
|
487
499
|
end
|
488
|
-
|
489
|
-
strings.uniq!
|
490
|
-
_write_sst workbook, writer, offset, total, strings
|
500
|
+
_write_sst workbook, writer, offset, num_total, strings.keys
|
491
501
|
end
|
492
502
|
def _write_sst workbook, writer, offset, total, strings
|
493
503
|
sst = {}
|
@@ -635,17 +645,13 @@ class Workbook < Spreadsheet::Writer
|
|
635
645
|
# the XF record with the fixed index 15 (0-based). By default, it uses the
|
636
646
|
# worksheet/workbook default cell style, described by the very first XF
|
637
647
|
# record (index 0).
|
638
|
-
@formats[workbook].each do |fmt| fmt.write_xf writer end
|
648
|
+
@formats[workbook][:writers].each do |fmt| fmt.write_xf writer end
|
639
649
|
end
|
640
650
|
def sst_index worksheet, str
|
641
651
|
@sst[worksheet][str]
|
642
652
|
end
|
643
653
|
def xf_index workbook, format
|
644
|
-
|
645
|
-
fmt.xf_index
|
646
|
-
else
|
647
|
-
0
|
648
|
-
end
|
654
|
+
@formats[workbook][:xf_indexes][format] || 0
|
649
655
|
end
|
650
656
|
end
|
651
657
|
end
|
@@ -118,9 +118,11 @@ class Worksheet
|
|
118
118
|
@io.size
|
119
119
|
end
|
120
120
|
def strings
|
121
|
-
@worksheet.inject
|
122
|
-
|
123
|
-
|
121
|
+
@worksheet.inject(Hash.new(0)) do |memo, row|
|
122
|
+
row.each do |cell|
|
123
|
+
memo[cell] += 1 if (cell.is_a?(String) && !cell.empty?)
|
124
|
+
end
|
125
|
+
memo
|
124
126
|
end
|
125
127
|
end
|
126
128
|
##
|
data/lib/spreadsheet/font.rb
CHANGED
@@ -74,10 +74,18 @@ module Spreadsheet
|
|
74
74
|
self.weight = bool ? :bold : nil
|
75
75
|
end
|
76
76
|
def key # :nodoc:
|
77
|
-
|
77
|
+
fk = fast_key
|
78
|
+
return @key if @previous_fast_key == fk
|
79
|
+
@previous_fast_key = fk
|
80
|
+
@key = build_key
|
81
|
+
end
|
82
|
+
private
|
83
|
+
def build_key # :nodoc:
|
78
84
|
underscore = client('_', 'UTF-8')
|
85
|
+
key = []
|
86
|
+
key << @name
|
79
87
|
key << underscore << client(size.to_s, 'US-ASCII')
|
80
|
-
key <<
|
88
|
+
key << underscore << client(weight.to_s, 'US-ASCII')
|
81
89
|
key << client('_italic', 'UTF-8') if italic?
|
82
90
|
key << client('_strikeout', 'UTF-8') if strikeout?
|
83
91
|
key << client('_outline', 'UTF-8') if outline?
|
@@ -87,6 +95,10 @@ module Spreadsheet
|
|
87
95
|
key << underscore << client(color.to_s, 'US-ASCII')
|
88
96
|
key << underscore << client(family.to_s, 'US-ASCII')
|
89
97
|
key << underscore << client(encoding.to_s, 'US-ASCII')
|
98
|
+
key.join("")
|
99
|
+
end
|
100
|
+
def fast_key
|
101
|
+
[@name, @size, @weight, @italic, @strikeout, @outline, @shadow, @escapement, @underline, @color, @family, @encoding]
|
90
102
|
end
|
91
103
|
end
|
92
104
|
end
|
data/lib/spreadsheet/format.rb
CHANGED
@@ -84,6 +84,12 @@ module Spreadsheet
|
|
84
84
|
@diagonal_color = :builtin_black
|
85
85
|
@pattern_fg_color = :border
|
86
86
|
@pattern_bg_color = :pattern_bg
|
87
|
+
@regexes = {
|
88
|
+
:date => Regexp.new(client("[YMD]", 'UTF-8')),
|
89
|
+
:date_or_time => Regexp.new(client("[hmsYMD]", 'UTF-8')),
|
90
|
+
:datetime => Regexp.new(client("([YMD].*[HS])|([HS].*[YMD])", 'UTF-8')),
|
91
|
+
:time => Regexp.new(client("[hms]", 'UTF-8'))
|
92
|
+
}
|
87
93
|
# Temp code to prevent merged formats in non-merged cells.
|
88
94
|
@used_merge = 0
|
89
95
|
opts.each do |key, val|
|
@@ -156,22 +162,22 @@ module Spreadsheet
|
|
156
162
|
##
|
157
163
|
# Is the cell formatted as a Date?
|
158
164
|
def date?
|
159
|
-
|
165
|
+
!!@regexes[:date].match(@number_format.to_s)
|
160
166
|
end
|
161
167
|
##
|
162
168
|
# Is the cell formatted as a Date or Time?
|
163
169
|
def date_or_time?
|
164
|
-
|
170
|
+
!!@regexes[:date_or_time].match(@number_format.to_s)
|
165
171
|
end
|
166
172
|
##
|
167
173
|
# Is the cell formatted as a DateTime?
|
168
174
|
def datetime?
|
169
|
-
|
175
|
+
!!@regexes[:datetime].match(@number_format.to_s)
|
170
176
|
end
|
171
177
|
##
|
172
178
|
# Is the cell formatted as a Time?
|
173
179
|
def time?
|
174
|
-
|
180
|
+
!!@regexes[:time].match(@number_format.to_s)
|
175
181
|
end
|
176
182
|
end
|
177
183
|
end
|
data/lib/spreadsheet/workbook.rb
CHANGED
@@ -19,8 +19,9 @@ module Spreadsheet
|
|
19
19
|
@io = io
|
20
20
|
@fonts = []
|
21
21
|
@formats = []
|
22
|
+
@formats_set = {}
|
22
23
|
if @default_format = opts[:default_format]
|
23
|
-
|
24
|
+
add_format @default_format
|
24
25
|
end
|
25
26
|
end
|
26
27
|
##
|
@@ -34,7 +35,10 @@ module Spreadsheet
|
|
34
35
|
# Add a Format to the Workbook. If you use Row#set_format, you should not
|
35
36
|
# need to use this Method.
|
36
37
|
def add_format format
|
37
|
-
|
38
|
+
if format && !@formats_set[format]
|
39
|
+
@formats_set[format] = true
|
40
|
+
@formats.push(format)
|
41
|
+
end
|
38
42
|
format
|
39
43
|
end
|
40
44
|
##
|
@@ -167,22 +167,30 @@ module Spreadsheet
|
|
167
167
|
# - 'DD.MM.YYYY' for Date
|
168
168
|
# - 'DD.MM.YYYY hh:mm:ss' for DateTime and Time
|
169
169
|
def format_dates! format=nil
|
170
|
+
new_formats = {}
|
171
|
+
fmt_str_time = client('DD.MM.YYYY hh:mm:ss', 'UTF-8')
|
172
|
+
fmt_str_date = client('DD.MM.YYYY', 'UTF-8')
|
170
173
|
each do |row|
|
171
174
|
row.each_with_index do |value, idx|
|
172
175
|
unless row.formats[idx] || row.format(idx).date_or_time?
|
173
176
|
numfmt = case value
|
174
177
|
when DateTime, Time
|
175
|
-
format ||
|
178
|
+
format || fmt_str_time
|
176
179
|
when Date
|
177
|
-
format ||
|
180
|
+
format || fmt_str_date
|
178
181
|
end
|
179
182
|
case numfmt
|
180
183
|
when Format
|
181
184
|
row.set_format idx, numfmt
|
182
185
|
when String
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
+
existing_format = row.format(idx)
|
187
|
+
new_formats[existing_format] ||= {}
|
188
|
+
new_format = new_formats[existing_format][numfmt]
|
189
|
+
if !new_format
|
190
|
+
new_format = new_formats[existing_format][numfmt] = existing_format.dup
|
191
|
+
new_format.number_format = numfmt
|
192
|
+
end
|
193
|
+
row.set_format idx, new_format
|
186
194
|
end
|
187
195
|
end
|
188
196
|
end
|
@@ -10,12 +10,84 @@ module Spreadsheet
|
|
10
10
|
module Excel
|
11
11
|
module Writer
|
12
12
|
class TestWorkbook < Test::Unit::TestCase
|
13
|
+
def setup
|
14
|
+
@book = Spreadsheet::Excel::Workbook.new
|
15
|
+
assert_instance_of Excel::Workbook, @book
|
16
|
+
assert_equal @book.worksheets.size, 0
|
17
|
+
@workbook_writer = Excel::Writer::Workbook.new @book
|
18
|
+
end
|
13
19
|
def test_sanitize_worksheets
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
20
|
+
assert_nothing_raised { @workbook_writer.sanitize_worksheets @book.worksheets }
|
21
|
+
end
|
22
|
+
def test_collect_formats
|
23
|
+
assert_equal 17, @workbook_writer.collect_formats(@book).length # Expected for vanilla
|
24
|
+
sheet = @book.create_worksheet
|
25
|
+
rowi=-1
|
26
|
+
|
27
|
+
f1 = Spreadsheet::Format.new
|
28
|
+
sheet.row(rowi+=1).default_format = f1
|
29
|
+
assert_equal 18, @workbook_writer.collect_formats(@book).length
|
30
|
+
|
31
|
+
f2 = Spreadsheet::Format.new
|
32
|
+
sheet.row(rowi+=1).default_format = f2
|
33
|
+
assert_equal 19, @workbook_writer.collect_formats(@book).length
|
34
|
+
|
35
|
+
sheet.row(rowi+=1).default_format = f2
|
36
|
+
assert_equal 19, @workbook_writer.collect_formats(@book).length # Ignores duplicates
|
37
|
+
end
|
38
|
+
def test_xf_index
|
39
|
+
sheet = @book.create_worksheet
|
40
|
+
rowi=-1
|
41
|
+
|
42
|
+
f1 = Spreadsheet::Format.new
|
43
|
+
sheet.row(rowi+=1).default_format = f1
|
44
|
+
@workbook_writer.collect_formats(@book)
|
45
|
+
assert_equal 17, @workbook_writer.xf_index(@book, f1)
|
46
|
+
|
47
|
+
f2 = Spreadsheet::Format.new
|
48
|
+
sheet.row(rowi+=1).default_format = f2
|
49
|
+
@workbook_writer.collect_formats(@book)
|
50
|
+
assert_equal 18, @workbook_writer.xf_index(@book, f2)
|
51
|
+
|
52
|
+
end
|
53
|
+
def test_write_fonts
|
54
|
+
num_written = 0
|
55
|
+
sheet = @book.create_worksheet
|
56
|
+
rowi=-1
|
57
|
+
# Stub inner #write_font as a counter:
|
58
|
+
(class << @workbook_writer; self; end).send(:define_method, :write_font) do |*args|
|
59
|
+
num_written += 1
|
60
|
+
end
|
61
|
+
io = StringIO.new("")
|
62
|
+
|
63
|
+
num_written = 0
|
64
|
+
@workbook_writer.collect_formats(@book)
|
65
|
+
@workbook_writer.write_fonts(@book, io)
|
66
|
+
assert_equal 1, num_written # Default format's font
|
67
|
+
|
68
|
+
f1 = Spreadsheet::Format.new
|
69
|
+
sheet.row(rowi+=1).default_format = f1
|
70
|
+
num_written = 0
|
71
|
+
@workbook_writer.collect_formats(@book)
|
72
|
+
@workbook_writer.write_fonts(@book, io)
|
73
|
+
assert_equal 1, num_written # No new fonts
|
74
|
+
|
75
|
+
f2 = Spreadsheet::Format.new
|
76
|
+
f2.font = Spreadsheet::Font.new("Foo")
|
77
|
+
sheet.row(rowi+=1).default_format = f2
|
78
|
+
num_written = 0
|
79
|
+
@workbook_writer.collect_formats(@book)
|
80
|
+
@workbook_writer.write_fonts(@book, io)
|
81
|
+
assert_equal 2, num_written # 2 distinct fonts total
|
82
|
+
|
83
|
+
f3 = Spreadsheet::Format.new
|
84
|
+
f3.font = f2.font # Re-use previous font
|
85
|
+
sheet.row(rowi+=1).default_format = f3
|
86
|
+
num_written = 0
|
87
|
+
@workbook_writer.collect_formats(@book)
|
88
|
+
@workbook_writer.write_fonts(@book, io)
|
89
|
+
assert_equal 2, num_written # 2 distinct fonts total still
|
90
|
+
|
19
91
|
end
|
20
92
|
end
|
21
93
|
end
|
@@ -49,6 +49,32 @@ module Spreadsheet
|
|
49
49
|
|
50
50
|
assert_equal false, sheet.data.empty?
|
51
51
|
end
|
52
|
+
|
53
|
+
def test_strings
|
54
|
+
book = Spreadsheet::Excel::Workbook.new
|
55
|
+
sheet = book.create_worksheet
|
56
|
+
writer = Worksheet.new book, sheet
|
57
|
+
rowi = -1
|
58
|
+
|
59
|
+
assert_equal(
|
60
|
+
{},
|
61
|
+
writer.strings
|
62
|
+
)
|
63
|
+
|
64
|
+
sheet.row(rowi+=1).concat(["Hello", "World"])
|
65
|
+
assert_equal(
|
66
|
+
{"Hello" => 1, "World" => 1},
|
67
|
+
writer.strings
|
68
|
+
)
|
69
|
+
|
70
|
+
sheet.row(rowi+=1).concat(["Goodbye", "Cruel", "World", 2012])
|
71
|
+
assert_equal(
|
72
|
+
{"Hello" => 1, "Goodbye" => 1, "Cruel" => 1, "World" => 2},
|
73
|
+
writer.strings
|
74
|
+
)
|
75
|
+
|
76
|
+
end
|
77
|
+
|
52
78
|
end
|
53
79
|
end
|
54
80
|
end
|
data/test/integration.rb
CHANGED
@@ -106,33 +106,11 @@ module Spreadsheet
|
|
106
106
|
assert_equal enc, book.encoding
|
107
107
|
assert_equal 25, book.formats.size
|
108
108
|
assert_equal 5, book.fonts.size
|
109
|
-
str1 =
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
str3 = book.shared_string 2
|
115
|
-
long = @@iconv.iconv('1234567890 ' * 1000)
|
116
|
-
if str3 != long
|
117
|
-
long.size.times do |idx|
|
118
|
-
len = idx.next
|
119
|
-
if str3[0,len] != long[0,len]
|
120
|
-
assert_equal long[idx - 5, 10], str3[idx - 5, 10], "in position #{idx}"
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
124
|
-
assert_equal long, str3
|
125
|
-
str4 = book.shared_string 3
|
126
|
-
long = @@iconv.iconv('9876543210 ' * 1000)
|
127
|
-
if str4 != long
|
128
|
-
long.size.times do |idx|
|
129
|
-
len = idx.next
|
130
|
-
if str4[0,len] != long[0,len]
|
131
|
-
assert_equal long[idx - 5, 10], str4[idx - 5, 10], "in position #{idx}"
|
132
|
-
end
|
133
|
-
end
|
134
|
-
end
|
135
|
-
assert_equal long, str4
|
109
|
+
str1 = @@iconv.iconv('Shared String')
|
110
|
+
str2 = @@iconv.iconv('Another Shared String')
|
111
|
+
str3 = @@iconv.iconv('1234567890 ' * 1000)
|
112
|
+
str4 = @@iconv.iconv('9876543210 ' * 1000)
|
113
|
+
assert_valid_sst(book, :contains => [str1, str2, str3, str4])
|
136
114
|
sheet = book.worksheet 0
|
137
115
|
assert_equal 11, sheet.row_count
|
138
116
|
assert_equal 12, sheet.column_count
|
@@ -211,32 +189,11 @@ module Spreadsheet
|
|
211
189
|
assert_equal enc, book.encoding
|
212
190
|
assert_equal 25, book.formats.size
|
213
191
|
assert_equal 5, book.fonts.size
|
214
|
-
str1 =
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
long = '1234567890 ' * 1000
|
220
|
-
if str3 != long
|
221
|
-
long.size.times do |idx|
|
222
|
-
len = idx.next
|
223
|
-
if str3[0,len] != long[0,len]
|
224
|
-
assert_equal long[idx - 5, 10], str3[idx - 5, 10], "in position #{idx}"
|
225
|
-
end
|
226
|
-
end
|
227
|
-
end
|
228
|
-
assert_equal long, str3
|
229
|
-
str4 = book.shared_string 3
|
230
|
-
long = '9876543210 ' * 1000
|
231
|
-
if str4 != long
|
232
|
-
long.size.times do |idx|
|
233
|
-
len = idx.next
|
234
|
-
if str4[0,len] != long[0,len]
|
235
|
-
assert_equal long[idx - 5, 10], str4[idx - 5, 10], "in position #{idx}"
|
236
|
-
end
|
237
|
-
end
|
238
|
-
end
|
239
|
-
assert_equal long, str4
|
192
|
+
str1 = 'Shared String'
|
193
|
+
str2 = 'Another Shared String'
|
194
|
+
str3 = '1234567890 ' * 1000
|
195
|
+
str4 = '9876543210 ' * 1000
|
196
|
+
assert_valid_sst(book, :contains => [str1, str2, str3, str4])
|
240
197
|
sheet = book.worksheet 0
|
241
198
|
assert_equal 11, sheet.row_count
|
242
199
|
assert_equal 12, sheet.column_count
|
@@ -601,32 +558,12 @@ module Spreadsheet
|
|
601
558
|
assert_equal 8, book.biff_version
|
602
559
|
assert_equal 'Microsoft Excel 97/2000/XP', book.version_string
|
603
560
|
path = File.join @var, 'test_change_cell.xls'
|
604
|
-
str1 =
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
if str3 != long
|
611
|
-
long.size.times do |idx|
|
612
|
-
len = idx.next
|
613
|
-
if str3[0,len] != long[0,len]
|
614
|
-
assert_equal long[idx - 5, 10], str3[idx - 5, 10], "in position #{idx}"
|
615
|
-
end
|
616
|
-
end
|
617
|
-
end
|
618
|
-
assert_equal long, str3
|
619
|
-
str4 = book.shared_string 3
|
620
|
-
long = '9876543210 ' * 1000
|
621
|
-
if str4 != long
|
622
|
-
long.size.times do |idx|
|
623
|
-
len = idx.next
|
624
|
-
if str4[0,len] != long[0,len]
|
625
|
-
assert_equal long[idx - 5, 10], str4[idx - 5, 10], "in position #{idx}"
|
626
|
-
end
|
627
|
-
end
|
628
|
-
end
|
629
|
-
assert_equal long, str4
|
561
|
+
str1 = 'Shared String'
|
562
|
+
str2 = 'Another Shared String'
|
563
|
+
str3 = '1234567890 ' * 1000
|
564
|
+
str4 = '9876543210 ' * 1000
|
565
|
+
str5 = "Link-Text"
|
566
|
+
assert_valid_sst(book, :is => [str1, str2, str3, str4, str5])
|
630
567
|
sheet = book.worksheet 0
|
631
568
|
sheet[0,0] = 4
|
632
569
|
row = sheet.row 1
|
@@ -704,44 +641,21 @@ module Spreadsheet
|
|
704
641
|
assert_equal 8, book.biff_version
|
705
642
|
assert_equal 'Microsoft Excel 97/2000/XP', book.version_string
|
706
643
|
path = File.join @var, 'test_change_cell.xls'
|
707
|
-
str1 =
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
if str3 != long
|
714
|
-
long.size.times do |idx|
|
715
|
-
len = idx.next
|
716
|
-
if str3[0,len] != long[0,len]
|
717
|
-
assert_equal long[idx - 5, 10], str3[idx - 5, 10], "in position #{idx}"
|
718
|
-
end
|
719
|
-
end
|
720
|
-
end
|
721
|
-
assert_equal long, str3
|
722
|
-
str4 = book.shared_string 3
|
723
|
-
long = '9876543210 ' * 1000
|
724
|
-
if str4 != long
|
725
|
-
long.size.times do |idx|
|
726
|
-
len = idx.next
|
727
|
-
if str4[0,len] != long[0,len]
|
728
|
-
assert_equal long[idx - 5, 10], str4[idx - 5, 10], "in position #{idx}"
|
729
|
-
end
|
730
|
-
end
|
731
|
-
end
|
732
|
-
assert_equal long, str4
|
644
|
+
str1 = 'Shared String'
|
645
|
+
str2 = 'Another Shared String'
|
646
|
+
str3 = '1234567890 ' * 1000
|
647
|
+
str4 = '9876543210 ' * 1000
|
648
|
+
str5 = 'Link-Text'
|
649
|
+
assert_valid_sst(book, :is => [str1, str2, str3, str4, str5])
|
733
650
|
sheet = book.worksheet 0
|
734
651
|
sheet[0,0] = 4
|
735
|
-
|
736
|
-
sheet[0,1] =
|
652
|
+
str6 = 'A completely different String'
|
653
|
+
sheet[0,1] = str6
|
737
654
|
row = sheet.row 1
|
738
655
|
row[0] = 3
|
739
656
|
book.write path
|
740
657
|
assert_nothing_raised do book = Spreadsheet.open path end
|
741
|
-
|
742
|
-
assert_equal str2, book.shared_string(1)
|
743
|
-
assert_equal str3, book.shared_string(2)
|
744
|
-
assert_equal str4, book.shared_string(3)
|
658
|
+
assert_valid_sst(book, :is => [str2, str3, str4, str5, str6])
|
745
659
|
sheet = book.worksheet 0
|
746
660
|
assert_equal 11, sheet.row_count
|
747
661
|
assert_equal 12, sheet.column_count
|
@@ -756,9 +670,9 @@ module Spreadsheet
|
|
756
670
|
assert_equal 4, row[0]
|
757
671
|
assert_equal 4, sheet[0,0]
|
758
672
|
assert_equal 4, sheet.cell(0,0)
|
759
|
-
assert_equal
|
760
|
-
assert_equal
|
761
|
-
assert_equal
|
673
|
+
assert_equal str6, row[1]
|
674
|
+
assert_equal str6, sheet[0,1]
|
675
|
+
assert_equal str6, sheet.cell(0,1)
|
762
676
|
row = sheet.row 1
|
763
677
|
assert_equal 3, row[0]
|
764
678
|
assert_equal 3, sheet[1,0]
|
@@ -905,31 +819,7 @@ module Spreadsheet
|
|
905
819
|
else
|
906
820
|
assert_equal 'UTF-16LE', book.encoding
|
907
821
|
end
|
908
|
-
|
909
|
-
assert_equal str2, book.shared_string(1)
|
910
|
-
test = nil
|
911
|
-
assert_nothing_raised "I've probably split a two-byte-character" do
|
912
|
-
test = book.shared_string 2
|
913
|
-
end
|
914
|
-
if test != str3
|
915
|
-
str3.size.times do |idx|
|
916
|
-
len = idx.next
|
917
|
-
if test[0,len] != str3[0,len]
|
918
|
-
assert_equal str3[idx - 5, 10], test[idx - 5, 10], "in position #{idx}"
|
919
|
-
end
|
920
|
-
end
|
921
|
-
end
|
922
|
-
assert_equal str3, test
|
923
|
-
test = book.shared_string 3
|
924
|
-
if test != str4
|
925
|
-
str4.size.times do |idx|
|
926
|
-
len = idx.next
|
927
|
-
if test[0,len] != str4[0,len]
|
928
|
-
assert_equal str4[idx - 5, 10], test[idx - 5, 10], "in position #{idx}"
|
929
|
-
end
|
930
|
-
end
|
931
|
-
end
|
932
|
-
assert_equal str4, test
|
822
|
+
assert_valid_sst(book, :contains => [str1, str2, str3, str4])
|
933
823
|
assert_equal 2, book.worksheets.size
|
934
824
|
sheet = book.worksheets.first
|
935
825
|
assert_instance_of Spreadsheet::Excel::Worksheet, sheet
|
@@ -1080,28 +970,7 @@ module Spreadsheet
|
|
1080
970
|
else
|
1081
971
|
assert_equal 'UTF-16LE', book.encoding
|
1082
972
|
end
|
1083
|
-
|
1084
|
-
assert_equal str2, book.shared_string(1)
|
1085
|
-
test = book.shared_string 2
|
1086
|
-
if test != str3
|
1087
|
-
str3.size.times do |idx|
|
1088
|
-
len = idx.next
|
1089
|
-
if test[0,len] != str3[0,len]
|
1090
|
-
assert_equal str3[idx - 5, 10], test[idx - 5, 10], "in position #{idx}"
|
1091
|
-
end
|
1092
|
-
end
|
1093
|
-
end
|
1094
|
-
assert_equal str3, test
|
1095
|
-
test = book.shared_string 3
|
1096
|
-
if test != str4
|
1097
|
-
str4.size.times do |idx|
|
1098
|
-
len = idx.next
|
1099
|
-
if test[0,len] != str4[0,len]
|
1100
|
-
assert_equal str4[idx - 5, 10], test[idx - 5, 10], "in position #{idx}"
|
1101
|
-
end
|
1102
|
-
end
|
1103
|
-
end
|
1104
|
-
assert_equal str4, test
|
973
|
+
assert_valid_sst(book, :is => [str1, str2, str3, str4, "formatted when empty"])
|
1105
974
|
assert_equal 2, book.worksheets.size
|
1106
975
|
sheet = book.worksheets.first
|
1107
976
|
assert_instance_of Spreadsheet::Excel::Worksheet, sheet
|
@@ -1364,5 +1233,35 @@ module Spreadsheet
|
|
1364
1233
|
sheet[0,0] # trigger read_worksheet
|
1365
1234
|
assert_equal [[2, 4, 1, 1], [3, 3, 2, 3]], sheet.merged_cells
|
1366
1235
|
end
|
1236
|
+
|
1237
|
+
private
|
1238
|
+
|
1239
|
+
# Validates the workbook's SST
|
1240
|
+
# Valid options:
|
1241
|
+
# :is => [array]
|
1242
|
+
# :contains => [array]
|
1243
|
+
# :length => num
|
1244
|
+
def assert_valid_sst(workbook, opts = {})
|
1245
|
+
assert workbook.is_a?(Spreadsheet::Excel::Workbook)
|
1246
|
+
sst = workbook.sst
|
1247
|
+
assert sst.is_a?(Array)
|
1248
|
+
strings = sst.map do |entry|
|
1249
|
+
assert entry.is_a?(Spreadsheet::Excel::SstEntry)
|
1250
|
+
entry.content
|
1251
|
+
end
|
1252
|
+
sorted_strings = strings.sort
|
1253
|
+
# Make sure there are no duplicates, the whole point of the SST:
|
1254
|
+
assert_equal strings.uniq.sort, sorted_strings
|
1255
|
+
if opts[:is]
|
1256
|
+
assert_equal opts[:is].sort, sorted_strings
|
1257
|
+
end
|
1258
|
+
if opts[:contains]
|
1259
|
+
assert_equal [], opts[:contains] - sorted_strings
|
1260
|
+
end
|
1261
|
+
if opts[:length]
|
1262
|
+
assert_equal opts[:length], sorted_strings
|
1263
|
+
end
|
1264
|
+
end
|
1265
|
+
|
1367
1266
|
end
|
1368
1267
|
end
|
data/test/workbook.rb
CHANGED
@@ -25,5 +25,20 @@ module Spreadsheet
|
|
25
25
|
@book.add_worksheet @worksheet2
|
26
26
|
assert_equal 2, @book.sheet_count
|
27
27
|
end
|
28
|
+
def test_add_format
|
29
|
+
|
30
|
+
assert_equal 1, @book.formats.length # Received a default format
|
31
|
+
|
32
|
+
f1 = Format.new
|
33
|
+
@book.add_format f1
|
34
|
+
assert_equal 2, @book.formats.length
|
35
|
+
|
36
|
+
f2 = Format.new
|
37
|
+
@book.add_format f2
|
38
|
+
assert_equal 3, @book.formats.length
|
39
|
+
|
40
|
+
@book.add_format f2
|
41
|
+
assert_equal 3, @book.formats.length # Rejected duplicate insertion
|
42
|
+
end
|
28
43
|
end
|
29
44
|
end
|
data/test/worksheet.rb
CHANGED
@@ -76,5 +76,37 @@ module Spreadsheet
|
|
76
76
|
assert_equal 30, @sheet.column(0).width
|
77
77
|
assert_equal 20, @sheet.column(1).width
|
78
78
|
end
|
79
|
+
def test_format_dates!
|
80
|
+
rowi = -1
|
81
|
+
|
82
|
+
@sheet.format_dates!
|
83
|
+
# No dates = no new formats
|
84
|
+
assert_equal 1, @book.formats.length # Default format
|
85
|
+
|
86
|
+
@sheet.row(rowi+=1).concat(["Hello", "World"])
|
87
|
+
@sheet.format_dates!
|
88
|
+
# No dates = no new formats
|
89
|
+
assert_equal 1, @book.formats.length
|
90
|
+
|
91
|
+
@sheet.row(rowi+=1).concat([Date.new(2010,1,1)])
|
92
|
+
@sheet.format_dates!
|
93
|
+
# 1 date = 1 new format
|
94
|
+
assert_equal 2, @book.formats.length
|
95
|
+
|
96
|
+
@sheet.row(rowi+=1).concat([Date.new(2011,1,1)])
|
97
|
+
@sheet.row(rowi+=1).concat([Date.new(2012,1,1)])
|
98
|
+
@sheet.row(rowi+=1).concat([Date.new(2013,1,1)])
|
99
|
+
@sheet.format_dates!
|
100
|
+
# 4 dates = only 1 new format across them:
|
101
|
+
assert_equal 3, @book.formats.length
|
102
|
+
|
103
|
+
@sheet.row(rowi+=1).concat([Date.new(2014,1,1)])
|
104
|
+
@sheet.row(rowi).default_format = Format.new
|
105
|
+
@sheet.row(rowi+=1).concat([Date.new(2015,1,1)])
|
106
|
+
@sheet.format_dates!
|
107
|
+
# 6 dates = 2 new formats across them:
|
108
|
+
assert_equal 6, @book.formats.length
|
109
|
+
|
110
|
+
end
|
79
111
|
end
|
80
112
|
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.7.
|
4
|
+
version: 0.7.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-06-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ruby-ole
|
16
|
-
requirement: &
|
16
|
+
requirement: &8107060 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '1.0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *8107060
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rdoc
|
27
|
-
requirement: &
|
27
|
+
requirement: &8106340 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '3.10'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *8106340
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: hoe
|
38
|
-
requirement: &
|
38
|
+
requirement: &8105620 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
version: '2.13'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *8105620
|
47
47
|
description: ! 'The Spreadsheet Library is designed to read and write Spreadsheet
|
48
48
|
Documents.
|
49
49
|
|