spreadsheet 0.6.2.1 → 0.6.3
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +18 -0
- data/Manifest.txt +6 -0
- data/bin/xlsopcodes +18 -0
- data/lib/spreadsheet.rb +1 -1
- data/lib/spreadsheet/excel/internals.rb +10 -1
- data/lib/spreadsheet/excel/reader.rb +31 -24
- data/lib/spreadsheet/excel/worksheet.rb +5 -5
- data/lib/spreadsheet/excel/writer/format.rb +3 -3
- data/lib/spreadsheet/excel/writer/workbook.rb +36 -27
- data/lib/spreadsheet/excel/writer/worksheet.rb +95 -36
- data/lib/spreadsheet/helpers.rb +11 -0
- data/lib/spreadsheet/row.rb +40 -26
- data/lib/spreadsheet/workbook.rb +1 -1
- data/lib/spreadsheet/worksheet.rb +13 -8
- data/test/data/test_datetime.xls +0 -0
- data/test/data/test_version_excel97.xls +0 -0
- data/test/excel/row.rb +2 -2
- data/test/excel/writer/worksheet.rb +22 -0
- data/test/integration.rb +19 -18
- data/test/row.rb +33 -0
- data/test/suite.rb +14 -0
- data/test/worksheet.rb +12 -4
- metadata +10 -4
data/History.txt
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
=== 0.6.3 / 2009-01-14
|
2
|
+
|
3
|
+
* 1 Bugfix
|
4
|
+
|
5
|
+
* Fixes the issue reported by Corey Martella in
|
6
|
+
http://rubyforge.org/forum/message.php?msg_id=63651
|
7
|
+
as well as other issues engendered by the decision to always shorten
|
8
|
+
Rows to the last non-nil value.
|
9
|
+
|
10
|
+
* 2 minor enhancements
|
11
|
+
|
12
|
+
* Added bin/xlsopcodes, a tool for examining Excel files
|
13
|
+
|
14
|
+
* Documents created by Spreadsheet can now be Printed in Excel and
|
15
|
+
Excel-Viewer.
|
16
|
+
This issue was reported by Spencer Turner in
|
17
|
+
http://rubyforge.org/tracker/index.php?func=detail&aid=23287&group_id=678&atid=2677
|
18
|
+
|
1
19
|
=== 0.6.2.1 / 2008-12-18
|
2
20
|
|
3
21
|
* 1 Bugfix
|
data/Manifest.txt
CHANGED
@@ -4,6 +4,7 @@ LICENSE.txt
|
|
4
4
|
Manifest.txt
|
5
5
|
README.txt
|
6
6
|
Rakefile
|
7
|
+
bin/xlsopcodes
|
7
8
|
lib/parseexcel.rb
|
8
9
|
lib/parseexcel/parseexcel.rb
|
9
10
|
lib/parseexcel/parser.rb
|
@@ -32,18 +33,23 @@ lib/spreadsheet/excel/writer/worksheet.rb
|
|
32
33
|
lib/spreadsheet/font.rb
|
33
34
|
lib/spreadsheet/format.rb
|
34
35
|
lib/spreadsheet/formula.rb
|
36
|
+
lib/spreadsheet/helpers.rb
|
35
37
|
lib/spreadsheet/link.rb
|
36
38
|
lib/spreadsheet/row.rb
|
37
39
|
lib/spreadsheet/workbook.rb
|
38
40
|
lib/spreadsheet/worksheet.rb
|
39
41
|
lib/spreadsheet/writer.rb
|
40
42
|
test/data/test_copy.xls
|
43
|
+
test/data/test_datetime.xls
|
41
44
|
test/data/test_empty.xls
|
42
45
|
test/data/test_version_excel5.xls
|
43
46
|
test/data/test_version_excel95.xls
|
44
47
|
test/data/test_version_excel97.xls
|
45
48
|
test/excel/row.rb
|
49
|
+
test/excel/writer/worksheet.rb
|
46
50
|
test/font.rb
|
47
51
|
test/integration.rb
|
52
|
+
test/row.rb
|
53
|
+
test/suite.rb
|
48
54
|
test/workbook.rb
|
49
55
|
test/worksheet.rb
|
data/bin/xlsopcodes
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'spreadsheet'
|
4
|
+
|
5
|
+
source, target = ARGV
|
6
|
+
|
7
|
+
if source.nil?
|
8
|
+
puts "Usage: #{$0} <source> [<target>]"
|
9
|
+
exit -1
|
10
|
+
end
|
11
|
+
|
12
|
+
target = target ? File.open(target, 'w') : STDOUT
|
13
|
+
|
14
|
+
reader = Spreadsheet::Excel::Reader.new :print_opcodes => target
|
15
|
+
reader.setup source
|
16
|
+
|
17
|
+
while tuple = reader.get_next_chunk
|
18
|
+
end
|
data/lib/spreadsheet.rb
CHANGED
@@ -98,8 +98,10 @@ module Internals
|
|
98
98
|
:font => 'v5C3x',
|
99
99
|
:labelsst => 'v3V',
|
100
100
|
:number => "v3#{EIGHT_BYTE_DOUBLE}",
|
101
|
+
:pagesetup => "v8#{EIGHT_BYTE_DOUBLE}2v",
|
101
102
|
:rk => 'v3V',
|
102
103
|
:row => 'v4x4V',
|
104
|
+
:window2 => 'v4x2v2x4',
|
103
105
|
:xf => 'v3C4V2v',
|
104
106
|
}
|
105
107
|
# From BIFF5 on, the built-in number formats will be omitted. The built-in
|
@@ -278,6 +280,11 @@ module Internals
|
|
278
280
|
:useselfs => 0x0160, # ○ USESELFS (Natural Language Formulas) ➜ 6.105
|
279
281
|
:dsf => 0x0161, # ○ DSF (Double Stream File) ➜ 6.32
|
280
282
|
:refreshall => 0x01b7, # ○ REFRESHALL
|
283
|
+
########################## ● Worksheet View Settings Block ➜ 5.5
|
284
|
+
:window2 => 0x023e, # ● WINDOW2 ➜ 5.110
|
285
|
+
:scl => 0x00a0, # ○ SCL ➜ 5.92 (BIFF4-BIFF8 only)
|
286
|
+
:pane => 0x0041, # ○ PANE ➜ 5.75
|
287
|
+
:selection => 0x001d, # ○○ SELECTION ➜ 5.93
|
281
288
|
########################## ○ Page Settings Block ➜ 5.4
|
282
289
|
:hpagebreaks => 0x001b, # ○ HORIZONTALPAGEBREAKS ➜ 6.54
|
283
290
|
:vpagebreaks => 0x001a, # ○ VERTICALPAGEBREAKS ➜ 6.107
|
@@ -290,7 +297,7 @@ module Internals
|
|
290
297
|
:topmargin => 0x0028, # ○ TOPMARGIN ➜ 6.103
|
291
298
|
:bottommargin => 0x0029, # ○ BOTTOMMARGIN ➜ 6.11
|
292
299
|
# ○ PLS (opcode unknown)
|
293
|
-
:
|
300
|
+
:pagesetup => 0x00a1, # ○ PAGESETUP ➜ 6.89 (BIFF4-BIFF8 only)
|
294
301
|
:bitmap => 0x00e9, # ○ BITMAP ➜ 6.6 (Background-Bitmap, BIFF8 only)
|
295
302
|
##########################
|
296
303
|
:printheaders => 0x002a, # ○ PRINTHEADERS ➜ 6.76
|
@@ -340,6 +347,8 @@ module Internals
|
|
340
347
|
}
|
341
348
|
NGILA_V_FX = XF_V_ALIGN.invert
|
342
349
|
OPCODE_SIZE = 4
|
350
|
+
ROW_HEIGHT = 12.1
|
351
|
+
SST_CHUNKSIZE = 20
|
343
352
|
def binfmt key
|
344
353
|
BINARY_FORMATS[key]
|
345
354
|
end
|
@@ -74,6 +74,23 @@ class Reader
|
|
74
74
|
name
|
75
75
|
end
|
76
76
|
end
|
77
|
+
def get_next_chunk
|
78
|
+
pos = @pos
|
79
|
+
if pos < @data.size
|
80
|
+
op, len = @data[@pos,OPCODE_SIZE].unpack('v2')
|
81
|
+
@pos += OPCODE_SIZE
|
82
|
+
if len
|
83
|
+
work = @data[@pos,len]
|
84
|
+
@pos += len
|
85
|
+
code = SEDOCPO.fetch(op, op)
|
86
|
+
if io = @opts[:print_opcodes]
|
87
|
+
io.puts sprintf("0x%04x/%-16s %5i: %s",
|
88
|
+
op, code.inspect, len, work.inspect)
|
89
|
+
end
|
90
|
+
[ pos, code, len + OPCODE_SIZE, work]
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
77
94
|
def in_row_block? op, previous
|
78
95
|
if op == :row
|
79
96
|
previous == op
|
@@ -98,17 +115,7 @@ class Reader
|
|
98
115
|
# The entry-point for reading Excel-documents. Reads the Biff-Version and
|
99
116
|
# loads additional reader-methods before proceeding with parsing the document.
|
100
117
|
def read io
|
101
|
-
|
102
|
-
@workbook = Workbook.new io, {}
|
103
|
-
@book = @ole.file.open("Book") rescue @ole.file.open("Workbook")
|
104
|
-
@data = @book.read
|
105
|
-
read_bof
|
106
|
-
@workbook.ole = @book
|
107
|
-
@workbook.bof = @bof
|
108
|
-
@workbook.version = @version
|
109
|
-
biff = @workbook.biff_version
|
110
|
-
extend_reader biff
|
111
|
-
extend_internals biff
|
118
|
+
setup io
|
112
119
|
read_workbook
|
113
120
|
@workbook.default_format = @workbook.format 0
|
114
121
|
@workbook.changes.clear
|
@@ -1047,6 +1054,19 @@ class Reader
|
|
1047
1054
|
# TODO: Row spacing
|
1048
1055
|
worksheet.set_row_address index, attrs
|
1049
1056
|
end
|
1057
|
+
def setup io
|
1058
|
+
@ole = Ole::Storage.open io
|
1059
|
+
@workbook = Workbook.new io, {}
|
1060
|
+
@book = @ole.file.open("Book") rescue @ole.file.open("Workbook")
|
1061
|
+
@data = @book.read
|
1062
|
+
read_bof
|
1063
|
+
@workbook.ole = @book
|
1064
|
+
@workbook.bof = @bof
|
1065
|
+
@workbook.version = @version
|
1066
|
+
biff = @workbook.biff_version
|
1067
|
+
extend_reader biff
|
1068
|
+
extend_internals biff
|
1069
|
+
end
|
1050
1070
|
private
|
1051
1071
|
def extend_internals version
|
1052
1072
|
require 'spreadsheet/excel/internals/biff%i' % version
|
@@ -1060,19 +1080,6 @@ class Reader
|
|
1060
1080
|
extend Reader.const_get('Biff%i' % version)
|
1061
1081
|
rescue LoadError
|
1062
1082
|
end
|
1063
|
-
def get_next_chunk
|
1064
|
-
pos = @pos
|
1065
|
-
op, len = @data[@pos,OPCODE_SIZE].unpack('v2')
|
1066
|
-
@pos += OPCODE_SIZE
|
1067
|
-
if len
|
1068
|
-
work = @data[@pos,len]
|
1069
|
-
@pos += len
|
1070
|
-
code = SEDOCPO.fetch(op, op)
|
1071
|
-
#puts "0x%04x/%-16s (0x%08x) %5i: %s" % [op, code.inspect, pos, len, work[0,16].inspect]
|
1072
|
-
#puts "0x%04x/%-16s %5i: %s" % [op, code.inspect, len, work[0,32].inspect]
|
1073
|
-
[ pos, code, len + OPCODE_SIZE, work]
|
1074
|
-
end
|
1075
|
-
end
|
1076
1083
|
end
|
1077
1084
|
end
|
1078
1085
|
end
|
@@ -36,11 +36,11 @@ class Worksheet < Spreadsheet::Worksheet
|
|
36
36
|
return if @row_addresses
|
37
37
|
@dimensions = nil
|
38
38
|
@row_addresses = []
|
39
|
-
@reader.read_worksheet self, @offset
|
39
|
+
@reader.read_worksheet self, @offset if @reader
|
40
40
|
end
|
41
41
|
def row idx
|
42
|
-
ensure_rows_read
|
43
42
|
@rows[idx] or begin
|
43
|
+
ensure_rows_read
|
44
44
|
if addr = @row_addresses[idx]
|
45
45
|
row = @reader.read_row self, addr
|
46
46
|
[:default_format, :height, :outline_level, :hidden, ].each do |key|
|
@@ -53,7 +53,7 @@ class Worksheet < Spreadsheet::Worksheet
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
end
|
56
|
-
def row_updated idx, row
|
56
|
+
def row_updated idx, row
|
57
57
|
res = super
|
58
58
|
@workbook.changes.store self, true
|
59
59
|
@workbook.changes.store :boundsheets, true
|
@@ -83,11 +83,11 @@ class Worksheet < Spreadsheet::Worksheet
|
|
83
83
|
index_of_first(@row_addresses) ].compact.min || 0
|
84
84
|
@dimensions[1] = [ @rows.size, @row_addresses.size ].compact.max || 0
|
85
85
|
compact = @rows.compact
|
86
|
-
first_rows = compact.collect do |row|
|
86
|
+
first_rows = compact.collect do |row| row.first_used end.compact.min
|
87
87
|
first_addrs = @row_addresses.compact.collect do |addr|
|
88
88
|
addr[:first_used] end.min
|
89
89
|
@dimensions[2] = [ first_rows, first_addrs ].compact.min || 0
|
90
|
-
last_rows = compact.collect do |row| row.
|
90
|
+
last_rows = compact.collect do |row| row.first_unused end.max
|
91
91
|
last_addrs = @row_addresses.compact.collect do |addr|
|
92
92
|
addr[:first_unused] end.max
|
93
93
|
@dimensions[3] = [last_rows, last_addrs].compact.max || 0
|
@@ -32,8 +32,8 @@ class Format < DelegateClass Spreadsheet::Format
|
|
32
32
|
color :pattern_bg_color, :pattern_bg
|
33
33
|
attr_accessor :xf_index
|
34
34
|
attr_reader :format
|
35
|
-
def initialize writer, workbook, format=workbook.default_format,
|
36
|
-
@
|
35
|
+
def initialize writer, workbook, format=workbook.default_format, opts={}
|
36
|
+
@opts = { :type => :format }.merge opts
|
37
37
|
@format = format
|
38
38
|
@writer = writer
|
39
39
|
@workbook = workbook
|
@@ -62,7 +62,7 @@ class Format < DelegateClass Spreadsheet::Format
|
|
62
62
|
writer.write [op,data.size].pack("v2")
|
63
63
|
writer.write data
|
64
64
|
end
|
65
|
-
def write_xf writer, type=@type
|
65
|
+
def write_xf writer, type=@opts[:type]
|
66
66
|
xf_type = xf_type_prot type
|
67
67
|
data = [
|
68
68
|
font_index, # Index to FONT record (➜ 6.43)
|
@@ -56,7 +56,8 @@ class Workbook < Spreadsheet::Writer
|
|
56
56
|
formats = []
|
57
57
|
unless opts[:existing_document]
|
58
58
|
15.times do
|
59
|
-
formats.push Format.new(self, workbook, workbook.default_format,
|
59
|
+
formats.push Format.new(self, workbook, workbook.default_format,
|
60
|
+
:type => :style)
|
60
61
|
end
|
61
62
|
formats.push Format.new(self, workbook)
|
62
63
|
end
|
@@ -258,7 +259,7 @@ class Workbook < Spreadsheet::Writer
|
|
258
259
|
write_op writer, 0x000a
|
259
260
|
end
|
260
261
|
def write_extsst workbook, offsets, writer
|
261
|
-
header = [
|
262
|
+
header = [SST_CHUNKSIZE].pack('v')
|
262
263
|
data = offsets.collect do |pair| pair.push(0).pack('Vv2') end
|
263
264
|
write_op writer, 0x00ff, header, data
|
264
265
|
end
|
@@ -374,7 +375,9 @@ class Workbook < Spreadsheet::Writer
|
|
374
375
|
buffer1 = StringIO.new ''
|
375
376
|
# ● BOF Type = workbook globals (➜ 6.8)
|
376
377
|
write_bof workbook, buffer1, :globals
|
377
|
-
# ○ File Protection Block ➜
|
378
|
+
# ○ File Protection Block ➜ 4.19
|
379
|
+
# ○ WRITEACCESS User name (BIFF3-BIFF8, ➜ 5.112)
|
380
|
+
# ○ FILESHARING File sharing options (BIFF3-BIFF8, ➜ 5.44)
|
378
381
|
# ○ CODEPAGE ➜ 6.17
|
379
382
|
write_encoding workbook, buffer1
|
380
383
|
# ○ DSF ➜ 6.32
|
@@ -382,42 +385,46 @@ class Workbook < Spreadsheet::Writer
|
|
382
385
|
# ○ TABID
|
383
386
|
write_tabid workbook, buffer1
|
384
387
|
# ○ FNGROUPCOUNT
|
385
|
-
# ○ Workbook Protection Block ➜
|
388
|
+
# ○ Workbook Protection Block ➜ 4.18
|
389
|
+
# ○ WINDOWPROTECT Window settings: 1 = protected (➜ 5.111)
|
390
|
+
# ○ PROTECT Cell contents: 1 = protected (➜ 5.82)
|
386
391
|
write_protect workbook, buffer1
|
392
|
+
# ○ OBJECTPROTECT Embedded objects: 1 = protected (➜ 5.72)
|
393
|
+
# ○ PASSWORD Hash value of the password; 0 = No password (➜ 5.76)
|
387
394
|
write_password workbook, buffer1
|
388
|
-
#
|
395
|
+
# ○ BACKUP ➜ 5.5
|
396
|
+
# ○ HIDEOBJ ➜ 5.56
|
397
|
+
# ● WINDOW1 ➜ 5.109
|
389
398
|
write_window1 workbook, buffer1
|
390
|
-
# ○
|
391
|
-
# ○ HIDEOBJ ➜ 6.52
|
392
|
-
# ○ DATEMODE ➜ 6.25
|
399
|
+
# ○ DATEMODE ➜ 5.28
|
393
400
|
write_datemode workbook, buffer1
|
394
|
-
# ○ PRECISION ➜
|
401
|
+
# ○ PRECISION ➜ 5.79
|
395
402
|
write_precision workbook, buffer1
|
396
403
|
# ○ REFRESHALL
|
397
404
|
write_refreshall workbook, buffer1
|
398
|
-
# ○ BOOKBOOL ➜
|
405
|
+
# ○ BOOKBOOL ➜ 5.9
|
399
406
|
write_bookbool workbook, buffer1
|
400
|
-
# ●● FONT ➜
|
407
|
+
# ●● FONT ➜ 5.45
|
401
408
|
write_fonts workbook, buffer1
|
402
|
-
# ○○ FORMAT ➜
|
409
|
+
# ○○ FORMAT ➜ 5.49
|
403
410
|
write_formats workbook, buffer1
|
404
|
-
# ●● XF ➜
|
411
|
+
# ●● XF ➜ 5.115
|
405
412
|
write_xfs workbook, buffer1
|
406
|
-
# ●● STYLE ➜
|
413
|
+
# ●● STYLE ➜ 5.103
|
407
414
|
write_styles workbook, buffer1
|
408
|
-
# ○ PALETTE ➜
|
409
|
-
# ○ USESELFS ➜
|
415
|
+
# ○ PALETTE ➜ 5.74
|
416
|
+
# ○ USESELFS ➜ 5.106
|
410
417
|
buffer1.rewind
|
411
|
-
# ●● BOUNDSHEET ➜
|
418
|
+
# ●● BOUNDSHEET ➜ 5.95
|
412
419
|
buffer2 = StringIO.new ''
|
413
|
-
# ○ COUNTRY ➜
|
414
|
-
# ○ Link Table ➜
|
420
|
+
# ○ COUNTRY ➜ 5.22
|
421
|
+
# ○ Link Table ➜ 4.10.3
|
415
422
|
# ○○ NAME ➜ 6.66
|
416
|
-
# ○ Shared String Table ➜
|
417
|
-
# ● SST ➜
|
418
|
-
# ● EXTSST ➜
|
423
|
+
# ○ Shared String Table ➜ 4.11
|
424
|
+
# ● SST ➜ 5.100
|
425
|
+
# ● EXTSST ➜ 5.42
|
419
426
|
write_sst workbook, buffer2, buffer1.size
|
420
|
-
# ● EOF ➜
|
427
|
+
# ● EOF ➜ 5.37
|
421
428
|
write_eof workbook, buffer2
|
422
429
|
buffer2.rewind
|
423
430
|
# worksheet data can only be assembled after write_sst
|
@@ -482,7 +489,9 @@ class Workbook < Spreadsheet::Writer
|
|
482
489
|
strings.each_with_index do |string, idx|
|
483
490
|
sst.store string, idx
|
484
491
|
op_offset = data.size + 4
|
485
|
-
|
492
|
+
if idx % SST_CHUNKSIZE == 0
|
493
|
+
offsets.push [offset + writer.pos + op_offset, op_offset]
|
494
|
+
end
|
486
495
|
header, packed, next_wide = _unicode_string string, 2
|
487
496
|
# the first few bytes (header + first character) must not be split
|
488
497
|
must_fit = header.size + wide + 1
|
@@ -546,9 +555,9 @@ class Workbook < Spreadsheet::Writer
|
|
546
555
|
# 0x07 = Currency [0] (BIFF4-BIFF8)
|
547
556
|
# 0x08 = Hyperlink (BIFF8)
|
548
557
|
# 0x09 = Followed Hyperlink (BIFF8)
|
549
|
-
|
550
|
-
#
|
551
|
-
|
558
|
+
0xff, # Level for RowLevel or ColLevel style (zero-based, lv),
|
559
|
+
# 0xff otherwise
|
560
|
+
# The RowLevel and ColLevel styles specify the formatting of
|
552
561
|
# subtotal cells in a specific outline level. The level is
|
553
562
|
# specified by the last field in the STYLE record. Valid values
|
554
563
|
# are 0…6 for the outline levels 1…7.
|
@@ -158,7 +158,7 @@ class Worksheet
|
|
158
158
|
write_op 0x000c, [count].pack('v')
|
159
159
|
end
|
160
160
|
def write_cell type, row, idx, *args
|
161
|
-
xf_idx = @workbook.xf_index @worksheet.workbook, row.
|
161
|
+
xf_idx = @workbook.xf_index @worksheet.workbook, row.formats[idx]
|
162
162
|
data = [
|
163
163
|
row.idx, # Index to row
|
164
164
|
idx, # Index to column
|
@@ -178,6 +178,7 @@ class Worksheet
|
|
178
178
|
# RK ➜ 6.82 (BIFF3-BIFF8)
|
179
179
|
# RSTRING ➜ 6.84 (BIFF5/BIFF7)
|
180
180
|
multiples, first_idx = nil
|
181
|
+
row = row.formatted
|
181
182
|
row.each_with_index do |cell, idx|
|
182
183
|
cell = nil if cell == ''
|
183
184
|
## it appears that there are limitations to RK precision, both for
|
@@ -357,7 +358,7 @@ class Worksheet
|
|
357
358
|
# Write a cell with a Formula. May write an additional String record depending
|
358
359
|
# on the stored result of the Formula.
|
359
360
|
def write_formula row, idx
|
360
|
-
xf_idx = @workbook.xf_index @worksheet.workbook, row.
|
361
|
+
xf_idx = @workbook.xf_index @worksheet.workbook, row.formats[idx]
|
361
362
|
cell = row[idx]
|
362
363
|
data1 = [
|
363
364
|
row.idx, # Index to row
|
@@ -415,47 +416,52 @@ class Worksheet
|
|
415
416
|
##
|
416
417
|
# Write a new Worksheet.
|
417
418
|
def write_from_scratch
|
418
|
-
# ● BOF Type = worksheet (➜
|
419
|
+
# ● BOF Type = worksheet (➜ 5.8)
|
419
420
|
write_bof
|
420
|
-
# ○ UNCALCED ➜
|
421
|
-
# ○ INDEX ➜
|
422
|
-
# ○ Calculation Settings Block ➜
|
421
|
+
# ○ UNCALCED ➜ 5.105
|
422
|
+
# ○ INDEX ➜ 4.7 (Row Blocks), ➜ 5.59
|
423
|
+
# ○ Calculation Settings Block ➜ 4.3
|
423
424
|
write_calccount
|
424
425
|
write_refmode
|
425
426
|
write_iteration
|
426
427
|
write_saverecalc
|
427
|
-
# ○ PRINTHEADERS ➜
|
428
|
-
# ○ PRINTGRIDLINES ➜
|
429
|
-
# ○ GRIDSET ➜
|
430
|
-
# ○ GUTS ➜
|
431
|
-
# ○ DEFAULTROWHEIGHT ➜
|
428
|
+
# ○ PRINTHEADERS ➜ 5.81
|
429
|
+
# ○ PRINTGRIDLINES ➜ 5.80
|
430
|
+
# ○ GRIDSET ➜ 5.52
|
431
|
+
# ○ GUTS ➜ 5.53
|
432
|
+
# ○ DEFAULTROWHEIGHT ➜ 5.31
|
432
433
|
write_defaultrowheight
|
433
|
-
# ○ WSBOOL ➜
|
434
|
+
# ○ WSBOOL ➜ 5.113
|
434
435
|
write_wsbool
|
435
|
-
# ○ Page Settings Block ➜
|
436
|
-
# ○ Worksheet Protection Block ➜
|
437
|
-
# ○ DEFCOLWIDTH ➜
|
436
|
+
# ○ Page Settings Block ➜ 4.4
|
437
|
+
# ○ Worksheet Protection Block ➜ 4.18
|
438
|
+
# ○ DEFCOLWIDTH ➜ 5.32
|
438
439
|
write_defcolwidth
|
439
|
-
# ○○ COLINFO ➜
|
440
|
+
# ○○ COLINFO ➜ 5.18
|
440
441
|
write_colinfos
|
441
|
-
# ○ SORT ➜
|
442
|
-
# ● DIMENSIONS ➜
|
442
|
+
# ○ SORT ➜ 5.99
|
443
|
+
# ● DIMENSIONS ➜ 5.35
|
443
444
|
write_dimensions
|
444
|
-
# ○○ Row Blocks ➜
|
445
|
+
# ○○ Row Blocks ➜ 4.7
|
445
446
|
write_rows
|
446
|
-
# ● Worksheet View Settings Block ➜
|
447
|
-
#
|
448
|
-
|
449
|
-
# ○
|
450
|
-
# ○
|
451
|
-
#
|
452
|
-
# ○
|
447
|
+
# ● Worksheet View Settings Block ➜ 4.5
|
448
|
+
# ● WINDOW2 ➜ 5.110
|
449
|
+
write_window2
|
450
|
+
# ○ SCL ➜ 5.92 (BIFF4-BIFF8 only)
|
451
|
+
# ○ PANE ➜ 5.75
|
452
|
+
# ○○ SELECTION ➜ 5.93
|
453
|
+
# ○ STANDARDWIDTH ➜ 5.101
|
454
|
+
# ○○ MERGEDCELLS ➜ 5.67
|
455
|
+
# ○ LABELRANGES ➜ 5.64
|
456
|
+
# ○ PHONETIC ➜ 5.77
|
457
|
+
# ○ Conditional Formatting Table ➜ 4.12
|
458
|
+
# ○ Hyperlink Table ➜ 4.13
|
453
459
|
write_hyperlink_table
|
454
|
-
# ○ Data Validity Table ➜
|
455
|
-
# ○ SHEETLAYOUT ➜
|
456
|
-
# ○ SHEETPROTECTION Additional protection, ➜
|
457
|
-
# ○ RANGEPROTECTION Additional protection, ➜
|
458
|
-
# ● EOF ➜
|
460
|
+
# ○ Data Validity Table ➜ 4.14
|
461
|
+
# ○ SHEETLAYOUT ➜ 5.96 (BIFF8X only)
|
462
|
+
# ○ SHEETPROTECTION Additional protection, ➜ 5.98 (BIFF8X only)
|
463
|
+
# ○ RANGEPROTECTION Additional protection, ➜ 5.84 (BIFF8X only)
|
464
|
+
# ● EOF ➜ 5.36
|
459
465
|
write_eof
|
460
466
|
end
|
461
467
|
def write_hlink row, col, link
|
@@ -556,11 +562,11 @@ class Worksheet
|
|
556
562
|
]
|
557
563
|
# List of nc=lc-fc+1 16-bit indexes to XF records (➜ 6.115)
|
558
564
|
multiples.each_with_index do |blank, cell_idx|
|
559
|
-
xf_idx = @workbook.xf_index @worksheet.workbook, row.
|
565
|
+
xf_idx = @workbook.xf_index @worksheet.workbook, row.formats[idx + cell_idx]
|
560
566
|
data.push xf_idx
|
561
567
|
end
|
562
568
|
# Index to last column (lc)
|
563
|
-
data.push idx + multiples.size
|
569
|
+
data.push idx + multiples.size - 1
|
564
570
|
write_op opcode(:mulblank), data.pack('v*')
|
565
571
|
end
|
566
572
|
##
|
@@ -673,23 +679,28 @@ class Worksheet
|
|
673
679
|
# formatted with a medium or thick
|
674
680
|
# line style. Thin line styles are
|
675
681
|
# not taken into account.
|
676
|
-
height = row.height ||
|
682
|
+
height = row.height || ROW_HEIGHT
|
677
683
|
opts = row.outline_level & 0x00000007
|
678
684
|
opts |= 0x00000010 if row.collapsed?
|
679
685
|
opts |= 0x00000020 if row.hidden?
|
680
|
-
opts |= 0x00000040 if height !=
|
686
|
+
opts |= 0x00000040 if height != ROW_HEIGHT
|
681
687
|
if fmt = row.default_format
|
682
688
|
xf_idx = @workbook.xf_index @worksheet.workbook, fmt
|
683
689
|
opts |= 0x00000080
|
684
690
|
opts |= xf_idx << 16
|
685
691
|
end
|
686
692
|
opts |= 0x00000100
|
693
|
+
height = if height == ROW_HEIGHT
|
694
|
+
height * TWIPS
|
695
|
+
else
|
696
|
+
( height * TWIPS ) | 0x8000
|
697
|
+
end
|
687
698
|
# TODO: Row spacing
|
688
699
|
data = [
|
689
700
|
row.idx,
|
690
701
|
row.first_used,
|
691
702
|
row.first_unused,
|
692
|
-
height
|
703
|
+
height,
|
693
704
|
opts,
|
694
705
|
].pack binfmt(:row)
|
695
706
|
write_op opcode(:row), data
|
@@ -714,6 +725,54 @@ class Worksheet
|
|
714
725
|
# 0 = Do not recalculate; 1 = Recalculate before saving the document
|
715
726
|
write_op 0x005f, [1].pack('v')
|
716
727
|
end
|
728
|
+
def write_window2
|
729
|
+
# This record contains additional settings for the document window
|
730
|
+
# (BIFF2-BIFF4) or for the window of a specific worksheet (BIFF5-BIFF8).
|
731
|
+
# It is part of the Sheet View Settings Block (➜ 4.5).
|
732
|
+
# Offset Size Contents
|
733
|
+
# 0 2 Option flags:
|
734
|
+
# Bits Mask Contents
|
735
|
+
# 0 0x0001 0 = Show formula results
|
736
|
+
# 1 = Show formulas
|
737
|
+
# 1 0x0002 0 = Do not show grid lines
|
738
|
+
# 1 = Show grid lines
|
739
|
+
# 2 0x0004 0 = Do not show sheet headers
|
740
|
+
# 1 = Show sheet headers
|
741
|
+
# 3 0x0008 0 = Panes are not frozen
|
742
|
+
# 1 = Panes are frozen (freeze)
|
743
|
+
# 4 0x0010 0 = Show zero values as empty cells
|
744
|
+
# 1 = Show zero values
|
745
|
+
# 5 0x0020 0 = Manual grid line colour
|
746
|
+
# 1 = Automatic grid line colour
|
747
|
+
# 6 0x0040 0 = Columns from left to right
|
748
|
+
# 1 = Columns from right to left
|
749
|
+
# 7 0x0080 0 = Do not show outline symbols
|
750
|
+
# 1 = Show outline symbols
|
751
|
+
# 8 0x0100 0 = Keep splits if pane freeze is removed
|
752
|
+
# 1 = Remove splits if pane freeze is removed
|
753
|
+
# 9 0x0200 0 = Sheet not selected
|
754
|
+
# 1 = Sheet selected (BIFF5-BIFF8)
|
755
|
+
# 10 0x0400 0 = Sheet not active
|
756
|
+
# 1 = Sheet active (BIFF5-BIFF8)
|
757
|
+
# 11 0x0800 0 = Show in normal view
|
758
|
+
# 1 = Show in page break preview (BIFF8)
|
759
|
+
# 2 2 Index to first visible row
|
760
|
+
# 4 2 Index to first visible column
|
761
|
+
# 6 2 Colour index of grid line colour (➜ 5.74).
|
762
|
+
# Note that in BIFF2-BIFF5 an RGB colour is written instead.
|
763
|
+
# 8 2 Not used
|
764
|
+
# 10 2 Cached magnification factor in page break preview (in percent)
|
765
|
+
# 0 = Default (60%)
|
766
|
+
# 12 2 Cached magnification factor in normal view (in percent)
|
767
|
+
# 0 = Default (100%)
|
768
|
+
# 14 4 Not used
|
769
|
+
flags = 310
|
770
|
+
if @worksheet.active
|
771
|
+
flags |= 0x0200
|
772
|
+
end
|
773
|
+
data = [ flags, 0, 0, 0, 0, 0 ].pack binfmt(:window2)
|
774
|
+
write_op opcode(:window2), data
|
775
|
+
end
|
717
776
|
def write_wsbool
|
718
777
|
bits = [
|
719
778
|
# Bit Mask Contents
|
data/lib/spreadsheet/row.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'spreadsheet/helpers'
|
2
|
+
|
1
3
|
module Spreadsheet
|
2
4
|
##
|
3
5
|
# The Row class. Encapsulates Cell data and formatting.
|
@@ -23,10 +25,7 @@ module Spreadsheet
|
|
23
25
|
alias_method :"unupdated_#{key}=", :"#{key}="
|
24
26
|
define_method "#{key}=" do |value|
|
25
27
|
send "unupdated_#{key}=", value
|
26
|
-
if @worksheet
|
27
|
-
@formatted = true
|
28
|
-
@worksheet.row_updated @idx, self, :formatted => true
|
29
|
-
end
|
28
|
+
@worksheet.row_updated @idx, self if @worksheet
|
30
29
|
value
|
31
30
|
end
|
32
31
|
end
|
@@ -36,9 +35,7 @@ module Spreadsheet
|
|
36
35
|
keys.each do |key|
|
37
36
|
define_method key do |*args|
|
38
37
|
res = super
|
39
|
-
if @worksheet
|
40
|
-
@worksheet.row_updated @idx, self, :formatted => @formatted
|
41
|
-
end
|
38
|
+
@worksheet.row_updated @idx, self if @worksheet
|
42
39
|
res
|
43
40
|
end
|
44
41
|
end
|
@@ -55,31 +52,22 @@ module Spreadsheet
|
|
55
52
|
def initialize worksheet, idx, cells=[]
|
56
53
|
@worksheet = worksheet
|
57
54
|
@idx = idx
|
58
|
-
while !cells.empty? && !cells.last
|
59
|
-
cells.pop
|
60
|
-
end
|
61
55
|
super cells
|
62
|
-
@first_used ||= index_of_first self
|
63
|
-
@first_unused ||= size
|
64
56
|
@formats = []
|
65
|
-
@height = 12
|
57
|
+
@height = 12.1
|
66
58
|
end
|
67
59
|
##
|
68
60
|
# Set the default Format used when writing a Cell if no explicit Format is
|
69
61
|
# stored for the cell.
|
70
62
|
def default_format= format
|
71
63
|
@worksheet.add_format format if @worksheet
|
72
|
-
@worksheet.row_updated @idx, self
|
64
|
+
@worksheet.row_updated @idx, self if @worksheet
|
73
65
|
@default_format = format
|
74
66
|
end
|
75
67
|
##
|
76
|
-
# #first_unused (really last used + 1) - the 0-based index of the first of
|
77
|
-
# all remaining contiguous blank Cells.
|
78
|
-
alias :first_unused :size
|
79
|
-
##
|
80
68
|
# #first_used the 0-based index of the first non-blank Cell.
|
81
69
|
def first_used
|
82
|
-
index_of_first
|
70
|
+
[ index_of_first(self), index_of_first(@formats) ].compact.min
|
83
71
|
end
|
84
72
|
##
|
85
73
|
# The Format for the Cell at _idx_ (0-based), or the first valid Format in
|
@@ -89,22 +77,48 @@ module Spreadsheet
|
|
89
77
|
|| @worksheet.column(idx).default_format if @worksheet
|
90
78
|
end
|
91
79
|
##
|
92
|
-
#
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
80
|
+
# Returns a copy of self with nil-values appended for empty cells that have
|
81
|
+
# an associated Format.
|
82
|
+
# This is primarily a helper-function for the writer classes.
|
83
|
+
def formatted
|
84
|
+
copy = dup
|
85
|
+
@formats.rcompact!
|
86
|
+
if copy.length < @formats.size
|
87
|
+
copy.concat Array.new(@formats.size - copy.length)
|
88
|
+
end
|
89
|
+
copy
|
90
|
+
end
|
91
|
+
##
|
92
|
+
# Same as Row#size, but takes into account formatted empty cells
|
93
|
+
def formatted_size
|
94
|
+
@formats.rcompact!
|
95
|
+
sz = size
|
96
|
+
fs = @formats.size
|
97
|
+
fs > sz ? fs : sz
|
98
98
|
end
|
99
|
+
##
|
100
|
+
# #first_unused (really last used + 1) - the 0-based index of the first of
|
101
|
+
# all remaining contiguous blank Cells.
|
102
|
+
alias :first_unused :formatted_size
|
99
103
|
def inspect
|
100
104
|
variables = instance_variables.collect do |name|
|
101
105
|
"%s=%s" % [name, instance_variable_get(name)]
|
102
106
|
end.join(' ')
|
103
107
|
sprintf "#<%s:0x%014x %s %s>", self.class, object_id, variables, super
|
104
108
|
end
|
109
|
+
##
|
110
|
+
# Set the Format for the Cell at _idx_ (0-based).
|
111
|
+
def set_format idx, fmt
|
112
|
+
@formats[idx] = fmt
|
113
|
+
@worksheet.add_format fmt
|
114
|
+
@worksheet.row_updated @idx, self if @worksheet
|
115
|
+
fmt
|
116
|
+
end
|
105
117
|
private
|
106
118
|
def index_of_first ary # :nodoc:
|
107
|
-
ary.
|
119
|
+
if first = ary.find do |elm| !elm.nil? end
|
120
|
+
ary.index first
|
121
|
+
end
|
108
122
|
end
|
109
123
|
end
|
110
124
|
end
|
data/lib/spreadsheet/workbook.rb
CHANGED
@@ -13,7 +13,7 @@ module Spreadsheet
|
|
13
13
|
class Workbook
|
14
14
|
include Spreadsheet::Encodings
|
15
15
|
attr_reader :io, :worksheets, :formats, :fonts
|
16
|
-
attr_accessor :encoding, :
|
16
|
+
attr_accessor :active_worksheet, :encoding, :default_format, :version
|
17
17
|
def initialize io = nil, opts={:default_format => Format.new}
|
18
18
|
@worksheets = []
|
19
19
|
@io = io
|
@@ -19,12 +19,19 @@ module Spreadsheet
|
|
19
19
|
# instances may appear at more than one position in #columns.
|
20
20
|
# If you modify a Column directly, your changes will be
|
21
21
|
# reflected in all those positions.
|
22
|
+
# #active :: When a user chooses to print a Workbook, Excel will include
|
23
|
+
# all active Worksheets. Defaults to true. If you want to
|
24
|
+
# exclude a Worksheet from the default print-list, set this
|
25
|
+
# to false. Warning: Excel will display a cryptic Error
|
26
|
+
# Message if a user tries to print a Workbook that has no
|
27
|
+
# active Worksheets.
|
22
28
|
class Worksheet
|
23
29
|
include Spreadsheet::Encodings
|
24
30
|
include Enumerable
|
25
|
-
attr_accessor :name, :workbook
|
31
|
+
attr_accessor :active, :name, :workbook
|
26
32
|
attr_reader :rows, :columns
|
27
33
|
def initialize opts={}
|
34
|
+
@active = true
|
28
35
|
@dimensions = [0,0,0,0]
|
29
36
|
@name = opts[:name] || 'Worksheet'
|
30
37
|
@workbook = opts[:workbook]
|
@@ -173,11 +180,8 @@ module Spreadsheet
|
|
173
180
|
##
|
174
181
|
# Tell Worksheet that the Row at _idx_ has been updated and the #dimensions
|
175
182
|
# need to be recalculated. You should not need to call this directly.
|
176
|
-
def row_updated idx, row
|
183
|
+
def row_updated idx, row
|
177
184
|
@dimensions = nil
|
178
|
-
unless opts[:formatted]
|
179
|
-
row = shorten(row)
|
180
|
-
end
|
181
185
|
@rows[idx] = row
|
182
186
|
format_dates row
|
183
187
|
row
|
@@ -188,7 +192,7 @@ module Spreadsheet
|
|
188
192
|
res = if row = @rows[idx]
|
189
193
|
row[0, cells.size] = cells
|
190
194
|
row
|
191
|
-
|
195
|
+
else
|
192
196
|
Row.new self, idx, cells
|
193
197
|
end
|
194
198
|
row_updated idx, res
|
@@ -251,8 +255,9 @@ module Spreadsheet
|
|
251
255
|
@dimensions[0] = index_of_first(@rows) || 0
|
252
256
|
@dimensions[1] = @rows.size
|
253
257
|
compact = @rows.compact
|
254
|
-
@dimensions[2] = compact.collect do |row|
|
255
|
-
@dimensions[3] = compact.collect do |row| row.
|
258
|
+
@dimensions[2] = compact.collect do |row| row.first_used end.compact.min || 0
|
259
|
+
@dimensions[3] = compact.collect do |row| row.first_unused end.max || 0
|
260
|
+
puts caller if @dimensions.nil?
|
256
261
|
@dimensions
|
257
262
|
end
|
258
263
|
def shorten ary # :nodoc:
|
Binary file
|
Binary file
|
data/test/excel/row.rb
CHANGED
@@ -19,8 +19,8 @@ class TestRow < Test::Unit::TestCase
|
|
19
19
|
assert_equal Date.new(1975,8,21), row.date(1)
|
20
20
|
end
|
21
21
|
def test_datetime
|
22
|
-
row = Row.new @worksheet, 0, [nil, 27627.
|
23
|
-
d1 = DateTime.new(1975,8,21) + 0.
|
22
|
+
row = Row.new @worksheet, 0, [nil, 27627.765]
|
23
|
+
d1 = DateTime.new(1975,8,21) + 0.765
|
24
24
|
d2 = row.datetime 1
|
25
25
|
assert_equal d1, d2
|
26
26
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Excel::Writer::TestWorksheet -- Spreadheet -- 21.11.2007 -- hwyss@ywesee.com
|
3
|
+
|
4
|
+
require 'test/unit'
|
5
|
+
require 'spreadsheet/excel/writer/worksheet'
|
6
|
+
|
7
|
+
module Spreadsheet
|
8
|
+
module Excel
|
9
|
+
module Writer
|
10
|
+
class TestWorksheet < Test::Unit::TestCase
|
11
|
+
def test_need_number
|
12
|
+
sheet = Worksheet.new nil, nil
|
13
|
+
assert_equal false, sheet.need_number?(10)
|
14
|
+
assert_equal false, sheet.need_number?(114.55)
|
15
|
+
assert_equal false, sheet.need_number?(0.1)
|
16
|
+
assert_equal false, sheet.need_number?(0.01)
|
17
|
+
assert_equal true, sheet.need_number?(0.001)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/test/integration.rb
CHANGED
@@ -63,7 +63,7 @@ module Spreadsheet
|
|
63
63
|
enc = Encoding.find enc
|
64
64
|
end
|
65
65
|
assert_equal enc, book.encoding
|
66
|
-
assert_equal
|
66
|
+
assert_equal 25, book.formats.size
|
67
67
|
assert_equal 5, book.fonts.size
|
68
68
|
str1 = book.shared_string 0
|
69
69
|
assert_equal @@iconv.iconv('Shared String'), str1
|
@@ -92,10 +92,10 @@ module Spreadsheet
|
|
92
92
|
end
|
93
93
|
assert_equal long, str4
|
94
94
|
sheet = book.worksheet 0
|
95
|
-
assert_equal
|
96
|
-
assert_equal
|
97
|
-
useds = [0,0,0,0,0,0,0,1,0,0]
|
98
|
-
unuseds = [2,2,1,1,1,2,1,11,1,2]
|
95
|
+
assert_equal 11, sheet.row_count
|
96
|
+
assert_equal 12, sheet.column_count
|
97
|
+
useds = [0,0,0,0,0,0,0,1,0,0,11]
|
98
|
+
unuseds = [2,2,1,1,1,2,1,11,1,2,12]
|
99
99
|
sheet.each do |row|
|
100
100
|
assert_equal useds.shift, row.first_used
|
101
101
|
assert_equal unuseds.shift, row.first_unused
|
@@ -154,6 +154,7 @@ module Spreadsheet
|
|
154
154
|
assert_equal 0.0001, row[0]
|
155
155
|
row = sheet.row 9
|
156
156
|
assert_equal 0.00009, row[0]
|
157
|
+
assert_equal :green, sheet.row(10).format(11).pattern_fg_color
|
157
158
|
end
|
158
159
|
def test_version_excel97__ooffice
|
159
160
|
path = File.join @data, 'test_version_excel97.xls'
|
@@ -166,7 +167,7 @@ module Spreadsheet
|
|
166
167
|
enc = Encoding.find enc
|
167
168
|
end
|
168
169
|
assert_equal enc, book.encoding
|
169
|
-
assert_equal
|
170
|
+
assert_equal 25, book.formats.size
|
170
171
|
assert_equal 5, book.fonts.size
|
171
172
|
str1 = book.shared_string 0
|
172
173
|
assert_equal 'Shared String', str1
|
@@ -195,10 +196,10 @@ module Spreadsheet
|
|
195
196
|
end
|
196
197
|
assert_equal long, str4
|
197
198
|
sheet = book.worksheet 0
|
198
|
-
assert_equal
|
199
|
-
assert_equal
|
200
|
-
useds = [0,0,0,0,0,0,0,1,0,0]
|
201
|
-
unuseds = [2,2,1,1,1,2,1,11,1,2]
|
199
|
+
assert_equal 11, sheet.row_count
|
200
|
+
assert_equal 12, sheet.column_count
|
201
|
+
useds = [0,0,0,0,0,0,0,1,0,0,11]
|
202
|
+
unuseds = [2,2,1,1,1,2,1,11,1,2,12]
|
202
203
|
sheet.each do |row|
|
203
204
|
assert_equal useds.shift, row.first_used
|
204
205
|
assert_equal unuseds.shift, row.first_unused
|
@@ -577,10 +578,10 @@ module Spreadsheet
|
|
577
578
|
book.write path
|
578
579
|
assert_nothing_raised do book = Spreadsheet.open path end
|
579
580
|
sheet = book.worksheet 0
|
580
|
-
assert_equal
|
581
|
-
assert_equal
|
582
|
-
useds = [0,0,0,0,0,0,0,1,0,0]
|
583
|
-
unuseds = [2,2,1,1,1,2,1,11,1,2]
|
581
|
+
assert_equal 11, sheet.row_count
|
582
|
+
assert_equal 12, sheet.column_count
|
583
|
+
useds = [0,0,0,0,0,0,0,1,0,0,11]
|
584
|
+
unuseds = [2,2,1,1,1,2,1,11,1,2,12]
|
584
585
|
sheet.each do |row|
|
585
586
|
assert_equal useds.shift, row.first_used
|
586
587
|
assert_equal unuseds.shift, row.first_unused
|
@@ -686,10 +687,10 @@ module Spreadsheet
|
|
686
687
|
assert_equal str3, book.shared_string(2)
|
687
688
|
assert_equal str4, book.shared_string(3)
|
688
689
|
sheet = book.worksheet 0
|
689
|
-
assert_equal
|
690
|
-
assert_equal
|
691
|
-
useds = [0,0,0,0,0,0,0,1,0,0]
|
692
|
-
unuseds = [2,2,1,1,1,2,1,11,1,2]
|
690
|
+
assert_equal 11, sheet.row_count
|
691
|
+
assert_equal 12, sheet.column_count
|
692
|
+
useds = [0,0,0,0,0,0,0,1,0,0,11]
|
693
|
+
unuseds = [2,2,1,1,1,2,1,11,1,2,12]
|
693
694
|
sheet.each do |row|
|
694
695
|
assert_equal useds.shift, row.first_used
|
695
696
|
assert_equal unuseds.shift, row.first_unused
|
data/test/row.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# TestRow -- Spreadsheet -- 08.01.2009 -- hwyss@ywesee.com
|
3
|
+
|
4
|
+
$: << File.expand_path('../../lib', File.dirname(__FILE__))
|
5
|
+
|
6
|
+
require 'test/unit'
|
7
|
+
require 'spreadsheet'
|
8
|
+
|
9
|
+
module Spreadsheet
|
10
|
+
class TestRow < Test::Unit::TestCase
|
11
|
+
def setup
|
12
|
+
@workbook = Excel::Workbook.new
|
13
|
+
@worksheet = Excel::Worksheet.new
|
14
|
+
@workbook.add_worksheet @worksheet
|
15
|
+
end
|
16
|
+
def test_formatted
|
17
|
+
row = Row.new @worksheet, 0, [nil, 1]
|
18
|
+
assert_equal 2, row.formatted.size
|
19
|
+
row.set_format 3, Format.new
|
20
|
+
assert_equal 4, row.formatted.size
|
21
|
+
end
|
22
|
+
def test_concat
|
23
|
+
row = Row.new @worksheet, 0, [nil, 1, nil]
|
24
|
+
assert_equal [nil, 1, nil], row
|
25
|
+
row.concat [2, nil]
|
26
|
+
assert_equal [nil, 1, nil, 2, nil], row
|
27
|
+
row.concat [3]
|
28
|
+
assert_equal [nil, 1, nil, 2, nil, 3], row
|
29
|
+
row.concat [nil, 4]
|
30
|
+
assert_equal [nil, 1, nil, 2, nil, 3, nil, 4], row
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/test/suite.rb
ADDED
data/test/worksheet.rb
CHANGED
@@ -28,10 +28,10 @@ module Spreadsheet
|
|
28
28
|
assert_equal 2, @sheet.row_count
|
29
29
|
@sheet[1,0] = nil
|
30
30
|
assert_equal 2, @sheet.column_count
|
31
|
-
assert_equal
|
31
|
+
assert_equal 2, @sheet.row_count
|
32
32
|
@sheet[0,1] = nil
|
33
|
-
assert_equal
|
34
|
-
assert_equal
|
33
|
+
assert_equal 2, @sheet.column_count
|
34
|
+
assert_equal 2, @sheet.row_count
|
35
35
|
end
|
36
36
|
def test_column_count
|
37
37
|
assert_equal 0, @sheet.column_count
|
@@ -44,7 +44,7 @@ module Spreadsheet
|
|
44
44
|
@sheet.replace_row 5, nil, 'something', 4, 7, nil
|
45
45
|
assert_equal 4, @sheet.column_count
|
46
46
|
@sheet.replace_row 3
|
47
|
-
assert_equal
|
47
|
+
assert_equal 4, @sheet.column_count
|
48
48
|
end
|
49
49
|
def test_row_count
|
50
50
|
assert_equal 0, @sheet.row_count
|
@@ -57,7 +57,15 @@ module Spreadsheet
|
|
57
57
|
@sheet.replace_row 5, nil, 'something', 4, 7, nil
|
58
58
|
assert_equal 6, @sheet.row_count
|
59
59
|
@sheet.replace_row 3
|
60
|
+
assert_equal 6, @sheet.row_count
|
61
|
+
@sheet.delete_row 3
|
62
|
+
assert_equal 5, @sheet.row_count
|
63
|
+
@sheet.delete_row 3
|
64
|
+
assert_equal 4, @sheet.row_count
|
65
|
+
@sheet.delete_row 2
|
60
66
|
assert_equal 4, @sheet.row_count
|
67
|
+
@sheet.delete_row 2
|
68
|
+
assert_equal 3, @sheet.row_count
|
61
69
|
end
|
62
70
|
def test_modify_column
|
63
71
|
assert_equal 10, @sheet.column(0).width
|
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.3
|
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:
|
12
|
+
date: 2009-01-14 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -35,8 +35,8 @@ dependencies:
|
|
35
35
|
description: The Spreadsheet Library is designed to read and write Spreadsheet Documents. As of version 0.6.0, only Microsoft Excel compatible spreadsheets are supported. Spreadsheet is a combination/complete rewrite of the Spreadsheet::Excel Library by Daniel J. Berger and the ParseExcel Library by Hannes Wyss. Spreadsheet can read, write and modify Spreadsheet Documents.
|
36
36
|
email:
|
37
37
|
- hannes.wyss@gmail.com
|
38
|
-
executables:
|
39
|
-
|
38
|
+
executables:
|
39
|
+
- xlsopcodes
|
40
40
|
extensions: []
|
41
41
|
|
42
42
|
extra_rdoc_files:
|
@@ -52,6 +52,7 @@ files:
|
|
52
52
|
- Manifest.txt
|
53
53
|
- README.txt
|
54
54
|
- Rakefile
|
55
|
+
- bin/xlsopcodes
|
55
56
|
- lib/parseexcel.rb
|
56
57
|
- lib/parseexcel/parseexcel.rb
|
57
58
|
- lib/parseexcel/parser.rb
|
@@ -80,19 +81,24 @@ files:
|
|
80
81
|
- lib/spreadsheet/font.rb
|
81
82
|
- lib/spreadsheet/format.rb
|
82
83
|
- lib/spreadsheet/formula.rb
|
84
|
+
- lib/spreadsheet/helpers.rb
|
83
85
|
- lib/spreadsheet/link.rb
|
84
86
|
- lib/spreadsheet/row.rb
|
85
87
|
- lib/spreadsheet/workbook.rb
|
86
88
|
- lib/spreadsheet/worksheet.rb
|
87
89
|
- lib/spreadsheet/writer.rb
|
88
90
|
- test/data/test_copy.xls
|
91
|
+
- test/data/test_datetime.xls
|
89
92
|
- test/data/test_empty.xls
|
90
93
|
- test/data/test_version_excel5.xls
|
91
94
|
- test/data/test_version_excel95.xls
|
92
95
|
- test/data/test_version_excel97.xls
|
93
96
|
- test/excel/row.rb
|
97
|
+
- test/excel/writer/worksheet.rb
|
94
98
|
- test/font.rb
|
95
99
|
- test/integration.rb
|
100
|
+
- test/row.rb
|
101
|
+
- test/suite.rb
|
96
102
|
- test/workbook.rb
|
97
103
|
- test/worksheet.rb
|
98
104
|
has_rdoc: true
|