spreadsheet 1.3.3 → 1.3.5

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