spreadsheet 0.6.0 → 0.6.1
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 +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
|