spreadsheet 0.6.2.1 → 0.6.3
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 +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
|