spreadsheet 0.6.0 → 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +8 -0
- data/README.txt +18 -1
- data/Rakefile +1 -0
- data/lib/spreadsheet.rb +1 -1
- data/lib/spreadsheet/excel.rb +10 -0
- data/lib/spreadsheet/excel/internals.rb +55 -29
- data/lib/spreadsheet/excel/reader.rb +75 -11
- data/lib/spreadsheet/excel/worksheet.rb +9 -2
- data/lib/spreadsheet/excel/writer/format.rb +12 -29
- data/lib/spreadsheet/excel/writer/workbook.rb +25 -21
- data/lib/spreadsheet/excel/writer/worksheet.rb +67 -9
- data/lib/spreadsheet/font.rb +4 -1
- data/lib/spreadsheet/format.rb +8 -9
- data/lib/spreadsheet/row.rb +5 -4
- data/lib/spreadsheet/workbook.rb +3 -2
- data/lib/spreadsheet/worksheet.rb +40 -4
- data/test/font.rb +3 -3
- data/test/integration.rb +26 -13
- metadata +12 -2
data/History.txt
CHANGED
data/README.txt
CHANGED
@@ -1,6 +1,13 @@
|
|
1
|
+
Last Update: 13.10.2008, 19.45 - zdavatz
|
2
|
+
|
1
3
|
= Spreadsheet
|
2
4
|
|
3
5
|
http://spreadsheet.rubyforge.org
|
6
|
+
http://scm.ywesee.com/spreadsheet
|
7
|
+
|
8
|
+
For a viewable directory of all recent changes, please see:
|
9
|
+
|
10
|
+
http://scm.ywesee.com/?p=spreadsheet;a=summary
|
4
11
|
|
5
12
|
== Description
|
6
13
|
|
@@ -34,6 +41,16 @@ Hannes Wyss. Spreadsheet can read, write and modify Spreadsheet Documents.
|
|
34
41
|
|
35
42
|
Have a look at the GUIDE[link://files/GUIDE_txt.html].
|
36
43
|
|
44
|
+
== Installation
|
45
|
+
|
46
|
+
Using RubyGems[http://www.rubygems.org]:
|
47
|
+
|
48
|
+
* sudo gem install spreadsheet
|
49
|
+
|
50
|
+
If you don't like RubyGems[http://www.rubygems.org], let me know which
|
51
|
+
installation solution you prefer and I'll include it in the future.
|
52
|
+
|
53
|
+
|
37
54
|
== Authors
|
38
55
|
|
39
56
|
Original Code:
|
@@ -49,6 +66,6 @@ Copyright (c) 2008 by Hannes Wyss (hannes.wyss@gmail.com)
|
|
49
66
|
|
50
67
|
== License
|
51
68
|
|
52
|
-
This library is distributed under the GPL.
|
69
|
+
This library is distributed under the GPL.
|
53
70
|
Please see the LICENSE[link://files/LICENSE_txt.html] file.
|
54
71
|
|
data/Rakefile
CHANGED
@@ -10,6 +10,7 @@ Hoe.new('spreadsheet', Spreadsheet::VERSION) do |p|
|
|
10
10
|
# p.rubyforge_name = 'spreadsheetx' # if different than lowercase project name
|
11
11
|
p.developer('Hannes Wyss', 'hannes.wyss@gmail.com')
|
12
12
|
p.remote_rdoc_dir = ''
|
13
|
+
p.extra_deps << 'ruby-ole'
|
13
14
|
end
|
14
15
|
|
15
16
|
# vim: syntax=Ruby
|
data/lib/spreadsheet.rb
CHANGED
data/lib/spreadsheet/excel.rb
CHANGED
@@ -34,6 +34,16 @@ module Spreadsheet
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
class Worksheet
|
37
|
+
unless instance_methods.include? "new_format_column"
|
38
|
+
alias :new_format_column :format_column
|
39
|
+
def format_column column, width=nil, format=nil
|
40
|
+
if width.is_a? Format
|
41
|
+
new_format_column column, width, format
|
42
|
+
else
|
43
|
+
new_format_column column, format, :width => width
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
37
47
|
def write row, col, data=nil, format=nil
|
38
48
|
if data.is_a? Array
|
39
49
|
write_row row, col, data, format
|
@@ -94,6 +94,7 @@ module Internals
|
|
94
94
|
BINARY_FORMATS = {
|
95
95
|
:blank => 'v3',
|
96
96
|
:boolerr => 'v3C2',
|
97
|
+
:colinfo => 'v5x2',
|
97
98
|
:font => 'v5C3x',
|
98
99
|
:labelsst => 'v3V',
|
99
100
|
:number => "v3#{EIGHT_BYTE_DOUBLE}",
|
@@ -107,7 +108,7 @@ module Internals
|
|
107
108
|
# default in a US-English environment. All indexes from 0 to 163 are
|
108
109
|
# reserved for built-in formats.
|
109
110
|
BUILTIN_FORMATS = { # TODO: locale support
|
110
|
-
0 => '
|
111
|
+
0 => 'GENERAL',
|
111
112
|
1 => '0',
|
112
113
|
2 => '0.00',
|
113
114
|
3 => '#,##0',
|
@@ -196,34 +197,35 @@ module Internals
|
|
196
197
|
}
|
197
198
|
LEAP_ERROR = Date.new 1900, 2, 28
|
198
199
|
OPCODES = {
|
199
|
-
:blank => 0x0201,
|
200
|
-
:boolerr => 0x0205,
|
201
|
-
:boundsheet => 0x0085,
|
202
|
-
:codepage => 0x0042,
|
203
|
-
:
|
204
|
-
:
|
205
|
-
:
|
206
|
-
:
|
207
|
-
:
|
208
|
-
:
|
209
|
-
:font => 0x0031,
|
210
|
-
:format => 0x041e,
|
211
|
-
:formula => 0x0006,
|
212
|
-
:
|
213
|
-
:
|
214
|
-
:
|
215
|
-
:
|
216
|
-
:
|
217
|
-
:
|
218
|
-
:
|
219
|
-
:
|
220
|
-
:
|
221
|
-
:
|
222
|
-
:
|
223
|
-
:
|
224
|
-
:uncalced => 0x005e,
|
225
|
-
:xf => 0x00e0,
|
200
|
+
:blank => 0x0201, # BLANK ➜ 6.7
|
201
|
+
:boolerr => 0x0205, # BOOLERR ➜ 6.10
|
202
|
+
:boundsheet => 0x0085, # ●● BOUNDSHEET ➜ 6.12
|
203
|
+
:codepage => 0x0042, # ○ CODEPAGE ➜ 6.17
|
204
|
+
:colinfo => 0x007d, # ○○ COLINFO ➜ 6.18
|
205
|
+
:continue => 0x003c, # ○ CONTINUE ➜ 6.22
|
206
|
+
:datemode => 0x0022, # ○ DATEMODE ➜ 6.25
|
207
|
+
:dbcell => 0x0a0b, # ○ DBCELL
|
208
|
+
:dimensions => 0x0200, # ● DIMENSIONS ➜ 6.31
|
209
|
+
:eof => 0x000a, # ● EOF ➜ 6.36
|
210
|
+
:font => 0x0031, # ●● FONT ➜ 6.43
|
211
|
+
:format => 0x041e, # ○○ FORMAT (Number Format) ➜ 6.45
|
212
|
+
:formula => 0x0006, # FORMULA ➜ 6.46
|
213
|
+
:label => 0x0204, # LABEL ➜ 6.59 (BIFF2-BIFF7)
|
214
|
+
:labelsst => 0x00fd, # LABELSST ➜ 6.61 (BIFF8 only)
|
215
|
+
:mulblank => 0x00be, # MULBLANK ➜ 6.64 (BIFF5-BIFF8)
|
216
|
+
:mulrk => 0x00bd, # MULRK ➜ 6.65 (BIFF5-BIFF8)
|
217
|
+
:number => 0x0203, # NUMBER ➜ 6.68
|
218
|
+
:rk => 0x027e, # RK ➜ 6.82 (BIFF3-BIFF8)
|
219
|
+
:row => 0x0208, # ● ROW ➜ 6.83
|
220
|
+
:rstring => 0x00d6, # RSTRING ➜ 6.84 (BIFF5/BIFF7)
|
221
|
+
:sst => 0x00fc, # ● SST ➜ 6.96
|
222
|
+
:string => 0x0207, # STRING ➜ 6.98
|
223
|
+
:style => 0x0293, # ●● STYLE ➜ 6.99
|
224
|
+
:xf => 0x00e0, # ●● XF ➜ 6.115
|
226
225
|
########################## Unhandled Opcodes ################################
|
226
|
+
:extsst => 0x00ff, # ● EXTSST ➜ 6.40
|
227
|
+
:index => 0x020b, # ○ INDEX ➜ 5.7 (Row Blocks), ➜ 6.55
|
228
|
+
:uncalced => 0x005e, # ○ UNCALCED ➜ 6.104
|
227
229
|
########################## ○ Calculation Settings Block ➜ 5.3
|
228
230
|
:calccount => 0x000c, # ○ CALCCOUNT ➜ 6.14
|
229
231
|
:calcmode => 0x000d, # ○ CALCMODE ➜ 6.15
|
@@ -296,7 +298,6 @@ module Internals
|
|
296
298
|
:defrowheight => 0x0225, # ○ DEFAULTROWHEIGHT ➜ 6.28
|
297
299
|
:wsbool => 0x0081, # ○ WSBOOL ➜ 6.113
|
298
300
|
:defcolwidth => 0x0055, # ○ DEFCOLWIDTH ➜ 6.29
|
299
|
-
:colinfo => 0x007d, # ○○ COLINFO ➜ 6.18
|
300
301
|
:sort => 0x0090, # ○ SORT ➜ 6.95
|
301
302
|
}
|
302
303
|
=begin ## unknown opcodes
|
@@ -311,6 +312,31 @@ module Internals
|
|
311
312
|
0x0022 => :double_accounting,
|
312
313
|
}
|
313
314
|
SEPYT_ENILREDNU = UNDERLINE_TYPES.invert
|
315
|
+
XF_H_ALIGN = {
|
316
|
+
:default => 0,
|
317
|
+
:left => 1,
|
318
|
+
:center => 2,
|
319
|
+
:right => 3,
|
320
|
+
:fill => 4,
|
321
|
+
:justify => 5,
|
322
|
+
:merge => 6,
|
323
|
+
:distributed => 7,
|
324
|
+
}
|
325
|
+
NGILA_H_FX = XF_H_ALIGN.invert
|
326
|
+
XF_TEXT_DIRECTION = {
|
327
|
+
:context => 0,
|
328
|
+
:left_to_right => 1,
|
329
|
+
:right_to_left => 2,
|
330
|
+
}
|
331
|
+
NOITCERID_TXET_FX = XF_TEXT_DIRECTION.invert
|
332
|
+
XF_V_ALIGN = {
|
333
|
+
:top => 0,
|
334
|
+
:middle => 1,
|
335
|
+
:bottom => 2,
|
336
|
+
:justify => 3,
|
337
|
+
:distributed => 4,
|
338
|
+
}
|
339
|
+
NGILA_V_FX = XF_V_ALIGN.invert
|
314
340
|
def binfmt key
|
315
341
|
BINARY_FORMATS[key]
|
316
342
|
end
|
@@ -107,6 +107,7 @@ class Reader
|
|
107
107
|
extend_reader biff
|
108
108
|
extend_internals biff
|
109
109
|
read_workbook
|
110
|
+
@workbook.default_format = @workbook.format 0
|
110
111
|
@workbook
|
111
112
|
end
|
112
113
|
def read_blank worksheet, addr, work
|
@@ -181,6 +182,31 @@ class Reader
|
|
181
182
|
codepage, _ = work.unpack 'v'
|
182
183
|
@workbook.set_encoding encoding(codepage), pos, len
|
183
184
|
end
|
185
|
+
def read_colinfo worksheet, work, pos, len
|
186
|
+
# Offset Size Contents
|
187
|
+
# 0 2 Index to first column in the range
|
188
|
+
# 2 2 Index to last column in the range
|
189
|
+
# 4 2 Width of the columns in 1/256 of the width of the zero
|
190
|
+
# character, using default font (first FONT record in the
|
191
|
+
# file)
|
192
|
+
# 6 2 Index to XF record (➜ 6.115) for default column formatting
|
193
|
+
# 8 2 Option flags:
|
194
|
+
# Bits Mask Contents
|
195
|
+
# 0 0x0001 1 = Columns are hidden
|
196
|
+
# 10-8 0x0700 Outline level of the columns (0 = no outline)
|
197
|
+
# 12 0x1000 1 = Columns are collapsed
|
198
|
+
# 10 2 Not used
|
199
|
+
first, last, width, xf, opts = work.unpack binfmt(:colinfo)[0..-2]
|
200
|
+
first.upto last do |col|
|
201
|
+
column = Column.new col, @workbook.format(xf),
|
202
|
+
:width => width.to_f / 256,
|
203
|
+
:hidden => (opts & 0x0001) > 0,
|
204
|
+
:collapsed => (opts & 0x1000) > 0,
|
205
|
+
:outline_level => (opts & 0x0700)
|
206
|
+
column.worksheet = worksheet
|
207
|
+
worksheet.columns[col] = column
|
208
|
+
end
|
209
|
+
end
|
184
210
|
def read_dimensions worksheet, work, pos, len
|
185
211
|
# Offset Size Contents
|
186
212
|
# 0 4 Index to first used row
|
@@ -550,7 +576,7 @@ class Reader
|
|
550
576
|
read_style work, pos, len
|
551
577
|
when :format # ○○ FORMAT (Number Format) ➜ 6.45
|
552
578
|
read_format work, pos, len
|
553
|
-
when :font
|
579
|
+
when :font # ●● FONT ➜ 6.43
|
554
580
|
read_font work, pos, len
|
555
581
|
end
|
556
582
|
previous_op = op unless op == :continue
|
@@ -577,6 +603,8 @@ class Reader
|
|
577
603
|
#when :index # ○ INDEX ➜ 5.7 (Row Blocks), ➜ 6.55
|
578
604
|
# TODO: if there are changes in rows, omit index when writing
|
579
605
|
#read_index worksheet, work, pos, len
|
606
|
+
when :colinfo # ○○ COLINFO ➜ 6.18
|
607
|
+
read_colinfo worksheet, work, pos, len
|
580
608
|
when :dimensions # ● DIMENSIONS ➜ 6.31
|
581
609
|
read_dimensions worksheet, work, pos, len
|
582
610
|
when :row # ○○ Row Blocks ➜ 5.7
|
@@ -729,12 +757,42 @@ class Reader
|
|
729
757
|
font_idx, numfmt, xf_type, xf_align, xf_rotation, xf_indent, xf_used_attr,
|
730
758
|
xf_borders, xf_brdcolors, xf_pattern = work.unpack binfmt(:xf)
|
731
759
|
fmt.number_format = @formats[numfmt]
|
732
|
-
|
760
|
+
## this appears to be undocumented: the first 4 fonts seem to be accessed
|
761
|
+
# with a 0-based index, but all subsequent font indices are 1-based.
|
762
|
+
fmt.font = @workbook.font(font_idx > 3 ? font_idx - 1 : font_idx)
|
763
|
+
fmt.horizontal_align = NGILA_H_FX[xf_align & 0x07]
|
764
|
+
fmt.text_wrap = xf_align & 0x08 > 0
|
765
|
+
fmt.vertical_align = NGILA_V_FX[xf_align & 0x70]
|
766
|
+
fmt.rotation = if xf_rotation == 255
|
767
|
+
:stacked
|
768
|
+
elsif xf_rotation > 90
|
769
|
+
90 - xf_rotation
|
770
|
+
else
|
771
|
+
xf_rotation
|
772
|
+
end
|
773
|
+
fmt.indent_level = xf_indent & 0x0f
|
774
|
+
fmt.shrink = xf_indent & 0x10 > 0
|
775
|
+
fmt.text_direction = NOITCERID_TXET_FX[xf_indent & 0xc0]
|
776
|
+
fmt.left = xf_borders & 0x0000000f > 0
|
777
|
+
fmt.right = xf_borders & 0x000000f0 > 0
|
778
|
+
fmt.top = xf_borders & 0x00000f00 > 0
|
779
|
+
fmt.bottom = xf_borders & 0x0000f000 > 0
|
780
|
+
fmt.left_color = COLOR_CODES[xf_borders & 0x007f0000] || :border
|
781
|
+
fmt.right_color = COLOR_CODES[xf_borders & 0x3f800000] || :border
|
782
|
+
fmt.cross_down = xf_borders & 0x40000000 > 0
|
783
|
+
fmt.cross_up = xf_borders & 0x80000000 > 0
|
784
|
+
fmt.top_color = COLOR_CODES[xf_brdcolors & 0x0000007f] || :border
|
785
|
+
fmt.bottom_color = COLOR_CODES[xf_brdcolors & 0x00003f80] || :border
|
786
|
+
fmt.diagonal_color = COLOR_CODES[xf_brdcolors & 0x001fc000] || :border
|
787
|
+
#fmt.diagonal_style = COLOR_CODES[xf_brdcolors & 0x01e00000]
|
788
|
+
fmt.pattern = xf_brdcolors & 0xfc000000
|
789
|
+
fmt.pattern_fg_color = COLOR_CODES[xf_pattern & 0x007f] || :border
|
790
|
+
fmt.pattern_bg_color = COLOR_CODES[xf_pattern & 0x3f80] || :pattern_bg
|
733
791
|
@workbook.add_format fmt
|
734
792
|
end
|
735
793
|
def set_cell worksheet, row, column, xf, value=nil
|
736
794
|
cells = @current_row_block[row] ||= Row.new(nil, row)
|
737
|
-
cells.formats[column] = @workbook.format(xf)
|
795
|
+
cells.formats[column] = @workbook.format(xf) unless xf == 0
|
738
796
|
cells[column] = value
|
739
797
|
end
|
740
798
|
def set_row_address worksheet, work, pos, len
|
@@ -758,21 +816,27 @@ class Reader
|
|
758
816
|
@current_row_block_offset ||= [pos]
|
759
817
|
index, first_used, first_unused, flags,
|
760
818
|
hasdefaults, offset = work.unpack binfmt(:row)
|
819
|
+
format = nil
|
761
820
|
# TODO: read attributes from work[13,3], read flags
|
762
|
-
if hasdefaults > 0
|
763
|
-
|
821
|
+
if hasdefaults > 0 && work.size > 13
|
822
|
+
xf, = work[-2..-1].unpack 'v'
|
823
|
+
format = @workbook.format(xf)
|
764
824
|
end
|
765
|
-
worksheet.set_row_address index,
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
825
|
+
worksheet.set_row_address index,
|
826
|
+
:default_format => format,
|
827
|
+
:first_used => first_used,
|
828
|
+
:first_unused => first_unused,
|
829
|
+
:index => index,
|
830
|
+
:row_block => @current_row_block_offset,
|
831
|
+
:offset => @current_row_block_offset[0]
|
832
|
+
#:first_cell => offset
|
771
833
|
end
|
772
834
|
private
|
773
835
|
def extend_internals version
|
774
836
|
require 'spreadsheet/excel/internals/biff%i' % version
|
775
837
|
extend Internals.const_get('Biff%i' % version)
|
838
|
+
## spreadsheets may not include a codepage record.
|
839
|
+
@workbook.encoding = encoding 850 if version < 8
|
776
840
|
rescue LoadError
|
777
841
|
end
|
778
842
|
def extend_reader version
|
@@ -17,6 +17,10 @@ class Worksheet < Spreadsheet::Worksheet
|
|
17
17
|
@offset, @ole, @reader = opts[:offset], opts[:ole], opts[:reader]
|
18
18
|
@dimensions = nil
|
19
19
|
end
|
20
|
+
def column idx
|
21
|
+
ensure_rows_read
|
22
|
+
super
|
23
|
+
end
|
20
24
|
def date_base
|
21
25
|
@workbook.date_base
|
22
26
|
end
|
@@ -35,6 +39,7 @@ class Worksheet < Spreadsheet::Worksheet
|
|
35
39
|
@rows.fetch idx do
|
36
40
|
if addr = @row_addresses[idx]
|
37
41
|
row = @reader.read_row self, addr
|
42
|
+
row.default_format = addr[:default_format]
|
38
43
|
row.worksheet = self
|
39
44
|
row
|
40
45
|
else
|
@@ -73,10 +78,12 @@ class Worksheet < Spreadsheet::Worksheet
|
|
73
78
|
@dimensions[1] = [ @rows.size, @row_addresses.size ].compact.max
|
74
79
|
compact = @rows.compact
|
75
80
|
first_rows = compact.collect do |row| index_of_first row end.compact.min
|
76
|
-
first_addrs = @row_addresses.collect do |addr|
|
81
|
+
first_addrs = @row_addresses.compact.collect do |addr|
|
82
|
+
addr[:first_used] end.min
|
77
83
|
@dimensions[2] = [ first_rows, first_addrs ].compact.min
|
78
84
|
last_rows = compact.collect do |row| row.size end.max
|
79
|
-
last_addrs = @row_addresses.collect do |addr|
|
85
|
+
last_addrs = @row_addresses.compact.collect do |addr|
|
86
|
+
addr[:first_unused] end.max
|
80
87
|
@dimensions[3] = [last_rows, last_addrs].compact.max
|
81
88
|
@dimensions
|
82
89
|
end
|
@@ -21,28 +21,6 @@ class Format < DelegateClass(Format)
|
|
21
21
|
color_code(@format.send(key) || default)
|
22
22
|
end
|
23
23
|
end
|
24
|
-
XF_H_ALIGN = {
|
25
|
-
:default => 0,
|
26
|
-
:left => 1,
|
27
|
-
:center => 2,
|
28
|
-
:right => 3,
|
29
|
-
:fill => 4,
|
30
|
-
:justify => 5,
|
31
|
-
:merge => 6,
|
32
|
-
:distributed => 7,
|
33
|
-
}
|
34
|
-
XF_TEXT_DIRECTION = {
|
35
|
-
:context => 0,
|
36
|
-
:left_to_right => 1,
|
37
|
-
:right_to_left => 2,
|
38
|
-
}
|
39
|
-
XF_V_ALIGN = {
|
40
|
-
:top => 0,
|
41
|
-
:middle => 1,
|
42
|
-
:bottom => 2,
|
43
|
-
:justify => 3,
|
44
|
-
:distributed => 4,
|
45
|
-
}
|
46
24
|
boolean :hidden, :locked, :merge_range, :shrink, :text_justlast, :text_wrap,
|
47
25
|
:cross_down, :cross_up, :left, :right, :top, :bottom
|
48
26
|
color :left_color, :border
|
@@ -54,7 +32,7 @@ class Format < DelegateClass(Format)
|
|
54
32
|
color :pattern_bg_color, :pattern_bg
|
55
33
|
attr_accessor :xf_index
|
56
34
|
attr_reader :format
|
57
|
-
def initialize writer, workbook, format, type=:
|
35
|
+
def initialize writer, workbook, format=workbook.default_format, type=:format
|
58
36
|
@type = type.to_s.downcase
|
59
37
|
@format = format
|
60
38
|
@writer = writer
|
@@ -219,7 +197,7 @@ class Format < DelegateClass(Format)
|
|
219
197
|
end
|
220
198
|
def xf_pattern
|
221
199
|
ptrn = pattern_fg_color
|
222
|
-
ptrn |= pattern_bg_color
|
200
|
+
ptrn |= pattern_bg_color << 7
|
223
201
|
ptrn
|
224
202
|
end
|
225
203
|
def xf_rotation
|
@@ -235,7 +213,7 @@ class Format < DelegateClass(Format)
|
|
235
213
|
rot
|
236
214
|
end
|
237
215
|
def xf_type_prot type
|
238
|
-
type = type.to_s.downcase == 'style' ?
|
216
|
+
type = type.to_s.downcase == 'style' ? 0xfff5 : 0x0000
|
239
217
|
type |= locked
|
240
218
|
type |= hidden << 1
|
241
219
|
type
|
@@ -243,6 +221,7 @@ class Format < DelegateClass(Format)
|
|
243
221
|
def xf_used_attr
|
244
222
|
atr_num = num_format & 1
|
245
223
|
atr_fnt = font_index & 1
|
224
|
+
atr_fnt = 1 unless @format.font.color == :text
|
246
225
|
atr_alc = 0
|
247
226
|
if horizontal_align != 0 \
|
248
227
|
|| vertical_align != 2 \
|
@@ -252,9 +231,13 @@ class Format < DelegateClass(Format)
|
|
252
231
|
atr_alc = 1
|
253
232
|
end
|
254
233
|
atr_bdr = [top, bottom, left, right, cross_up, cross_down].max
|
255
|
-
atr_pat =
|
256
|
-
|
257
|
-
||
|
234
|
+
atr_pat = 0
|
235
|
+
if @format.pattern_fg_color != :border \
|
236
|
+
|| @format.pattern_bg_color != :pattern_bg \
|
237
|
+
|| pattern != 0x00
|
238
|
+
then
|
239
|
+
atr_pat = 1
|
240
|
+
end
|
258
241
|
atr_prot = hidden? || locked? ? 1 : 0
|
259
242
|
attrs = atr_num
|
260
243
|
attrs |= atr_fnt << 1
|
@@ -262,7 +245,7 @@ class Format < DelegateClass(Format)
|
|
262
245
|
attrs |= atr_bdr << 3
|
263
246
|
attrs |= atr_pat << 4
|
264
247
|
attrs |= atr_prot << 5
|
265
|
-
attrs
|
248
|
+
attrs << 2
|
266
249
|
end
|
267
250
|
end
|
268
251
|
end
|
@@ -48,16 +48,23 @@ class Workbook < Spreadsheet::Writer
|
|
48
48
|
@number_formats.delete workbook
|
49
49
|
@worksheets.delete workbook
|
50
50
|
end
|
51
|
-
def collect_formats workbook
|
51
|
+
def collect_formats workbook, opts={}
|
52
52
|
# The default cell format is always present in an Excel file, described by
|
53
53
|
# the XF record with the fixed index 15 (0-based). By default, it uses the
|
54
54
|
# worksheet/workbook default cell style, described by the very first XF
|
55
55
|
# record (index 0).
|
56
56
|
formats = []
|
57
|
+
unless opts[:existing_document]
|
58
|
+
15.times do
|
59
|
+
formats.push Format.new(self, workbook, workbook.default_format, :style)
|
60
|
+
end
|
61
|
+
formats.push Format.new(self, workbook)
|
62
|
+
end
|
57
63
|
workbook.formats.each do |fmt|
|
58
|
-
|
59
|
-
|
60
|
-
|
64
|
+
formats.push Format.new(self, workbook, fmt)
|
65
|
+
end
|
66
|
+
formats.each_with_index do |fmt, idx|
|
67
|
+
fmt.xf_index = idx
|
61
68
|
end
|
62
69
|
@formats[workbook] = formats
|
63
70
|
end
|
@@ -68,6 +75,7 @@ class Workbook < Spreadsheet::Writer
|
|
68
75
|
end
|
69
76
|
total = current.size
|
70
77
|
current.uniq!
|
78
|
+
current.delete ''
|
71
79
|
if (stored - current).empty?
|
72
80
|
## if all previously stored strings are still needed, we don't have to
|
73
81
|
# rewrite all cells because the sst-index of such string does not change.
|
@@ -78,7 +86,10 @@ class Workbook < Spreadsheet::Writer
|
|
78
86
|
end
|
79
87
|
end
|
80
88
|
def font_index workbook, font_key
|
81
|
-
@fonts[workbook][font_key] || 0
|
89
|
+
idx = @fonts[workbook][font_key] || 0
|
90
|
+
## this appears to be undocumented: the first 4 fonts seem to be accessed
|
91
|
+
# with a 0-based index, but all subsequent font indices are 1-based.
|
92
|
+
idx > 3 ? idx.next : idx
|
82
93
|
end
|
83
94
|
def number_format_index workbook, format
|
84
95
|
@number_formats[workbook][format] || 0
|
@@ -135,7 +146,7 @@ class Workbook < Spreadsheet::Writer
|
|
135
146
|
# Copy unchanged data verbatim, adjust offsets and write new records for
|
136
147
|
# changed data.
|
137
148
|
def write_changes workbook, io
|
138
|
-
collect_formats workbook
|
149
|
+
collect_formats workbook, :existing_document => true
|
139
150
|
reader = workbook.ole
|
140
151
|
sheet_data = {}
|
141
152
|
sst_status, sst_total, sst_strings = complete_sst_update? workbook
|
@@ -299,7 +310,7 @@ class Workbook < Spreadsheet::Writer
|
|
299
310
|
end
|
300
311
|
def write_fonts workbook, writer
|
301
312
|
fonts = @fonts[workbook] = {}
|
302
|
-
workbook.
|
313
|
+
@formats[workbook].each do |format|
|
303
314
|
if(font = format.font) && !fonts.include?(font.key)
|
304
315
|
fonts.store font.key, fonts.size
|
305
316
|
write_font workbook, writer, font
|
@@ -317,6 +328,8 @@ class Workbook < Spreadsheet::Writer
|
|
317
328
|
BUILTIN_FORMATS.each do |idx, str|
|
318
329
|
formats.store client(str, 'UTF8'), idx
|
319
330
|
end
|
331
|
+
## Ensure at least a 'GENERAL' format is written
|
332
|
+
formats.delete client('GENERAL', 'UTF8')
|
320
333
|
idx = 0xa4
|
321
334
|
workbook.formats.each do |fmt|
|
322
335
|
str = fmt.number_format
|
@@ -342,6 +355,7 @@ class Workbook < Spreadsheet::Writer
|
|
342
355
|
# ○ DSF ➜ 6.32
|
343
356
|
write_dsf workbook, buffer1
|
344
357
|
# ○ TABID
|
358
|
+
write_tabid workbook, buffer1
|
345
359
|
# ○ FNGROUPCOUNT
|
346
360
|
# ○ Workbook Protection Block ➜ 5.18
|
347
361
|
write_protect workbook, buffer1
|
@@ -505,6 +519,9 @@ class Workbook < Spreadsheet::Writer
|
|
505
519
|
]
|
506
520
|
write_op writer, 0x0293, data.pack('vC2')
|
507
521
|
end
|
522
|
+
def write_tabid workbook, writer
|
523
|
+
write_op writer, 0x013d, [1].pack('v')
|
524
|
+
end
|
508
525
|
def write_window1 workbook, writer
|
509
526
|
data = [
|
510
527
|
0x0000, # Horizontal position of the document window
|
@@ -555,20 +572,7 @@ class Workbook < Spreadsheet::Writer
|
|
555
572
|
# the XF record with the fixed index 15 (0-based). By default, it uses the
|
556
573
|
# worksheet/workbook default cell style, described by the very first XF
|
557
574
|
# record (index 0).
|
558
|
-
|
559
|
-
default = formats.first
|
560
|
-
## First 15 formats, or dummy/default styles if there are fewer formats
|
561
|
-
fmts1 = formats.slice!(0,15)
|
562
|
-
while fmts1.size < 15 do
|
563
|
-
fmt = Format.new self, workbook, workbook.default_format, writer
|
564
|
-
fmt.xf_index = fmts1.size
|
565
|
-
fmts1.push fmt
|
566
|
-
end
|
567
|
-
fmts1.each do |fmt| fmt.write_xf writer end
|
568
|
-
## Default cell format
|
569
|
-
default.write_xf writer, :format
|
570
|
-
## remaining formats
|
571
|
-
formats.each do |fmt| fmt.write_xf writer end
|
575
|
+
@formats[workbook].each do |fmt| fmt.write_xf writer end
|
572
576
|
end
|
573
577
|
def sst_index worksheet, str
|
574
578
|
@sst[worksheet][str]
|
@@ -100,7 +100,7 @@ class Worksheet
|
|
100
100
|
end
|
101
101
|
def strings
|
102
102
|
@worksheet.inject [] do |memo, row|
|
103
|
-
strings = row.select do |cell| cell.is_a?
|
103
|
+
strings = row.select do |cell| cell.is_a?(String) && !cell.empty? end
|
104
104
|
memo.concat strings
|
105
105
|
end
|
106
106
|
end
|
@@ -171,8 +171,9 @@ class Worksheet
|
|
171
171
|
# RSTRING ➜ 6.84 (BIFF5/BIFF7)
|
172
172
|
multiples, first_idx = nil
|
173
173
|
row.each_with_index do |cell, idx|
|
174
|
-
|
175
|
-
|
174
|
+
cell = nil if cell == ''
|
175
|
+
number = cell.is_a?(Float) && cell.to_s.length > 5
|
176
|
+
if multiples && (!multiples.last.is_a?(cell.class) || number)
|
176
177
|
write_multiples row, first_idx, multiples
|
177
178
|
multiples, first_idx = nil
|
178
179
|
end
|
@@ -196,7 +197,7 @@ class Worksheet
|
|
196
197
|
# 10^9. Not sure what is a good rule of thumb here, but it seems that
|
197
198
|
# Decimal Numbers with more than 4 significant digits are not represented
|
198
199
|
# with sufficient precision by RK
|
199
|
-
if
|
200
|
+
if number
|
200
201
|
write_number row, idx
|
201
202
|
elsif multiples
|
202
203
|
multiples.push cell
|
@@ -240,6 +241,43 @@ class Worksheet
|
|
240
241
|
end
|
241
242
|
@io.write reader.read(endpos - lastpos)
|
242
243
|
end
|
244
|
+
def write_colinfo bunch
|
245
|
+
col = bunch.first
|
246
|
+
width = col.width.to_f * 256
|
247
|
+
xf_idx = @workbook.xf_index @worksheet.workbook, col.default_format
|
248
|
+
opts = 0
|
249
|
+
opts |= 0x0001 if col.hidden?
|
250
|
+
opts |= col.outline_level.to_i << 8
|
251
|
+
opts |= 0x1000 if col.collapsed?
|
252
|
+
data = [
|
253
|
+
col.idx, # Index to first column in the range
|
254
|
+
bunch.last.idx, # Index to last column in the range
|
255
|
+
width.to_i, # Width of the columns in 1/256 of the width of the zero
|
256
|
+
# character, using default font (first FONT record in the
|
257
|
+
# file)
|
258
|
+
xf_idx.to_i, # Index to XF record (➜ 6.115) for default column formatting
|
259
|
+
opts, # Option flags:
|
260
|
+
# Bits Mask Contents
|
261
|
+
# 0 0x0001 1 = Columns are hidden
|
262
|
+
# 10-8 0x0700 Outline level of the columns
|
263
|
+
# (0 = no outline)
|
264
|
+
# 12 0x1000 1 = Columns are collapsed
|
265
|
+
]
|
266
|
+
write_op opcode(:colinfo), data.pack(binfmt(:colinfo))
|
267
|
+
end
|
268
|
+
def write_colinfos
|
269
|
+
cols = @worksheet.columns
|
270
|
+
bunch = []
|
271
|
+
cols.each_with_index do |column, idx|
|
272
|
+
if column
|
273
|
+
bunch << column
|
274
|
+
if cols[idx.next] != column
|
275
|
+
write_colinfo bunch
|
276
|
+
bunch.clear
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|
243
281
|
def write_defaultrowheight
|
244
282
|
data = [
|
245
283
|
0x00, # Option flags:
|
@@ -252,6 +290,20 @@ class Worksheet
|
|
252
290
|
]
|
253
291
|
write_op 0x0225, data.pack('v2')
|
254
292
|
end
|
293
|
+
def write_defcolwidth
|
294
|
+
# Offset Size Contents
|
295
|
+
# 0 2 Column width in characters, using the width of the zero
|
296
|
+
# character from default font (first FONT record in the
|
297
|
+
# file). Excel adds some extra space to the default width,
|
298
|
+
# depending on the default font and default font size. The
|
299
|
+
# algorithm how to exactly calculate the resulting column
|
300
|
+
# width is not known.
|
301
|
+
#
|
302
|
+
# Example: The default width of 8 set in this record results
|
303
|
+
# in a column width of 8.43 using Arial font with a size of
|
304
|
+
# 10 points.
|
305
|
+
write_op 0x0055, [8].pack('v')
|
306
|
+
end
|
255
307
|
def write_dimensions
|
256
308
|
# Offset Size Contents
|
257
309
|
# 0 4 Index to first used row
|
@@ -268,11 +320,12 @@ class Worksheet
|
|
268
320
|
# Write a cell with a Formula. May write an additional String record depending
|
269
321
|
# on the stored result of the Formula.
|
270
322
|
def write_formula row, idx
|
323
|
+
xf_idx = @workbook.xf_index @worksheet.workbook, row.format(idx)
|
271
324
|
cell = row[idx]
|
272
325
|
data1 = [
|
273
326
|
row.idx, # Index to row
|
274
327
|
idx, # Index to column
|
275
|
-
|
328
|
+
xf_idx, # Index to XF record (➜ 6.115)
|
276
329
|
].pack 'v3'
|
277
330
|
data2 = nil
|
278
331
|
case value = cell.value
|
@@ -345,7 +398,9 @@ class Worksheet
|
|
345
398
|
# ○ Page Settings Block ➜ 5.4
|
346
399
|
# ○ Worksheet Protection Block ➜ 5.18
|
347
400
|
# ○ DEFCOLWIDTH ➜ 6.29
|
401
|
+
write_defcolwidth
|
348
402
|
# ○○ COLINFO ➜ 6.18
|
403
|
+
write_colinfos
|
349
404
|
# ○ SORT ➜ 6.95
|
350
405
|
# ● DIMENSIONS ➜ 6.31
|
351
406
|
write_dimensions
|
@@ -400,9 +455,9 @@ class Worksheet
|
|
400
455
|
idx, # Index to first column (fc)
|
401
456
|
]
|
402
457
|
# List of nc=lc-fc+1 16-bit indexes to XF records (➜ 6.115)
|
403
|
-
multiples.
|
404
|
-
|
405
|
-
data.push
|
458
|
+
multiples.each_with_index do |cell, cell_idx|
|
459
|
+
xf_idx = @workbook.xf_index @worksheet.workbook, row.format(idx + cell_idx)
|
460
|
+
data.push xf_idx, encode_rk(cell)
|
406
461
|
fmt << 'vV'
|
407
462
|
end
|
408
463
|
# Index to last column (lc)
|
@@ -477,9 +532,12 @@ class Worksheet
|
|
477
532
|
0, # Not used
|
478
533
|
has_defaults,
|
479
534
|
0, # OOffice does not set this - ignore until someone complains
|
535
|
+
1,
|
536
|
+
15,
|
537
|
+
0,
|
480
538
|
]
|
481
539
|
# OpenOffice apparently can't read Rows with a length other than 16 Bytes
|
482
|
-
fmt = binfmt(:row) + '
|
540
|
+
fmt = binfmt(:row) + 'C3'
|
483
541
|
=begin
|
484
542
|
if format = row.default_format
|
485
543
|
fmt = fmt + 'xv'
|
data/lib/spreadsheet/font.rb
CHANGED
@@ -59,9 +59,12 @@ module Spreadsheet
|
|
59
59
|
:korean_hangul, :korean_johab, :chinese_simplified,
|
60
60
|
:chinese_traditional, :greek, :turkish, :vietnamese,
|
61
61
|
:hebrew, :arabic, :cyrillic, :thai, :iso_latin2, :oem_latin1
|
62
|
-
def initialize name
|
62
|
+
def initialize name, opts={}
|
63
63
|
self.name = name
|
64
64
|
@color = :text
|
65
|
+
opts.each do |key, val|
|
66
|
+
self.send "#{key}=", val
|
67
|
+
end
|
65
68
|
end
|
66
69
|
##
|
67
70
|
# Sets #weight to :bold if(_bool_), :normal otherwise.
|
data/lib/spreadsheet/format.rb
CHANGED
@@ -33,7 +33,7 @@ module Spreadsheet
|
|
33
33
|
##
|
34
34
|
# Color attributes
|
35
35
|
colors :bottom_color, :top_color, :left_color, :right_color,
|
36
|
-
:
|
36
|
+
:pattern_fg_color, :pattern_bg_color,
|
37
37
|
:diagonal_color
|
38
38
|
##
|
39
39
|
# Text direction
|
@@ -72,16 +72,15 @@ module Spreadsheet
|
|
72
72
|
# Text rotation
|
73
73
|
attr_reader :rotation
|
74
74
|
def initialize opts={}
|
75
|
-
@font = Font.new client("Arial", 'UTF8')
|
76
|
-
@number_format = client '
|
75
|
+
@font = Font.new client("Arial", 'UTF8'), :family => :swiss
|
76
|
+
@number_format = client 'GENERAL', 'UTF8'
|
77
77
|
@rotation = 0
|
78
|
-
@bg_color = :pattern_bg
|
79
78
|
@pattern = 0
|
80
|
-
@bottom_color = :
|
81
|
-
@top_color = :
|
82
|
-
@left_color = :
|
83
|
-
@right_color = :
|
84
|
-
@diagonal_color = :
|
79
|
+
@bottom_color = :builtin_black
|
80
|
+
@top_color = :builtin_black
|
81
|
+
@left_color = :builtin_black
|
82
|
+
@right_color = :builtin_black
|
83
|
+
@diagonal_color = :builtin_black
|
85
84
|
@pattern_fg_color = :border
|
86
85
|
@pattern_bg_color = :pattern_bg
|
87
86
|
# Temp code to prevent merged formats in non-merged cells.
|
data/lib/spreadsheet/row.rb
CHANGED
@@ -47,7 +47,7 @@ module Spreadsheet
|
|
47
47
|
# Set the default Format used when writing a Cell if no explicit Format is
|
48
48
|
# stored for the cell.
|
49
49
|
def default_format= format
|
50
|
-
@worksheet.add_format format
|
50
|
+
@worksheet.add_format format if @worksheet
|
51
51
|
@default_format = format
|
52
52
|
end
|
53
53
|
##
|
@@ -60,10 +60,11 @@ module Spreadsheet
|
|
60
60
|
index_of_first self
|
61
61
|
end
|
62
62
|
##
|
63
|
-
# The Format for the Cell at _idx_ (0-based), or
|
64
|
-
#
|
63
|
+
# The Format for the Cell at _idx_ (0-based), or the first valid Format in
|
64
|
+
# Row#default_format, Column#default_format and Worksheet#default_format.
|
65
65
|
def format idx
|
66
|
-
@formats[idx] || @default_format
|
66
|
+
@formats[idx] || @default_format \
|
67
|
+
|| @worksheet.column(idx).default_format if @worksheet
|
67
68
|
end
|
68
69
|
##
|
69
70
|
# Set the Format for the Cell at _idx_ (0-based).
|
data/lib/spreadsheet/workbook.rb
CHANGED
@@ -27,13 +27,14 @@ module Spreadsheet
|
|
27
27
|
# Add a Font to the Workbook. Used by the parser. You should not need to
|
28
28
|
# use this Method.
|
29
29
|
def add_font font
|
30
|
-
@fonts.push font
|
30
|
+
@fonts.push(font).uniq! if font
|
31
|
+
font
|
31
32
|
end
|
32
33
|
##
|
33
34
|
# Add a Format to the Workbook. If you use Row#set_format, you should not
|
34
35
|
# need to use this Method.
|
35
36
|
def add_format format
|
36
|
-
@formats.push(format).
|
37
|
+
@formats.push(format) if format && !@formats.include?(format)
|
37
38
|
format
|
38
39
|
end
|
39
40
|
##
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'date'
|
2
|
+
require 'spreadsheet/column'
|
2
3
|
require 'spreadsheet/encodings'
|
3
4
|
require 'spreadsheet/row'
|
4
5
|
|
@@ -14,22 +15,27 @@ module Spreadsheet
|
|
14
15
|
# #rows :: The Rows in this Worksheet. It is not recommended to
|
15
16
|
# Manipulate this Array directly. If you do, call
|
16
17
|
# #updated_from with the smallest modified index.
|
18
|
+
# #columns :: The Column formatting in this Worksheet. Column
|
19
|
+
# instances may appear at more than one position in #columns.
|
20
|
+
# If you modify a Column directly, your changes will be
|
21
|
+
# reflected in all those positions.
|
17
22
|
class Worksheet
|
18
23
|
include Encodings
|
19
|
-
attr_accessor :name, :workbook
|
20
|
-
attr_reader :rows
|
21
24
|
include Enumerable
|
25
|
+
attr_accessor :name, :workbook
|
26
|
+
attr_reader :rows, :columns
|
22
27
|
def initialize opts={}
|
23
28
|
@dimensions = [0,0,0,0]
|
24
29
|
@name = opts[:name] || 'Worksheet'
|
25
30
|
@workbook = opts[:workbook]
|
26
31
|
@rows = []
|
32
|
+
@columns = []
|
27
33
|
end
|
28
34
|
##
|
29
35
|
# Add a Format to the Workbook. If you use Row#set_format, you should not
|
30
36
|
# need to use this Method.
|
31
37
|
def add_format fmt
|
32
|
-
@workbook.add_format fmt
|
38
|
+
@workbook.add_format fmt if fmt
|
33
39
|
end
|
34
40
|
##
|
35
41
|
# Get the enriched value of the Cell at _row_, _column_.
|
@@ -38,6 +44,11 @@ module Spreadsheet
|
|
38
44
|
row(row)[column]
|
39
45
|
end
|
40
46
|
##
|
47
|
+
# Returns the Column at _idx_.
|
48
|
+
def column idx
|
49
|
+
@columns[idx] || Column.new(idx, default_format, :worksheet => self)
|
50
|
+
end
|
51
|
+
##
|
41
52
|
# The number of columns in this Worksheet which contain data.
|
42
53
|
def column_count
|
43
54
|
dimensions[3] - dimensions[2]
|
@@ -59,7 +70,7 @@ module Spreadsheet
|
|
59
70
|
# Set the default Format of this Worksheet.
|
60
71
|
def default_format= format
|
61
72
|
@default_format = format
|
62
|
-
add_format format
|
73
|
+
add_format format
|
63
74
|
format
|
64
75
|
end
|
65
76
|
##
|
@@ -87,6 +98,31 @@ module Spreadsheet
|
|
87
98
|
@workbook.encoding
|
88
99
|
end
|
89
100
|
##
|
101
|
+
# Sets the default Format of the column at _idx_.
|
102
|
+
#
|
103
|
+
# _idx_ may be an Integer, or an Enumerable that iterates over a number of
|
104
|
+
# Integers.
|
105
|
+
#
|
106
|
+
# _format_ is a Format, or nil if you want to remove the Formatting at _idx_
|
107
|
+
#
|
108
|
+
# Returns an instance of Column if _idx_ is an Integer, an Array of Columns
|
109
|
+
# otherwise.
|
110
|
+
def format_column idx, format=nil, opts={}
|
111
|
+
opts[:worksheet] = self
|
112
|
+
res = case idx
|
113
|
+
when Integer
|
114
|
+
column = nil
|
115
|
+
if format
|
116
|
+
column = Column.new(idx, format, opts)
|
117
|
+
end
|
118
|
+
@columns[idx] = column
|
119
|
+
else
|
120
|
+
idx.collect do |col| format_column col, format, opts end
|
121
|
+
end
|
122
|
+
shorten @columns
|
123
|
+
res
|
124
|
+
end
|
125
|
+
##
|
90
126
|
# Insert a Row at _idx_ (0-based) containing _cells_
|
91
127
|
def insert_row idx, cells=[]
|
92
128
|
res = @rows.insert idx, Row.new(self, idx, cells)
|
data/test/font.rb
CHANGED
@@ -77,11 +77,11 @@ module Spreadsheet
|
|
77
77
|
assert_equal true, @font.shadow
|
78
78
|
end
|
79
79
|
def test_size
|
80
|
-
assert_equal 10, @font.size
|
80
|
+
assert_equal 10, @font.size
|
81
81
|
@font.size = 12
|
82
|
-
assert_equal 12, @font.size
|
82
|
+
assert_equal 12, @font.size
|
83
83
|
@font.size = 11.2
|
84
|
-
assert_equal 11.2, @font.size
|
84
|
+
assert_equal 11.2, @font.size
|
85
85
|
assert_raises ArgumentError do @font.size = "123" end
|
86
86
|
end
|
87
87
|
def test_strikeout
|
data/test/integration.rb
CHANGED
@@ -37,7 +37,7 @@ module Spreadsheet
|
|
37
37
|
book = Spreadsheet.open path
|
38
38
|
assert_instance_of Excel::Workbook, book
|
39
39
|
assert_equal 8, book.biff_version
|
40
|
-
assert_equal @@iconv.iconv('Microsoft Excel 97/2000/XP'),
|
40
|
+
assert_equal @@iconv.iconv('Microsoft Excel 97/2000/XP'),
|
41
41
|
book.version_string
|
42
42
|
enc = 'UTF-16LE'
|
43
43
|
if defined? Encoding
|
@@ -532,13 +532,13 @@ module Spreadsheet
|
|
532
532
|
end
|
533
533
|
end
|
534
534
|
assert_equal long, str4
|
535
|
-
sheet = book.worksheet 0
|
535
|
+
sheet = book.worksheet 0
|
536
536
|
sheet[0,0] = 4
|
537
537
|
row = sheet.row 1
|
538
538
|
row[0] = 3
|
539
539
|
book.write path
|
540
540
|
assert_nothing_raised do book = Spreadsheet.open path end
|
541
|
-
sheet = book.worksheet 0
|
541
|
+
sheet = book.worksheet 0
|
542
542
|
assert_equal 10, sheet.row_count
|
543
543
|
assert_equal 11, sheet.column_count
|
544
544
|
useds = [0,0,0,0,0,0,0,1,0,0]
|
@@ -635,7 +635,7 @@ module Spreadsheet
|
|
635
635
|
end
|
636
636
|
end
|
637
637
|
assert_equal long, str4
|
638
|
-
sheet = book.worksheet 0
|
638
|
+
sheet = book.worksheet 0
|
639
639
|
sheet[0,0] = 4
|
640
640
|
str5 = 'A completely different String'
|
641
641
|
sheet[0,1] = str5
|
@@ -647,7 +647,7 @@ module Spreadsheet
|
|
647
647
|
assert_equal str2, book.shared_string(1)
|
648
648
|
assert_equal str3, book.shared_string(2)
|
649
649
|
assert_equal str4, book.shared_string(3)
|
650
|
-
sheet = book.worksheet 0
|
650
|
+
sheet = book.worksheet 0
|
651
651
|
assert_equal 10, sheet.row_count
|
652
652
|
assert_equal 11, sheet.column_count
|
653
653
|
useds = [0,0,0,0,0,0,0,1,0,0]
|
@@ -719,6 +719,13 @@ module Spreadsheet
|
|
719
719
|
str2 = 'Another Shared String'
|
720
720
|
str3 = '1234567890 ' * 1000
|
721
721
|
str4 = '9876543210 ' * 1000
|
722
|
+
fmt1 = Format.new :italic => true, :color => :blue
|
723
|
+
sheet1.format_column 1, fmt1, :width => 20
|
724
|
+
fmt2 = Format.new(:weight => :bold, :color => :yellow)
|
725
|
+
sheet1.format_column 2, fmt2
|
726
|
+
sheet1.format_column 3, Format.new(:weight => :bold, :color => :red)
|
727
|
+
sheet1.format_column 6..9, fmt1
|
728
|
+
sheet1.format_column [4,5,7], fmt2
|
722
729
|
sheet1[0,0] = str1
|
723
730
|
sheet1.row(0).push str1
|
724
731
|
sheet1.row(1).concat [str2, str2]
|
@@ -797,10 +804,15 @@ module Spreadsheet
|
|
797
804
|
assert_equal 2, book.worksheets.size
|
798
805
|
sheet = book.worksheets.first
|
799
806
|
assert_instance_of Spreadsheet::Excel::Worksheet, sheet
|
800
|
-
assert_equal "W\000o\000r\000k\000s\000h\000e\000e\000t\0001\000",
|
807
|
+
assert_equal "W\000o\000r\000k\000s\000h\000e\000e\000t\0001\000",
|
801
808
|
sheet.name
|
802
809
|
assert_not_nil sheet.offset
|
810
|
+
assert_not_nil col = sheet.column(1)
|
811
|
+
assert_equal true, col.default_format.font.italic?
|
812
|
+
assert_equal :blue, col.default_format.font.color
|
813
|
+
assert_equal 20, col.width
|
803
814
|
row = sheet.row 0
|
815
|
+
assert_equal col.default_format, row.format(1)
|
804
816
|
assert_equal str1, row[0]
|
805
817
|
assert_equal str1, sheet[0,0]
|
806
818
|
assert_equal str1, sheet.cell(0,0)
|
@@ -880,7 +892,7 @@ module Spreadsheet
|
|
880
892
|
assert_equal 1.00005, sheet1[10,4]
|
881
893
|
assert_instance_of Spreadsheet::Excel::Worksheet, sheet
|
882
894
|
sheet = book.worksheets.last
|
883
|
-
assert_equal "m\000y\000 \000n\000a\000m\000e\000",
|
895
|
+
assert_equal "m\000y\000 \000n\000a\000m\000e\000",
|
884
896
|
sheet.name
|
885
897
|
assert_not_nil sheet.offset
|
886
898
|
end
|
@@ -893,6 +905,8 @@ module Spreadsheet
|
|
893
905
|
str2 = @@iconv.iconv 'Another Shared String'
|
894
906
|
str3 = @@iconv.iconv('1234567890 ' * 1000)
|
895
907
|
str4 = @@iconv.iconv('9876543210 ' * 1000)
|
908
|
+
fmt = Format.new :italic => true, :color => :blue
|
909
|
+
sheet1.format_column 1, fmt, :width => 20
|
896
910
|
sheet1[0,0] = str1
|
897
911
|
sheet1.row(0).push str1
|
898
912
|
sheet1.row(1).concat [str2, str2]
|
@@ -948,7 +962,11 @@ module Spreadsheet
|
|
948
962
|
assert_instance_of Spreadsheet::Excel::Worksheet, sheet
|
949
963
|
assert_equal "Worksheet1", sheet.name
|
950
964
|
assert_not_nil sheet.offset
|
965
|
+
assert_not_nil col = sheet.column(1)
|
966
|
+
assert_equal true, col.default_format.font.italic?
|
967
|
+
assert_equal :blue, col.default_format.font.color
|
951
968
|
row = sheet.row 0
|
969
|
+
assert_equal col.default_format, row.format(1)
|
952
970
|
assert_equal str1, row[0]
|
953
971
|
assert_equal str1, sheet[0,0]
|
954
972
|
assert_equal str1, sheet.cell(0,0)
|
@@ -1008,14 +1026,9 @@ module Spreadsheet
|
|
1008
1026
|
assert_equal [1,2,3,4,5,6,7,8,9,0], sheet.cell(7,1..10)
|
1009
1027
|
assert_instance_of Spreadsheet::Excel::Worksheet, sheet
|
1010
1028
|
sheet = book.worksheets.last
|
1011
|
-
assert_equal "my name",
|
1029
|
+
assert_equal "my name",
|
1012
1030
|
sheet.name
|
1013
1031
|
assert_not_nil sheet.offset
|
1014
1032
|
end
|
1015
|
-
def test_read_bsv
|
1016
|
-
book = Spreadsheet.open '/home/hwyss/cogito/oddb.org/data/xls/BSV_per_2008.10.01.xls'
|
1017
|
-
sheet = book.worksheet 0
|
1018
|
-
assert_equal Date.new(2000), sheet[1,6]
|
1019
|
-
end
|
1020
1033
|
end
|
1021
1034
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spreadsheet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hannes Wyss
|
@@ -9,9 +9,19 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-10-
|
12
|
+
date: 2008-10-17 00:00:00 +02:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: ruby-ole
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
15
25
|
- !ruby/object:Gem::Dependency
|
16
26
|
name: hoe
|
17
27
|
type: :development
|