spreadsheet 1.3.3 → 1.3.4

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.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/lib/parseexcel/parseexcel.rb +66 -58
  3. data/lib/parseexcel/parser.rb +1 -1
  4. data/lib/parseexcel.rb +1 -1
  5. data/lib/spreadsheet/column.rb +11 -9
  6. data/lib/spreadsheet/compatibility.rb +3 -1
  7. data/lib/spreadsheet/datatypes.rb +149 -147
  8. data/lib/spreadsheet/encodings.rb +20 -16
  9. data/lib/spreadsheet/errors.rb +2 -2
  10. data/lib/spreadsheet/excel/error.rb +23 -22
  11. data/lib/spreadsheet/excel/internals/biff5.rb +11 -11
  12. data/lib/spreadsheet/excel/internals/biff8.rb +13 -13
  13. data/lib/spreadsheet/excel/internals.rb +451 -451
  14. data/lib/spreadsheet/excel/offset.rb +32 -31
  15. data/lib/spreadsheet/excel/password_hash.rb +18 -18
  16. data/lib/spreadsheet/excel/reader/biff5.rb +34 -35
  17. data/lib/spreadsheet/excel/reader/biff8.rb +234 -222
  18. data/lib/spreadsheet/excel/reader.rb +1320 -1274
  19. data/lib/spreadsheet/excel/rgb.rb +91 -91
  20. data/lib/spreadsheet/excel/row.rb +99 -91
  21. data/lib/spreadsheet/excel/sst_entry.rb +40 -38
  22. data/lib/spreadsheet/excel/workbook.rb +86 -76
  23. data/lib/spreadsheet/excel/worksheet.rb +125 -107
  24. data/lib/spreadsheet/excel/writer/biff8.rb +56 -55
  25. data/lib/spreadsheet/excel/writer/format.rb +273 -256
  26. data/lib/spreadsheet/excel/writer/n_worksheet.rb +837 -798
  27. data/lib/spreadsheet/excel/writer/workbook.rb +671 -635
  28. data/lib/spreadsheet/excel/writer/worksheet.rb +898 -861
  29. data/lib/spreadsheet/excel/writer.rb +1 -1
  30. data/lib/spreadsheet/excel.rb +18 -11
  31. data/lib/spreadsheet/font.rb +30 -26
  32. data/lib/spreadsheet/format.rb +74 -59
  33. data/lib/spreadsheet/link.rb +7 -5
  34. data/lib/spreadsheet/note.rb +6 -6
  35. data/lib/spreadsheet/noteObject.rb +5 -5
  36. data/lib/spreadsheet/row.rb +33 -23
  37. data/lib/spreadsheet/version.rb +1 -1
  38. data/lib/spreadsheet/workbook.rb +27 -13
  39. data/lib/spreadsheet/worksheet.rb +102 -68
  40. data/lib/spreadsheet/writer.rb +3 -0
  41. data/lib/spreadsheet.rb +12 -15
  42. data/test/excel/reader.rb +8 -8
  43. data/test/excel/row.rb +35 -31
  44. data/test/excel/writer/workbook.rb +18 -16
  45. data/test/excel/writer/worksheet.rb +10 -8
  46. data/test/font.rb +44 -32
  47. data/test/format.rb +38 -33
  48. data/test/integration.rb +627 -598
  49. data/test/row.rb +5 -3
  50. data/test/suite.rb +7 -7
  51. data/test/workbook.rb +15 -14
  52. data/test/workbook_protection.rb +5 -5
  53. data/test/worksheet.rb +36 -34
  54. metadata +48 -6
@@ -1,264 +1,281 @@
1
- require 'delegate'
2
- require 'spreadsheet/format'
3
- require 'spreadsheet/excel/internals'
1
+ require "delegate"
2
+ require "spreadsheet/format"
3
+ require "spreadsheet/excel/internals"
4
4
 
5
5
  module Spreadsheet
6
6
  module Excel
7
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,
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 self.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
+
20
+ def self.color key, default
21
+ define_method key do
22
+ color_code(@format.send(key) || default)
23
+ end
24
+ end
25
+
26
+ def self.line_style key, default
27
+ define_method key do
28
+ style_code(@format.send(key) || default)
29
+ end
30
+ end
31
+ boolean :hidden, :locked, :merge_range, :shrink, :text_justlast, :text_wrap,
30
32
  :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
33
+ line_style :left, :none
34
+ line_style :right, :none
35
+ line_style :top, :none
36
+ line_style :bottom, :none
37
+ color :left_color, :black
38
+ color :right_color, :black
39
+ color :top_color, :black
40
+ color :bottom_color, :black
41
+ color :diagonal_color, :black
42
+ color :pattern_fg_color, :pattern_bg
43
+ color :pattern_bg_color, :pattern_bg
44
+ attr_reader :format
45
+ def initialize writer, workbook, format = workbook.default_format, opts = {}
46
+ @opts = {type: :format}.merge opts
47
+ @format = format
48
+ @writer = writer
49
+ @workbook = workbook
50
+ super(format)
51
+ end
52
+
53
+ def color_code color
54
+ SEDOC_ROLOC[color]
55
+ end
56
+
57
+ def style_code style
58
+ SELYTS_ENIL_REDROB_FX[style]
59
+ end
60
+
61
+ def font_index
62
+ @writer.font_index @workbook, font.key
63
+ end
64
+
65
+ def horizontal_align
66
+ XF_H_ALIGN.fetch @format.horizontal_align, 0
67
+ end
68
+
69
+ def num_format
70
+ @writer.number_format_index @workbook, @format.number_format
71
+ end
72
+
73
+ def text_direction
74
+ XF_TEXT_DIRECTION.fetch @format.text_direction, 0
75
+ end
76
+
77
+ def vertical_align
78
+ XF_V_ALIGN.fetch @format.vertical_align, 2
79
+ end
80
+
81
+ def write_op writer, op, *args
82
+ data = args.join
83
+ writer.write [op, data.size].pack("v2")
84
+ writer.write data
85
+ end
86
+
87
+ def write_xf writer, type = @opts[:type]
88
+ xf_type = xf_type_prot type
89
+ data = [
90
+ font_index, # Index to FONT record (➜ 6.43)
91
+ num_format, # Index to FORMAT record (➜ 6.45)
92
+ xf_type, # Bit Mask Contents
93
+ # 2-0 0x0007 XF_TYPE_PROT – XF type, cell protection
94
+ # Bit Mask Contents
95
+ # 0 0x01 1 = Cell is locked
96
+ # 1 0x02 1 = Formula is hidden
97
+ # 2 0x04 0 = Cell XF; 1 = Style XF
98
+ # 15-4 0xfff0 Index to parent style XF
99
+ # (always 0xfff in style XFs)
100
+ xf_align, # Bit Mask Contents
101
+ # 2-0 0x07 XF_HOR_ALIGN – Horizontal alignment
102
+ # Value Horizontal alignment
103
+ # 0x00 General
104
+ # 0x01 Left
105
+ # 0x02 Centred
106
+ # 0x03 Right
107
+ # 0x04 Filled
108
+ # 0x05 Justified (BIFF4-BIFF8X)
109
+ # 0x06 Centred across selection
110
+ # (BIFF4-BIFF8X)
111
+ # 0x07 Distributed (BIFF8X)
112
+ # 3 0x08 1 = Text is wrapped at right border
113
+ # 6-4 0x70 XF_VERT_ALIGN – Vertical alignment
114
+ # Value Vertical alignment
115
+ # 0x00 Top
116
+ # 0x01 Centred
117
+ # 0x02 Bottom
118
+ # 0x03 Justified (BIFF5-BIFF8X)
119
+ # 0x04 Distributed (BIFF8X)
120
+ xf_rotation, # XF_ROTATION: Text rotation angle
121
+ # Value Text rotation
122
+ # 0 Not rotated
123
+ # 1-90 1 to 90 degrees counterclockwise
124
+ # 91-180 1 to 90 degrees clockwise
125
+ # 255 Letters are stacked top-to-bottom,
126
+ # but not rotated
127
+ xf_indent, # Bit Mask Contents
128
+ # 3-0 0x0f Indent level
129
+ # 4 0x10 1 = Shrink content to fit into cell
130
+ # 5 0x40 1 = Merge Range (djberger)
131
+ # 7-6 0xc0 Text direction (BIFF8X only)
132
+ # 0 = According to context
133
+ # 1 = Left-to-right
134
+ # 2 = Right-to-left
135
+ xf_used_attr, # Bit Mask Contents
136
+ # 7-2 0xfc XF_USED_ATTRIB Used attributes
137
+ # Each bit describes the validity of a
138
+ # specific group of attributes. In cell XFs
139
+ # a cleared bit means the attributes of the
140
+ # parent style XF are used (but only if the
141
+ # attributes are valid there), a set bit
142
+ # means the attributes of this XF are used.
143
+ # In style XFs a cleared bit means the
144
+ # attribute setting is valid, a set bit
145
+ # means the attribute should be ignored.
146
+ # Bit Mask Contents
147
+ # 0 0x01 Flag for number format
148
+ # 1 0x02 Flag for font
149
+ # 2 0x04 Flag for horizontal and
150
+ # vertical alignment, text wrap,
151
+ # indentation, orientation,
152
+ # rotation, and text direction
153
+ # 3 0x08 Flag for border lines
154
+ # 4 0x10 Flag for background area style
155
+ # 5 0x20 Flag for cell protection (cell
156
+ # locked and formula hidden)
157
+ xf_borders, # Cell border lines and background area:
158
+ # Bit Mask Contents
159
+ # 3- 0 0x0000000f Left line style (➜ 3.10)
160
+ # 7- 4 0x000000f0 Right line style (➜ 3.10)
161
+ # 11- 8 0x00000f00 Top line style (➜ 3.10)
162
+ # 15-12 0x0000f000 Bottom line style (➜ 3.10)
163
+ # 22-16 0x007f0000 Colour index (➜ 6.70)
164
+ # for left line colour
165
+ # 29-23 0x3f800000 Colour index (➜ 6.70)
166
+ # for right line colour
167
+ # 30 0x40000000 1 = Diagonal line
168
+ # from top left to right bottom
169
+ # 31 0x80000000 1 = Diagonal line
170
+ # from bottom left to right top
171
+ xf_brdcolors, # Bit Mask Contents
172
+ # 6- 0 0x0000007f Colour index (➜ 6.70)
173
+ # for top line colour
174
+ # 13- 7 0x00003f80 Colour index (➜ 6.70)
175
+ # for bottom line colour
176
+ # 20-14 0x001fc000 Colour index (➜ 6.70)
177
+ # for diagonal line colour
178
+ # 24-21 0x01e00000 Diagonal line style (➜ 3.10)
179
+ # 31-26 0xfc000000 Fill pattern (➜ 3.11)
180
+ xf_pattern # Bit Mask Contents
181
+ # 6-0 0x007f Colour index (➜ 6.70)
182
+ # for pattern colour
183
+ # 13-7 0x3f80 Colour index (➜ 6.70)
184
+ # for pattern background
185
+ ]
186
+ write_op writer, 0x00e0, data.pack(binfmt(:xf))
187
+ end
188
+
189
+ def xf_align
190
+ align = horizontal_align
191
+ align |= text_wrap << 3
192
+ align |= vertical_align << 4
193
+ align |= text_justlast << 7
194
+ align
195
+ end
196
+
197
+ def xf_borders
198
+ border = left
199
+ border |= right << 4
200
+ border |= top << 8
201
+ border |= bottom << 12
202
+ border |= left_color << 16
203
+ border |= right_color << 23
204
+ border |= cross_down << 30
205
+ border |= cross_up << 31
206
+ border
207
+ end
208
+
209
+ def xf_brdcolors
210
+ border = top_color
211
+ border |= bottom_color << 7
212
+ border |= diagonal_color << 14
213
+ border |= pattern << 26
214
+ border
215
+ end
216
+
217
+ def xf_indent
218
+ indent = indent_level & 0x0f
219
+ indent |= shrink << 4
220
+ indent |= merge_range << 5
221
+ indent |= text_direction << 6
222
+ indent
223
+ end
224
+
225
+ def xf_pattern
226
+ ptrn = pattern_fg_color
227
+ ptrn |= pattern_bg_color << 7
228
+ ptrn
229
+ end
230
+
231
+ def xf_rotation
232
+ rot = @format.rotation
233
+ if @format.rotation_stacked?
234
+ rot = 255
235
+ elsif rot >= -90 || rotation <= 90
236
+ rot = -rot + 90 if rot < 0
237
+ else
238
+ warn "rotation outside -90..90; rotation set to 0"
239
+ rot = 0
240
+ end
241
+ rot
242
+ end
243
+
244
+ def xf_type_prot type
245
+ type = (type.to_s.downcase == "style") ? 0xfff4 : 0x0000
246
+ type |= locked
247
+ type |= hidden << 1
248
+ type
249
+ end
250
+
251
+ def xf_used_attr
252
+ atr_num = num_format & 1
253
+ atr_fnt = font_index & 1
254
+ atr_fnt = 1 unless @format.font.color == :text
255
+ atr_alc = 0
256
+ if horizontal_align != 0 \
257
+ || vertical_align != 2 \
258
+ || indent_level > 0 \
259
+ || shrink? || merge_range? || text_wrap?
260
+ atr_alc = 1
261
+ end
262
+ atr_bdr = 1
263
+ atr_pat = 0
264
+ if @format.pattern_fg_color != :border \
265
+ || @format.pattern_bg_color != :pattern_bg \
266
+ || pattern != 0x00
267
+ atr_pat = 1
268
+ end
269
+ atr_prot = (hidden? || locked?) ? 1 : 0
270
+ attrs = atr_num
271
+ attrs |= atr_fnt << 1
272
+ attrs |= atr_alc << 2
273
+ attrs |= atr_bdr << 3
274
+ attrs |= atr_pat << 4
275
+ attrs |= atr_prot << 5
276
+ attrs << 2
277
+ end
278
+ end
262
279
  end
263
280
  end
264
281
  end