keeguon-spreadsheet 0.9.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.
- checksums.yaml +7 -0
- data/LICENSE.txt +619 -0
- data/Manifest.txt +85 -0
- data/bin/xlsopcodes +18 -0
- data/lib/parseexcel.rb +27 -0
- data/lib/parseexcel/parseexcel.rb +75 -0
- data/lib/parseexcel/parser.rb +11 -0
- data/lib/spreadsheet.rb +80 -0
- data/lib/spreadsheet/column.rb +71 -0
- data/lib/spreadsheet/compatibility.rb +23 -0
- data/lib/spreadsheet/datatypes.rb +161 -0
- data/lib/spreadsheet/encodings.rb +57 -0
- data/lib/spreadsheet/excel.rb +88 -0
- data/lib/spreadsheet/excel/error.rb +26 -0
- data/lib/spreadsheet/excel/internals.rb +458 -0
- data/lib/spreadsheet/excel/internals/biff5.rb +17 -0
- data/lib/spreadsheet/excel/internals/biff8.rb +19 -0
- data/lib/spreadsheet/excel/offset.rb +41 -0
- data/lib/spreadsheet/excel/password_hash.rb +24 -0
- data/lib/spreadsheet/excel/reader.rb +1302 -0
- data/lib/spreadsheet/excel/reader/biff5.rb +42 -0
- data/lib/spreadsheet/excel/reader/biff8.rb +231 -0
- data/lib/spreadsheet/excel/rgb.rb +122 -0
- data/lib/spreadsheet/excel/row.rb +98 -0
- data/lib/spreadsheet/excel/sst_entry.rb +46 -0
- data/lib/spreadsheet/excel/workbook.rb +80 -0
- data/lib/spreadsheet/excel/worksheet.rb +115 -0
- data/lib/spreadsheet/excel/writer.rb +1 -0
- data/lib/spreadsheet/excel/writer/biff8.rb +75 -0
- data/lib/spreadsheet/excel/writer/format.rb +264 -0
- data/lib/spreadsheet/excel/writer/n_worksheet.rb +888 -0
- data/lib/spreadsheet/excel/writer/workbook.rb +735 -0
- data/lib/spreadsheet/excel/writer/worksheet.rb +940 -0
- data/lib/spreadsheet/font.rb +115 -0
- data/lib/spreadsheet/format.rb +209 -0
- data/lib/spreadsheet/formula.rb +9 -0
- data/lib/spreadsheet/helpers.rb +11 -0
- data/lib/spreadsheet/link.rb +43 -0
- data/lib/spreadsheet/note.rb +23 -0
- data/lib/spreadsheet/noteObject.rb +17 -0
- data/lib/spreadsheet/row.rb +151 -0
- data/lib/spreadsheet/workbook.rb +143 -0
- data/lib/spreadsheet/worksheet.rb +326 -0
- data/lib/spreadsheet/writer.rb +30 -0
- data/test/data/test_adding_data_to_existing_file.xls +0 -0
- data/test/data/test_borders.xls +0 -0
- data/test/data/test_changes.xls +0 -0
- data/test/data/test_comment.xls +0 -0
- data/test/data/test_copy.xls +0 -0
- data/test/data/test_datetime.xls +0 -0
- data/test/data/test_empty.xls +0 -0
- data/test/data/test_formula.xls +0 -0
- data/test/data/test_long_sst_record.xls +0 -0
- data/test/data/test_margin.xls +0 -0
- data/test/data/test_merged_and_protected.xls +0 -0
- data/test/data/test_merged_cells.xls +0 -0
- data/test/data/test_missing_row.xls +0 -0
- data/test/data/test_pagesetup.xls +0 -0
- data/test/data/test_version_excel5.xls +0 -0
- data/test/data/test_version_excel95.xls +0 -0
- data/test/data/test_version_excel97.xls +0 -0
- data/test/data/test_version_excel97_2010.xls +0 -0
- data/test/data/test_worksheet_visibility.xls +0 -0
- data/test/excel/reader.rb +30 -0
- data/test/excel/row.rb +40 -0
- data/test/excel/writer/workbook.rb +95 -0
- data/test/excel/writer/worksheet.rb +81 -0
- data/test/font.rb +163 -0
- data/test/format.rb +95 -0
- data/test/integration.rb +1390 -0
- data/test/row.rb +33 -0
- data/test/suite.rb +18 -0
- data/test/workbook.rb +55 -0
- data/test/workbook_protection.rb +19 -0
- data/test/worksheet.rb +112 -0
- metadata +148 -0
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'spreadsheet/encodings'
|
2
|
+
|
3
|
+
module Spreadsheet
|
4
|
+
module Excel
|
5
|
+
##
|
6
|
+
# Shared String Table Entry
|
7
|
+
class SstEntry
|
8
|
+
include Spreadsheet::Encodings
|
9
|
+
attr_accessor :chars, :phonetic, :richtext, :flags, :available,
|
10
|
+
:continued_chars, :wide
|
11
|
+
def initialize opts = {}
|
12
|
+
@content = nil
|
13
|
+
@offset = opts[:offset]
|
14
|
+
@ole = opts[:ole]
|
15
|
+
@reader = opts[:reader]
|
16
|
+
@continuations = []
|
17
|
+
end
|
18
|
+
##
|
19
|
+
# Access the contents of this Shared String
|
20
|
+
def content
|
21
|
+
@content or begin
|
22
|
+
data = nil
|
23
|
+
data = @ole[@offset, @available]
|
24
|
+
content, _ = @reader.read_string_body data, @flags, @available, @wide
|
25
|
+
@continuations.each do |offset, len|
|
26
|
+
@reader.continue_string(@ole[offset,len], [content, @chars])
|
27
|
+
end
|
28
|
+
content = client content, 'UTF-16LE'
|
29
|
+
if @reader.memoize?
|
30
|
+
@content = content
|
31
|
+
end
|
32
|
+
content
|
33
|
+
end
|
34
|
+
end
|
35
|
+
##
|
36
|
+
# Register the offset of a String continuation
|
37
|
+
def continue offset, size, chars
|
38
|
+
@continued_chars -= chars
|
39
|
+
@continuations.push [offset, size]
|
40
|
+
end
|
41
|
+
def continued? # :nodoc:
|
42
|
+
@continued_chars > 0
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'spreadsheet/workbook'
|
2
|
+
require 'spreadsheet/excel/offset'
|
3
|
+
require 'spreadsheet/excel/writer'
|
4
|
+
require 'ole/storage'
|
5
|
+
|
6
|
+
module Spreadsheet
|
7
|
+
module Excel
|
8
|
+
##
|
9
|
+
# Excel-specific Workbook methods. These are mostly pertinent to the Excel
|
10
|
+
# reader. You should have no reason to use any of these.
|
11
|
+
class Workbook < Spreadsheet::Workbook
|
12
|
+
include Spreadsheet::Encodings
|
13
|
+
include Spreadsheet::Excel::Offset
|
14
|
+
BIFF_VERSIONS = {
|
15
|
+
0x000 => 2,
|
16
|
+
0x007 => 2,
|
17
|
+
0x200 => 2,
|
18
|
+
0x300 => 3,
|
19
|
+
0x400 => 4,
|
20
|
+
0x500 => 5,
|
21
|
+
0x600 => 8,
|
22
|
+
}
|
23
|
+
VERSION_STRINGS = {
|
24
|
+
0x600 => 'Microsoft Excel 97/2000/XP',
|
25
|
+
0x500 => 'Microsoft Excel 95',
|
26
|
+
}
|
27
|
+
offset :encoding, :boundsheets, :sst
|
28
|
+
attr_accessor :bof, :ole
|
29
|
+
attr_writer :date_base
|
30
|
+
def Workbook.open io, opts = {}
|
31
|
+
@reader = Reader.new opts
|
32
|
+
@reader.read io
|
33
|
+
end
|
34
|
+
def initialize *args
|
35
|
+
super
|
36
|
+
enc = 'UTF-16LE'
|
37
|
+
if RUBY_VERSION >= '1.9'
|
38
|
+
enc = Encoding.find enc
|
39
|
+
end
|
40
|
+
@encoding = enc
|
41
|
+
@version = 0x600
|
42
|
+
@sst = []
|
43
|
+
end
|
44
|
+
def add_shared_string str
|
45
|
+
@sst.push str
|
46
|
+
end
|
47
|
+
def add_worksheet worksheet
|
48
|
+
@changes.store :boundsheets, true
|
49
|
+
super
|
50
|
+
end
|
51
|
+
def biff_version
|
52
|
+
case @bof
|
53
|
+
when 0x009
|
54
|
+
2
|
55
|
+
when 0x209
|
56
|
+
3
|
57
|
+
when 0x409
|
58
|
+
4
|
59
|
+
else
|
60
|
+
BIFF_VERSIONS.fetch(@version) { raise "Unkown BIFF_VERSION '#@version'" }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
def date_base
|
64
|
+
@date_base ||= DateTime.new 1899, 12, 31
|
65
|
+
end
|
66
|
+
def shared_string idx
|
67
|
+
@sst[idx.to_i].content
|
68
|
+
end
|
69
|
+
def sst_size
|
70
|
+
@sst.size
|
71
|
+
end
|
72
|
+
def uninspect_variables
|
73
|
+
super.push '@sst', '@offsets', '@changes'
|
74
|
+
end
|
75
|
+
def version_string
|
76
|
+
client VERSION_STRINGS.fetch(@version, "Unknown"), 'UTF-8'
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'spreadsheet/excel/offset'
|
2
|
+
require 'spreadsheet/excel/row'
|
3
|
+
require 'spreadsheet/worksheet'
|
4
|
+
|
5
|
+
module Spreadsheet
|
6
|
+
module Excel
|
7
|
+
##
|
8
|
+
# Excel-specific Worksheet methods. These are mostly pertinent to the Excel
|
9
|
+
# reader, and to recording changes to the Worksheet. You should have no reason
|
10
|
+
# to use any of these.
|
11
|
+
class Worksheet < Spreadsheet::Worksheet
|
12
|
+
include Spreadsheet::Excel::Offset
|
13
|
+
offset :dimensions
|
14
|
+
attr_reader :offset, :ole, :links, :guts, :notes
|
15
|
+
def initialize opts = {}
|
16
|
+
@row_addresses = nil
|
17
|
+
super
|
18
|
+
@offset, @ole, @reader = opts[:offset], opts[:ole], opts[:reader]
|
19
|
+
@dimensions = nil
|
20
|
+
@links = {}
|
21
|
+
@guts = {}
|
22
|
+
@notes = {}
|
23
|
+
end
|
24
|
+
def add_link row, column, link
|
25
|
+
@links.store [row, column], link
|
26
|
+
end
|
27
|
+
def add_note row, column, note
|
28
|
+
@notes.store [row, column], note
|
29
|
+
end
|
30
|
+
def column idx
|
31
|
+
ensure_rows_read
|
32
|
+
super
|
33
|
+
end
|
34
|
+
def date_base
|
35
|
+
@workbook.date_base
|
36
|
+
end
|
37
|
+
def margins
|
38
|
+
ensure_rows_read
|
39
|
+
super
|
40
|
+
end
|
41
|
+
def pagesetup
|
42
|
+
ensure_rows_read
|
43
|
+
super
|
44
|
+
end
|
45
|
+
def each *args
|
46
|
+
ensure_rows_read
|
47
|
+
super
|
48
|
+
end
|
49
|
+
def ensure_rows_read
|
50
|
+
return if @row_addresses
|
51
|
+
@dimensions = nil
|
52
|
+
@row_addresses = []
|
53
|
+
@reader.read_worksheet self, @offset if @reader
|
54
|
+
end
|
55
|
+
def row idx
|
56
|
+
@rows[idx] or begin
|
57
|
+
ensure_rows_read
|
58
|
+
if addr = @row_addresses[idx]
|
59
|
+
row = @reader.read_row self, addr
|
60
|
+
[:default_format, :height, :outline_level, :hidden, ].each do |key|
|
61
|
+
row.send "unupdated_#{key}=", addr[key]
|
62
|
+
end
|
63
|
+
row.worksheet = self
|
64
|
+
row
|
65
|
+
else
|
66
|
+
Row.new self, idx
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
def rows
|
71
|
+
self.to_a
|
72
|
+
end
|
73
|
+
def row_updated idx, row
|
74
|
+
res = super
|
75
|
+
@workbook.changes.store self, true
|
76
|
+
@workbook.changes.store :boundsheets, true
|
77
|
+
@changes.store idx, true
|
78
|
+
@changes.store :dimensions, true
|
79
|
+
res
|
80
|
+
end
|
81
|
+
def set_row_address idx, opts
|
82
|
+
@offsets.store idx, opts[:row_block]
|
83
|
+
@row_addresses[idx] = opts
|
84
|
+
end
|
85
|
+
def shared_string idx
|
86
|
+
@workbook.shared_string idx
|
87
|
+
end
|
88
|
+
private
|
89
|
+
## premature optimization?
|
90
|
+
def have_set_dimensions value, pos, len
|
91
|
+
if @row_addresses.size < row_count
|
92
|
+
@row_addresses.concat Array.new(row_count - @row_addresses.size)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
def recalculate_dimensions
|
96
|
+
ensure_rows_read
|
97
|
+
shorten @rows
|
98
|
+
@dimensions = []
|
99
|
+
@dimensions[0] = [ index_of_first(@rows),
|
100
|
+
index_of_first(@row_addresses) ].compact.min || 0
|
101
|
+
@dimensions[1] = [ @rows.size, @row_addresses.size ].compact.max || 0
|
102
|
+
compact = @rows.compact
|
103
|
+
first_rows = compact.collect do |row| row.first_used end.compact.min
|
104
|
+
first_addrs = @row_addresses.compact.collect do |addr|
|
105
|
+
addr[:first_used] end.min
|
106
|
+
@dimensions[2] = [ first_rows, first_addrs ].compact.min || 0
|
107
|
+
last_rows = compact.collect do |row| row.first_unused end.max
|
108
|
+
last_addrs = @row_addresses.compact.collect do |addr|
|
109
|
+
addr[:first_unused] end.max
|
110
|
+
@dimensions[3] = [last_rows, last_addrs].compact.max || 0
|
111
|
+
@dimensions
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'spreadsheet/excel/writer/workbook'
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'spreadsheet/encodings'
|
2
|
+
|
3
|
+
module Spreadsheet
|
4
|
+
module Excel
|
5
|
+
module Writer
|
6
|
+
##
|
7
|
+
# This Module collects writer methods such as unicode_string that are specific
|
8
|
+
# to Biff8. This Module is likely to be expanded as Support for older Versions
|
9
|
+
# of Excel grows and methods get moved here for disambiguation.
|
10
|
+
module Biff8
|
11
|
+
include Spreadsheet::Encodings
|
12
|
+
##
|
13
|
+
# Check whether the string _data_ can be compressed (i.e. every second byte
|
14
|
+
# is a Null-byte) and perform compression.
|
15
|
+
# Returns the data and compression_status (0/1)
|
16
|
+
def compress_unicode_string data
|
17
|
+
compressed = internal('')
|
18
|
+
expect_null = false
|
19
|
+
data.each_byte do |byte|
|
20
|
+
if expect_null
|
21
|
+
if byte != 0
|
22
|
+
return [data, 1] # 1 => Data consists of wide Chars
|
23
|
+
end
|
24
|
+
expect_null = false
|
25
|
+
else
|
26
|
+
compressed << byte
|
27
|
+
expect_null = true
|
28
|
+
end
|
29
|
+
end
|
30
|
+
[compressed, 0] # 0 => Data consists of compressed Chars
|
31
|
+
end
|
32
|
+
##
|
33
|
+
# Encode _string_ into a Biff8 Unicode String. Header and body are encoded
|
34
|
+
# separately by #_unicode_string. This method simply combines the two.
|
35
|
+
def unicode_string string, count_length=1
|
36
|
+
header, data, _ = _unicode_string string, count_length
|
37
|
+
header << data
|
38
|
+
end
|
39
|
+
@@bytesize = RUBY_VERSION >= '1.9' ? :bytesize : :size
|
40
|
+
##
|
41
|
+
# Encode _string_ into a Biff8 Unicode String Header and Body.
|
42
|
+
def _unicode_string string, count_length=1
|
43
|
+
data = internal string
|
44
|
+
size = data.send(@@bytesize) / 2
|
45
|
+
fmt = count_length == 1 ? 'C2' : 'vC'
|
46
|
+
data, wide = compress_unicode_string data
|
47
|
+
opts = wide
|
48
|
+
header = [
|
49
|
+
size, # Length of the string (character count, ln)
|
50
|
+
opts, # Option flags:
|
51
|
+
# Bit Mask Contents
|
52
|
+
# 0 0x01 Character compression (ccompr):
|
53
|
+
# 0 = Compressed (8-bit characters)
|
54
|
+
# 1 = Uncompressed (16-bit characters)
|
55
|
+
# 2 0x04 Asian phonetic settings (phonetic):
|
56
|
+
# 0 = Does not contain Asian phonetic settings
|
57
|
+
# 1 = Contains Asian phonetic settings
|
58
|
+
# 3 0x08 Rich-Text settings (richtext):
|
59
|
+
# 0 = Does not contain Rich-Text settings
|
60
|
+
# 1 = Contains Rich-Text settings
|
61
|
+
#0x00,# (optional, only if richtext=1) Number of Rich-Text
|
62
|
+
# formatting runs (rt)
|
63
|
+
#0x00,# (optional, only if phonetic=1) Size of Asian phonetic
|
64
|
+
# settings block (in bytes, sz)
|
65
|
+
].pack fmt
|
66
|
+
data << '' # (optional, only if richtext=1)
|
67
|
+
# List of rt formatting runs (➜ 3.2)
|
68
|
+
data << '' # (optional, only if phonetic=1)
|
69
|
+
# Asian Phonetic Settings Block (➜ 3.4.2)
|
70
|
+
[header, data, wide]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,264 @@
|
|
1
|
+
require 'delegate'
|
2
|
+
require 'spreadsheet/format'
|
3
|
+
require 'spreadsheet/excel/internals'
|
4
|
+
|
5
|
+
module Spreadsheet
|
6
|
+
module Excel
|
7
|
+
module Writer
|
8
|
+
##
|
9
|
+
# This class encapsulates everything that is needed to write an XF record.
|
10
|
+
class Format < DelegateClass Spreadsheet::Format
|
11
|
+
include Spreadsheet::Excel::Internals
|
12
|
+
def Format.boolean *args
|
13
|
+
args.each do |key|
|
14
|
+
define_method key do
|
15
|
+
@format.send("#{key}?") ? 1 : 0
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
def Format.color key, default
|
20
|
+
define_method key do
|
21
|
+
color_code(@format.send(key) || default)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
def Format.line_style key, default
|
25
|
+
define_method key do
|
26
|
+
style_code(@format.send(key) || default)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
boolean :hidden, :locked, :merge_range, :shrink, :text_justlast, :text_wrap,
|
30
|
+
:cross_down, :cross_up
|
31
|
+
line_style :left, :none
|
32
|
+
line_style :right, :none
|
33
|
+
line_style :top, :none
|
34
|
+
line_style :bottom, :none
|
35
|
+
color :left_color, :black
|
36
|
+
color :right_color, :black
|
37
|
+
color :top_color, :black
|
38
|
+
color :bottom_color, :black
|
39
|
+
color :diagonal_color, :black
|
40
|
+
color :pattern_fg_color, :pattern_bg
|
41
|
+
color :pattern_bg_color, :pattern_bg
|
42
|
+
attr_reader :format
|
43
|
+
def initialize writer, workbook, format=workbook.default_format, opts={}
|
44
|
+
@opts = { :type => :format }.merge opts
|
45
|
+
@format = format
|
46
|
+
@writer = writer
|
47
|
+
@workbook = workbook
|
48
|
+
super format
|
49
|
+
end
|
50
|
+
def color_code color
|
51
|
+
SEDOC_ROLOC[color]
|
52
|
+
end
|
53
|
+
def style_code style
|
54
|
+
SELYTS_ENIL_REDROB_FX[style]
|
55
|
+
end
|
56
|
+
def font_index
|
57
|
+
@writer.font_index @workbook, font.key
|
58
|
+
end
|
59
|
+
def horizontal_align
|
60
|
+
XF_H_ALIGN.fetch @format.horizontal_align, 0
|
61
|
+
end
|
62
|
+
def num_format
|
63
|
+
@writer.number_format_index @workbook, @format.number_format
|
64
|
+
end
|
65
|
+
def text_direction
|
66
|
+
XF_TEXT_DIRECTION.fetch @format.text_direction, 0
|
67
|
+
end
|
68
|
+
def vertical_align
|
69
|
+
XF_V_ALIGN.fetch @format.vertical_align, 2
|
70
|
+
end
|
71
|
+
def write_op writer, op, *args
|
72
|
+
data = args.join
|
73
|
+
writer.write [op,data.size].pack("v2")
|
74
|
+
writer.write data
|
75
|
+
end
|
76
|
+
def write_xf writer, type=@opts[:type]
|
77
|
+
xf_type = xf_type_prot type
|
78
|
+
data = [
|
79
|
+
font_index, # Index to FONT record (➜ 6.43)
|
80
|
+
num_format, # Index to FORMAT record (➜ 6.45)
|
81
|
+
xf_type, # Bit Mask Contents
|
82
|
+
# 2-0 0x0007 XF_TYPE_PROT – XF type, cell protection
|
83
|
+
# Bit Mask Contents
|
84
|
+
# 0 0x01 1 = Cell is locked
|
85
|
+
# 1 0x02 1 = Formula is hidden
|
86
|
+
# 2 0x04 0 = Cell XF; 1 = Style XF
|
87
|
+
# 15-4 0xfff0 Index to parent style XF
|
88
|
+
# (always 0xfff in style XFs)
|
89
|
+
xf_align, # Bit Mask Contents
|
90
|
+
# 2-0 0x07 XF_HOR_ALIGN – Horizontal alignment
|
91
|
+
# Value Horizontal alignment
|
92
|
+
# 0x00 General
|
93
|
+
# 0x01 Left
|
94
|
+
# 0x02 Centred
|
95
|
+
# 0x03 Right
|
96
|
+
# 0x04 Filled
|
97
|
+
# 0x05 Justified (BIFF4-BIFF8X)
|
98
|
+
# 0x06 Centred across selection
|
99
|
+
# (BIFF4-BIFF8X)
|
100
|
+
# 0x07 Distributed (BIFF8X)
|
101
|
+
# 3 0x08 1 = Text is wrapped at right border
|
102
|
+
# 6-4 0x70 XF_VERT_ALIGN – Vertical alignment
|
103
|
+
# Value Vertical alignment
|
104
|
+
# 0x00 Top
|
105
|
+
# 0x01 Centred
|
106
|
+
# 0x02 Bottom
|
107
|
+
# 0x03 Justified (BIFF5-BIFF8X)
|
108
|
+
# 0x04 Distributed (BIFF8X)
|
109
|
+
xf_rotation, # XF_ROTATION: Text rotation angle
|
110
|
+
# Value Text rotation
|
111
|
+
# 0 Not rotated
|
112
|
+
# 1-90 1 to 90 degrees counterclockwise
|
113
|
+
# 91-180 1 to 90 degrees clockwise
|
114
|
+
# 255 Letters are stacked top-to-bottom,
|
115
|
+
# but not rotated
|
116
|
+
xf_indent, # Bit Mask Contents
|
117
|
+
# 3-0 0x0f Indent level
|
118
|
+
# 4 0x10 1 = Shrink content to fit into cell
|
119
|
+
# 5 0x40 1 = Merge Range (djberger)
|
120
|
+
# 7-6 0xc0 Text direction (BIFF8X only)
|
121
|
+
# 0 = According to context
|
122
|
+
# 1 = Left-to-right
|
123
|
+
# 2 = Right-to-left
|
124
|
+
xf_used_attr, # Bit Mask Contents
|
125
|
+
# 7-2 0xfc XF_USED_ATTRIB – Used attributes
|
126
|
+
# Each bit describes the validity of a
|
127
|
+
# specific group of attributes. In cell XFs
|
128
|
+
# a cleared bit means the attributes of the
|
129
|
+
# parent style XF are used (but only if the
|
130
|
+
# attributes are valid there), a set bit
|
131
|
+
# means the attributes of this XF are used.
|
132
|
+
# In style XFs a cleared bit means the
|
133
|
+
# attribute setting is valid, a set bit
|
134
|
+
# means the attribute should be ignored.
|
135
|
+
# Bit Mask Contents
|
136
|
+
# 0 0x01 Flag for number format
|
137
|
+
# 1 0x02 Flag for font
|
138
|
+
# 2 0x04 Flag for horizontal and
|
139
|
+
# vertical alignment, text wrap,
|
140
|
+
# indentation, orientation,
|
141
|
+
# rotation, and text direction
|
142
|
+
# 3 0x08 Flag for border lines
|
143
|
+
# 4 0x10 Flag for background area style
|
144
|
+
# 5 0x20 Flag for cell protection (cell
|
145
|
+
# locked and formula hidden)
|
146
|
+
xf_borders, # Cell border lines and background area:
|
147
|
+
# Bit Mask Contents
|
148
|
+
# 3- 0 0x0000000f Left line style (➜ 3.10)
|
149
|
+
# 7- 4 0x000000f0 Right line style (➜ 3.10)
|
150
|
+
# 11- 8 0x00000f00 Top line style (➜ 3.10)
|
151
|
+
# 15-12 0x0000f000 Bottom line style (➜ 3.10)
|
152
|
+
# 22-16 0x007f0000 Colour index (➜ 6.70)
|
153
|
+
# for left line colour
|
154
|
+
# 29-23 0x3f800000 Colour index (➜ 6.70)
|
155
|
+
# for right line colour
|
156
|
+
# 30 0x40000000 1 = Diagonal line
|
157
|
+
# from top left to right bottom
|
158
|
+
# 31 0x80000000 1 = Diagonal line
|
159
|
+
# from bottom left to right top
|
160
|
+
xf_brdcolors, # Bit Mask Contents
|
161
|
+
# 6- 0 0x0000007f Colour index (➜ 6.70)
|
162
|
+
# for top line colour
|
163
|
+
# 13- 7 0x00003f80 Colour index (➜ 6.70)
|
164
|
+
# for bottom line colour
|
165
|
+
# 20-14 0x001fc000 Colour index (➜ 6.70)
|
166
|
+
# for diagonal line colour
|
167
|
+
# 24-21 0x01e00000 Diagonal line style (➜ 3.10)
|
168
|
+
# 31-26 0xfc000000 Fill pattern (➜ 3.11)
|
169
|
+
xf_pattern # Bit Mask Contents
|
170
|
+
# 6-0 0x007f Colour index (➜ 6.70)
|
171
|
+
# for pattern colour
|
172
|
+
# 13-7 0x3f80 Colour index (➜ 6.70)
|
173
|
+
# for pattern background
|
174
|
+
]
|
175
|
+
write_op writer, 0x00e0, data.pack(binfmt(:xf))
|
176
|
+
end
|
177
|
+
def xf_align
|
178
|
+
align = horizontal_align
|
179
|
+
align |= text_wrap << 3
|
180
|
+
align |= vertical_align << 4
|
181
|
+
align |= text_justlast << 7
|
182
|
+
align
|
183
|
+
end
|
184
|
+
def xf_borders
|
185
|
+
border = left
|
186
|
+
border |= right << 4
|
187
|
+
border |= top << 8
|
188
|
+
border |= bottom << 12
|
189
|
+
border |= left_color << 16
|
190
|
+
border |= right_color << 23
|
191
|
+
border |= cross_down << 30
|
192
|
+
border |= cross_up << 31
|
193
|
+
border
|
194
|
+
end
|
195
|
+
def xf_brdcolors
|
196
|
+
border = top_color
|
197
|
+
border |= bottom_color << 7
|
198
|
+
border |= diagonal_color << 14
|
199
|
+
border |= pattern << 26
|
200
|
+
border
|
201
|
+
end
|
202
|
+
def xf_indent
|
203
|
+
indent = indent_level & 0x0f
|
204
|
+
indent |= shrink << 4
|
205
|
+
indent |= merge_range << 5
|
206
|
+
indent |= text_direction << 6
|
207
|
+
indent
|
208
|
+
end
|
209
|
+
def xf_pattern
|
210
|
+
ptrn = pattern_fg_color
|
211
|
+
ptrn |= pattern_bg_color << 7
|
212
|
+
ptrn
|
213
|
+
end
|
214
|
+
def xf_rotation
|
215
|
+
rot = @format.rotation
|
216
|
+
if @format.rotation_stacked?
|
217
|
+
rot = 255
|
218
|
+
elsif rot >= -90 or rotation <= 90
|
219
|
+
rot = -rot + 90 if rot < 0
|
220
|
+
else
|
221
|
+
warn "rotation outside -90..90; rotation set to 0"
|
222
|
+
rot = 0
|
223
|
+
end
|
224
|
+
rot
|
225
|
+
end
|
226
|
+
def xf_type_prot type
|
227
|
+
type = type.to_s.downcase == 'style' ? 0xfff4 : 0x0000
|
228
|
+
type |= locked
|
229
|
+
type |= hidden << 1
|
230
|
+
type
|
231
|
+
end
|
232
|
+
def xf_used_attr
|
233
|
+
atr_num = num_format & 1
|
234
|
+
atr_fnt = font_index & 1
|
235
|
+
atr_fnt = 1 unless @format.font.color == :text
|
236
|
+
atr_alc = 0
|
237
|
+
if horizontal_align != 0 \
|
238
|
+
|| vertical_align != 2 \
|
239
|
+
|| indent_level > 0 \
|
240
|
+
|| shrink? || merge_range? || text_wrap?
|
241
|
+
then
|
242
|
+
atr_alc = 1
|
243
|
+
end
|
244
|
+
atr_bdr = 1
|
245
|
+
atr_pat = 0
|
246
|
+
if @format.pattern_fg_color != :border \
|
247
|
+
|| @format.pattern_bg_color != :pattern_bg \
|
248
|
+
|| pattern != 0x00
|
249
|
+
then
|
250
|
+
atr_pat = 1
|
251
|
+
end
|
252
|
+
atr_prot = hidden? || locked? ? 1 : 0
|
253
|
+
attrs = atr_num
|
254
|
+
attrs |= atr_fnt << 1
|
255
|
+
attrs |= atr_alc << 2
|
256
|
+
attrs |= atr_bdr << 3
|
257
|
+
attrs |= atr_pat << 4
|
258
|
+
attrs |= atr_prot << 5
|
259
|
+
attrs << 2
|
260
|
+
end
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|