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.
- checksums.yaml +4 -4
- data/bin/irb +29 -0
- data/bin/racc +29 -0
- data/bin/rdbg +29 -0
- data/bin/rdoc +29 -0
- data/bin/ri +29 -0
- data/bin/rubocop +29 -0
- data/bin/ruby-parse +29 -0
- data/bin/ruby-rewrite +29 -0
- data/bin/standardrb +29 -0
- data/bin/test-unit +29 -0
- data/lib/parseexcel/parseexcel.rb +66 -58
- data/lib/parseexcel/parser.rb +1 -1
- data/lib/parseexcel.rb +1 -1
- data/lib/spreadsheet/column.rb +13 -10
- data/lib/spreadsheet/compatibility.rb +3 -1
- data/lib/spreadsheet/datatypes.rb +150 -147
- data/lib/spreadsheet/encodings.rb +20 -16
- data/lib/spreadsheet/errors.rb +2 -2
- data/lib/spreadsheet/excel/error.rb +23 -22
- data/lib/spreadsheet/excel/internals/biff5.rb +11 -11
- data/lib/spreadsheet/excel/internals/biff8.rb +13 -13
- data/lib/spreadsheet/excel/internals.rb +451 -451
- data/lib/spreadsheet/excel/offset.rb +34 -31
- data/lib/spreadsheet/excel/password_hash.rb +18 -18
- data/lib/spreadsheet/excel/reader/biff5.rb +34 -35
- data/lib/spreadsheet/excel/reader/biff8.rb +235 -222
- data/lib/spreadsheet/excel/reader.rb +1331 -1274
- data/lib/spreadsheet/excel/rgb.rb +91 -91
- data/lib/spreadsheet/excel/row.rb +99 -91
- data/lib/spreadsheet/excel/sst_entry.rb +41 -38
- data/lib/spreadsheet/excel/workbook.rb +87 -76
- data/lib/spreadsheet/excel/worksheet.rb +126 -107
- data/lib/spreadsheet/excel/writer/biff8.rb +57 -55
- data/lib/spreadsheet/excel/writer/format.rb +274 -256
- data/lib/spreadsheet/excel/writer/n_worksheet.rb +838 -798
- data/lib/spreadsheet/excel/writer/workbook.rb +672 -635
- data/lib/spreadsheet/excel/writer/worksheet.rb +899 -861
- data/lib/spreadsheet/excel/writer.rb +1 -1
- data/lib/spreadsheet/excel.rb +19 -12
- data/lib/spreadsheet/font.rb +31 -26
- data/lib/spreadsheet/format.rb +75 -59
- data/lib/spreadsheet/link.rb +8 -5
- data/lib/spreadsheet/note.rb +7 -6
- data/lib/spreadsheet/noteObject.rb +6 -5
- data/lib/spreadsheet/row.rb +35 -24
- data/lib/spreadsheet/version.rb +1 -1
- data/lib/spreadsheet/workbook.rb +28 -13
- data/lib/spreadsheet/worksheet.rb +103 -68
- data/lib/spreadsheet/writer.rb +3 -0
- data/lib/spreadsheet.rb +12 -15
- data/test/data/test_row_record_empty_range.xls +0 -0
- data/test/excel/reader.rb +8 -8
- data/test/excel/row.rb +35 -31
- data/test/excel/writer/workbook.rb +18 -16
- data/test/excel/writer/worksheet.rb +10 -8
- data/test/font.rb +44 -32
- data/test/format.rb +38 -33
- data/test/integration.rb +641 -598
- data/test/row.rb +5 -3
- data/test/suite.rb +7 -7
- data/test/workbook.rb +15 -14
- data/test/workbook_protection.rb +5 -5
- data/test/worksheet.rb +36 -34
- metadata +59 -6
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
require
|
|
1
|
+
require "date"
|
|
2
|
+
require "spreadsheet/column"
|
|
3
|
+
require "spreadsheet/encodings"
|
|
4
|
+
require "spreadsheet/row"
|
|
5
|
+
require "spreadsheet/excel/password_hash"
|
|
6
6
|
|
|
7
7
|
module Spreadsheet
|
|
8
8
|
##
|
|
@@ -28,28 +28,29 @@ module Spreadsheet
|
|
|
28
28
|
include Spreadsheet::Encodings
|
|
29
29
|
include Spreadsheet::Datatypes
|
|
30
30
|
include Enumerable
|
|
31
|
+
|
|
31
32
|
attr_accessor :name, :selected, :workbook, :password_hash
|
|
32
33
|
attr_reader :rows, :columns, :merged_cells, :margins, :pagesetup
|
|
33
34
|
attr_reader :froze_top, :froze_left
|
|
34
35
|
enum :visibility, :visible, :hidden, :strong_hidden
|
|
35
|
-
def initialize opts={}
|
|
36
|
+
def initialize opts = {}
|
|
36
37
|
@froze_top = 0
|
|
37
38
|
@froze_left = 0
|
|
38
39
|
@default_format = nil
|
|
39
40
|
@selected = opts[:selected]
|
|
40
|
-
@dimensions = [0,0,0,0]
|
|
41
|
+
@dimensions = [0, 0, 0, 0]
|
|
41
42
|
@pagesetup = {
|
|
42
|
-
:
|
|
43
|
-
:
|
|
44
|
-
:
|
|
43
|
+
orig_data: [9, 100, 1, 1, 1, 0, 300, 300, 0.5, 0.5, 1],
|
|
44
|
+
orientation: :portrait,
|
|
45
|
+
adjust_to: 100
|
|
45
46
|
}
|
|
46
47
|
@margins = {
|
|
47
|
-
:
|
|
48
|
-
:
|
|
49
|
-
:
|
|
50
|
-
:
|
|
48
|
+
top: 1,
|
|
49
|
+
left: 0.75,
|
|
50
|
+
right: 0.75,
|
|
51
|
+
bottom: 1
|
|
51
52
|
}
|
|
52
|
-
@name = sanitize_invalid_characters(opts[:name] ||
|
|
53
|
+
@name = sanitize_invalid_characters(opts[:name] || "Worksheet")
|
|
53
54
|
@workbook = opts[:workbook]
|
|
54
55
|
@rows = []
|
|
55
56
|
@columns = []
|
|
@@ -59,6 +60,7 @@ module Spreadsheet
|
|
|
59
60
|
@password_hash = 0
|
|
60
61
|
@visibility = opts[:visibility]
|
|
61
62
|
end
|
|
63
|
+
|
|
62
64
|
def has_frozen_panel?
|
|
63
65
|
@froze_top > 0 or @froze_left > 0
|
|
64
66
|
end
|
|
@@ -67,39 +69,47 @@ module Spreadsheet
|
|
|
67
69
|
@froze_top = top.to_i
|
|
68
70
|
@froze_left = left.to_i
|
|
69
71
|
end
|
|
72
|
+
|
|
70
73
|
def active # :nodoc:
|
|
71
74
|
warn "Worksheet#active is deprecated. Please use Worksheet#selected instead."
|
|
72
75
|
selected
|
|
73
76
|
end
|
|
77
|
+
|
|
74
78
|
def active= selected # :nodoc:
|
|
75
79
|
warn "Worksheet#active= is deprecated. Please use Worksheet#selected= instead."
|
|
76
80
|
self.selected = selected
|
|
77
81
|
end
|
|
82
|
+
|
|
78
83
|
##
|
|
79
84
|
# Add a Format to the Workbook. If you use Row#set_format, you should not
|
|
80
85
|
# need to use this Method.
|
|
81
86
|
def add_format fmt
|
|
82
87
|
@workbook.add_format fmt if fmt
|
|
83
88
|
end
|
|
89
|
+
|
|
84
90
|
##
|
|
85
91
|
# Get the enriched value of the Cell at _row_, _column_.
|
|
86
92
|
# See also Worksheet#[], Row#[].
|
|
87
93
|
def cell row, column
|
|
88
94
|
row(row)[column]
|
|
89
95
|
end
|
|
96
|
+
|
|
90
97
|
##
|
|
91
98
|
# Returns the Column at _idx_.
|
|
92
99
|
def column idx
|
|
93
|
-
@columns[idx] || Column.new(idx, default_format, :
|
|
100
|
+
@columns[idx] || Column.new(idx, default_format, worksheet: self)
|
|
94
101
|
end
|
|
102
|
+
|
|
95
103
|
##
|
|
96
104
|
# The number of columns in this Worksheet which contain data.
|
|
97
105
|
def column_count
|
|
98
106
|
dimensions[3] - dimensions[2]
|
|
99
107
|
end
|
|
108
|
+
|
|
100
109
|
def column_updated idx, column
|
|
101
110
|
@columns[idx] = column
|
|
102
111
|
end
|
|
112
|
+
|
|
103
113
|
##
|
|
104
114
|
# Delete the Row at _idx_ (0-based) from this Worksheet.
|
|
105
115
|
def delete_row idx
|
|
@@ -107,33 +117,36 @@ module Spreadsheet
|
|
|
107
117
|
updated_from idx
|
|
108
118
|
res
|
|
109
119
|
end
|
|
120
|
+
|
|
110
121
|
##
|
|
111
122
|
# The default Format of this Worksheet, if you have set one.
|
|
112
123
|
# Returns the Workbook's default Format otherwise.
|
|
113
124
|
def default_format
|
|
114
125
|
@default_format || @workbook.default_format
|
|
115
126
|
end
|
|
127
|
+
|
|
116
128
|
##
|
|
117
129
|
# Set the default Format of this Worksheet.
|
|
118
130
|
def default_format= format
|
|
119
131
|
@default_format = format
|
|
120
132
|
add_format format
|
|
121
|
-
format
|
|
122
133
|
end
|
|
134
|
+
|
|
123
135
|
##
|
|
124
136
|
# Is the worksheet protected?
|
|
125
137
|
def protected?
|
|
126
138
|
@protected
|
|
127
139
|
end
|
|
140
|
+
|
|
128
141
|
##
|
|
129
142
|
# Set worklist protection
|
|
130
|
-
def protect! password =
|
|
143
|
+
def protect! password = ""
|
|
131
144
|
@protected = true
|
|
132
145
|
password = password.to_s
|
|
133
|
-
if password.size == 0
|
|
134
|
-
|
|
146
|
+
@password_hash = if password.size == 0
|
|
147
|
+
0
|
|
135
148
|
else
|
|
136
|
-
|
|
149
|
+
Excel::Password.password_hash password
|
|
137
150
|
end
|
|
138
151
|
end
|
|
139
152
|
|
|
@@ -146,6 +159,7 @@ module Spreadsheet
|
|
|
146
159
|
def dimensions
|
|
147
160
|
@dimensions || recalculate_dimensions
|
|
148
161
|
end
|
|
162
|
+
|
|
149
163
|
##
|
|
150
164
|
# If no argument is given, #each iterates over all used Rows (from the first
|
|
151
165
|
# used Row until but omitting the first unused Row, see also #dimensions).
|
|
@@ -153,7 +167,7 @@ module Spreadsheet
|
|
|
153
167
|
# If the argument skip is given, #each iterates from that row until but
|
|
154
168
|
# omitting the first unused Row, effectively skipping the first _skip_ Rows
|
|
155
169
|
# from the top of the Worksheet.
|
|
156
|
-
def each(skip=dimensions[0], &block)
|
|
170
|
+
def each(skip = dimensions[0], &block)
|
|
157
171
|
rows = skip.upto(dimensions[1] - 1).map { |index| row(index) }.to_enum
|
|
158
172
|
|
|
159
173
|
if block_given?
|
|
@@ -162,9 +176,11 @@ module Spreadsheet
|
|
|
162
176
|
rows
|
|
163
177
|
end
|
|
164
178
|
end
|
|
179
|
+
|
|
165
180
|
def encoding # :nodoc:
|
|
166
181
|
@workbook.encoding
|
|
167
182
|
end
|
|
183
|
+
|
|
168
184
|
##
|
|
169
185
|
# Sets the default Format of the column at _idx_.
|
|
170
186
|
#
|
|
@@ -175,39 +191,40 @@ module Spreadsheet
|
|
|
175
191
|
#
|
|
176
192
|
# Returns an instance of Column if _idx_ is an Integer, an Array of Columns
|
|
177
193
|
# otherwise.
|
|
178
|
-
def format_column idx, format=nil, opts={}
|
|
194
|
+
def format_column idx, format = nil, opts = {}
|
|
179
195
|
opts[:worksheet] = self
|
|
180
196
|
res = case idx
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
197
|
+
when Integer
|
|
198
|
+
column = nil
|
|
199
|
+
if format
|
|
200
|
+
column = Column.new(idx, format, opts)
|
|
201
|
+
end
|
|
202
|
+
@columns[idx] = column
|
|
203
|
+
else
|
|
204
|
+
idx.collect { |col| format_column col, format, opts }
|
|
205
|
+
end
|
|
190
206
|
shorten @columns
|
|
191
207
|
res
|
|
192
208
|
end
|
|
209
|
+
|
|
193
210
|
##
|
|
194
211
|
# Formats all Date, DateTime and Time cells with _format_ or the default
|
|
195
212
|
# formats:
|
|
196
213
|
# - 'DD.MM.YYYY' for Date
|
|
197
214
|
# - 'DD.MM.YYYY hh:mm:ss' for DateTime and Time
|
|
198
|
-
def format_dates! format=nil
|
|
215
|
+
def format_dates! format = nil
|
|
199
216
|
new_formats = {}
|
|
200
|
-
fmt_str_time = client(
|
|
201
|
-
fmt_str_date = client(
|
|
217
|
+
fmt_str_time = client("DD.MM.YYYY hh:mm:ss", "UTF-8")
|
|
218
|
+
fmt_str_date = client("DD.MM.YYYY", "UTF-8")
|
|
202
219
|
each do |row|
|
|
203
220
|
row.each_with_index do |value, idx|
|
|
204
221
|
unless row.formats[idx] || row.format(idx).date_or_time?
|
|
205
222
|
numfmt = case value
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
223
|
+
when DateTime, Time
|
|
224
|
+
format || fmt_str_time
|
|
225
|
+
when Date
|
|
226
|
+
format || fmt_str_date
|
|
227
|
+
end
|
|
211
228
|
case numfmt
|
|
212
229
|
when Format
|
|
213
230
|
row.set_format idx, numfmt
|
|
@@ -225,52 +242,61 @@ module Spreadsheet
|
|
|
225
242
|
end
|
|
226
243
|
end
|
|
227
244
|
end
|
|
245
|
+
|
|
228
246
|
##
|
|
229
247
|
# Insert a Row at _idx_ (0-based) containing _cells_
|
|
230
|
-
def insert_row idx, cells=[]
|
|
248
|
+
def insert_row idx, cells = []
|
|
231
249
|
res = @rows.insert idx, Row.new(self, idx, cells)
|
|
232
250
|
updated_from idx
|
|
233
251
|
res
|
|
234
252
|
end
|
|
235
|
-
|
|
253
|
+
|
|
254
|
+
def << cells = []
|
|
236
255
|
insert_row @rows.size, cells
|
|
237
256
|
end
|
|
257
|
+
|
|
238
258
|
def inspect
|
|
239
259
|
names = instance_variables
|
|
240
|
-
names.delete
|
|
260
|
+
names.delete "@rows"
|
|
241
261
|
variables = names.collect do |name|
|
|
242
262
|
"%s=%s" % [name, instance_variable_get(name)]
|
|
243
|
-
end.join(
|
|
263
|
+
end.join(" ")
|
|
244
264
|
sprintf "#<%s:0x%014x %s @rows[%i]>", self.class, object_id,
|
|
245
|
-
|
|
265
|
+
variables, row_count
|
|
246
266
|
end
|
|
267
|
+
|
|
247
268
|
## The last Row containing any data
|
|
248
269
|
def last_row
|
|
249
270
|
row(last_row_index)
|
|
250
271
|
end
|
|
272
|
+
|
|
251
273
|
## The index of the last Row containing any data
|
|
252
274
|
def last_row_index
|
|
253
275
|
[dimensions[1] - 1, 0].max
|
|
254
276
|
end
|
|
277
|
+
|
|
255
278
|
##
|
|
256
279
|
# Replace the Row at _idx_ with the following arguments. Like #update_row,
|
|
257
280
|
# but truncates the Row if there are fewer arguments than Cells in the Row.
|
|
258
281
|
def replace_row idx, *cells
|
|
259
|
-
if(row = @rows[idx]) && cells.size < row.size
|
|
282
|
+
if (row = @rows[idx]) && cells.size < row.size
|
|
260
283
|
cells.concat Array.new(row.size - cells.size)
|
|
261
284
|
end
|
|
262
285
|
update_row idx, *cells
|
|
263
286
|
end
|
|
287
|
+
|
|
264
288
|
##
|
|
265
289
|
# The Row at _idx_ or a new Row.
|
|
266
290
|
def row idx
|
|
267
291
|
@rows[idx] || Row.new(self, idx)
|
|
268
292
|
end
|
|
293
|
+
|
|
269
294
|
##
|
|
270
295
|
# The number of Rows in this Worksheet which contain data.
|
|
271
296
|
def row_count
|
|
272
297
|
dimensions[1] - dimensions[0]
|
|
273
298
|
end
|
|
299
|
+
|
|
274
300
|
##
|
|
275
301
|
# Tell Worksheet that the Row at _idx_ has been updated and the #dimensions
|
|
276
302
|
# need to be recalculated. You should not need to call this directly.
|
|
@@ -278,18 +304,20 @@ module Spreadsheet
|
|
|
278
304
|
@dimensions = nil
|
|
279
305
|
@rows[idx] = row
|
|
280
306
|
end
|
|
307
|
+
|
|
281
308
|
##
|
|
282
309
|
# Updates the Row at _idx_ with the following arguments.
|
|
283
310
|
def update_row idx, *cells
|
|
284
|
-
res = if row = @rows[idx]
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
311
|
+
res = if (row = @rows[idx])
|
|
312
|
+
row[0, cells.size] = cells
|
|
313
|
+
row
|
|
314
|
+
else
|
|
315
|
+
Row.new self, idx, cells
|
|
316
|
+
end
|
|
290
317
|
row_updated idx, res
|
|
291
318
|
res
|
|
292
319
|
end
|
|
320
|
+
|
|
293
321
|
##
|
|
294
322
|
# Renumbers all Rows starting at _idx_ and calls #row_updated for each of
|
|
295
323
|
# them.
|
|
@@ -300,18 +328,21 @@ module Spreadsheet
|
|
|
300
328
|
row_updated idx, row
|
|
301
329
|
end
|
|
302
330
|
end
|
|
331
|
+
|
|
303
332
|
##
|
|
304
333
|
# Get the enriched value of the Cell at _row_, _column_.
|
|
305
334
|
# See also Worksheet#cell, Row#[].
|
|
306
335
|
def [] row, column
|
|
307
336
|
row(row)[column]
|
|
308
337
|
end
|
|
338
|
+
|
|
309
339
|
##
|
|
310
340
|
# Set the value of the Cell at _row_, _column_ to _value_.
|
|
311
341
|
# See also Row#[]=.
|
|
312
342
|
def []= row, column, value
|
|
313
343
|
row(row)[column] = value
|
|
314
344
|
end
|
|
345
|
+
|
|
315
346
|
##
|
|
316
347
|
# Merges multiple cells into one.
|
|
317
348
|
def merge_cells start_row, start_col, end_row, end_col
|
|
@@ -323,66 +354,70 @@ module Spreadsheet
|
|
|
323
354
|
recalculate_dimensions
|
|
324
355
|
|
|
325
356
|
# detect first non-nil non-empty row if given first row is empty or nil
|
|
326
|
-
if row(@dimensions[0]).empty? || row(@dimensions[0]).compact.join(
|
|
357
|
+
if row(@dimensions[0]).empty? || row(@dimensions[0]).compact.join("").empty?
|
|
327
358
|
(@dimensions[0]...@dimensions[1]).each do |i|
|
|
328
|
-
break unless row(i).empty? || row(i).compact.join(
|
|
359
|
+
break unless row(i).empty? || row(i).compact.join("").empty?
|
|
329
360
|
@dimensions[0] = i
|
|
330
361
|
end
|
|
331
362
|
end
|
|
332
363
|
|
|
333
364
|
# detect last non-nil non-empty row if given last row is empty or nil
|
|
334
|
-
if row(@dimensions[1] - 1).empty? || row(@dimensions[1] - 1).compact.join(
|
|
365
|
+
if row(@dimensions[1] - 1).empty? || row(@dimensions[1] - 1).compact.join("").empty?
|
|
335
366
|
row_size = @dimensions[1] - 1
|
|
336
367
|
@dimensions[1] = @dimensions[0]
|
|
337
368
|
# divide and conquer
|
|
338
|
-
while
|
|
339
|
-
if row(row_size).empty? || row(row_size).compact.join(
|
|
369
|
+
while row_size - @dimensions[1] > 1
|
|
370
|
+
if row(row_size).empty? || row(row_size).compact.join("").empty?
|
|
340
371
|
row_size = @dimensions[1] + (((row_size - @dimensions[1]) + 1) / 2).to_i
|
|
341
372
|
else
|
|
342
|
-
|
|
373
|
+
idx = ((row_size - @dimensions[1]) / 2).to_i + 1
|
|
343
374
|
@dimensions[1] = row_size
|
|
344
|
-
row_size
|
|
375
|
+
row_size += idx
|
|
345
376
|
end
|
|
346
377
|
end
|
|
347
378
|
@dimensions[1] = row_size + 1
|
|
348
379
|
end
|
|
349
380
|
|
|
350
381
|
# detect first non-empty non-nil column if first column is empty or nil
|
|
351
|
-
if (@dimensions[0]..@dimensions[1]).inject(true){|t, j| t && row(j)[@dimensions[2]].nil?}
|
|
382
|
+
if (@dimensions[0]..@dimensions[1]).inject(true) { |t, j| t && row(j)[@dimensions[2]].nil? }
|
|
352
383
|
(@dimensions[2]..@dimensions[3]).each do |i|
|
|
353
|
-
break unless (@dimensions[0]..@dimensions[1]).inject(true){|t, j| t && row(j)[i].to_s.empty?}
|
|
384
|
+
break unless (@dimensions[0]..@dimensions[1]).inject(true) { |t, j| t && row(j)[i].to_s.empty? }
|
|
354
385
|
@dimensions[2] = i
|
|
355
386
|
end
|
|
356
387
|
end
|
|
357
388
|
|
|
358
389
|
# detect last non-empty non-nil column if last column is empty or nil
|
|
359
|
-
if (@dimensions[0]..@dimensions[1]).inject(true){|t, j| t && row(j)[@dimensions[3]].nil?}
|
|
390
|
+
if (@dimensions[0]..@dimensions[1]).inject(true) { |t, j| t && row(j)[@dimensions[3]].nil? }
|
|
360
391
|
(@dimensions[2]..@dimensions[3]).reverse_each do |i|
|
|
361
|
-
break unless (@dimensions[0]..@dimensions[1]).inject(true){|t, j| t && row(j)[i].to_s.empty?}
|
|
392
|
+
break unless (@dimensions[0]..@dimensions[1]).inject(true) { |t, j| t && row(j)[i].to_s.empty? }
|
|
362
393
|
@dimensions[3] = i
|
|
363
394
|
end
|
|
364
|
-
@dimensions[3]
|
|
395
|
+
@dimensions[3]
|
|
365
396
|
end
|
|
366
397
|
end
|
|
367
398
|
|
|
368
399
|
private
|
|
400
|
+
|
|
369
401
|
def sanitize_invalid_characters(name) # :nodoc:
|
|
370
|
-
name.gsub(Regexp.new('[\\\/\*\?\:\[\]]'.encode(Spreadsheet.client_encoding)),
|
|
402
|
+
name.gsub(Regexp.new('[\\\/\*\?\:\[\]]'.encode(Spreadsheet.client_encoding)), "_")
|
|
371
403
|
end
|
|
404
|
+
|
|
372
405
|
def index_of_first ary # :nodoc:
|
|
373
406
|
return unless ary
|
|
374
|
-
ary.index(ary.find
|
|
407
|
+
ary.index(ary.find { |elm| elm })
|
|
375
408
|
end
|
|
409
|
+
|
|
376
410
|
def recalculate_dimensions # :nodoc:
|
|
377
411
|
shorten @rows
|
|
378
412
|
@dimensions = []
|
|
379
413
|
@dimensions[0] = index_of_first(@rows) || 0
|
|
380
414
|
@dimensions[1] = @rows.size
|
|
381
415
|
compact = @rows.compact
|
|
382
|
-
@dimensions[2] = compact.collect
|
|
383
|
-
@dimensions[3] = compact.collect
|
|
416
|
+
@dimensions[2] = compact.collect { |row| row.first_used }.compact.min || 0
|
|
417
|
+
@dimensions[3] = compact.collect { |row| row.first_unused }.max || 0
|
|
384
418
|
@dimensions
|
|
385
419
|
end
|
|
420
|
+
|
|
386
421
|
def shorten ary # :nodoc:
|
|
387
422
|
return unless ary
|
|
388
423
|
while !ary.empty? && !ary.last
|
data/lib/spreadsheet/writer.rb
CHANGED
|
@@ -6,6 +6,7 @@ module Spreadsheet
|
|
|
6
6
|
def initialize io_or_path
|
|
7
7
|
@io_or_path = io_or_path
|
|
8
8
|
end
|
|
9
|
+
|
|
9
10
|
def write workbook
|
|
10
11
|
if @io_or_path.respond_to? :seek
|
|
11
12
|
@io_or_path.binmode
|
|
@@ -16,7 +17,9 @@ module Spreadsheet
|
|
|
16
17
|
end
|
|
17
18
|
end
|
|
18
19
|
end
|
|
20
|
+
|
|
19
21
|
private
|
|
22
|
+
|
|
20
23
|
def write_workbook workbook, io
|
|
21
24
|
reader = workbook.io
|
|
22
25
|
unless io == reader
|
data/lib/spreadsheet.rb
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
### Spreadsheet - A Library for reading and writing Spreadsheet Documents.
|
|
3
2
|
#
|
|
4
3
|
# Copyright (C) 2008-2010 ywesee GmbH
|
|
@@ -25,12 +24,12 @@
|
|
|
25
24
|
# 8006 Zürich
|
|
26
25
|
### Switzerland
|
|
27
26
|
|
|
28
|
-
require
|
|
29
|
-
require
|
|
27
|
+
require "spreadsheet/version"
|
|
28
|
+
require "spreadsheet/errors"
|
|
30
29
|
|
|
31
|
-
require
|
|
32
|
-
require
|
|
33
|
-
require
|
|
30
|
+
require "spreadsheet/excel/workbook"
|
|
31
|
+
require "spreadsheet/excel/reader"
|
|
32
|
+
require "spreadsheet/excel/rgb"
|
|
34
33
|
|
|
35
34
|
# = Synopsis
|
|
36
35
|
# The Spreadsheet Library is designed to read and write Spreadsheet Documents.
|
|
@@ -44,38 +43,36 @@ require 'spreadsheet/excel/rgb'
|
|
|
44
43
|
# sheet = book.worksheet 0
|
|
45
44
|
# sheet.each do |row| puts row[0] end
|
|
46
45
|
module Spreadsheet
|
|
47
|
-
|
|
48
46
|
##
|
|
49
47
|
# Default client Encoding. Change this value if your application uses a
|
|
50
48
|
# different Encoding:
|
|
51
49
|
# Spreadsheet.client_encoding = 'ISO-LATIN-1//TRANSLIT//IGNORE'
|
|
52
|
-
@client_encoding =
|
|
53
|
-
@enc_translit =
|
|
54
|
-
@enc_ignore =
|
|
50
|
+
@client_encoding = "UTF-8"
|
|
51
|
+
@enc_translit = "TRANSLIT"
|
|
52
|
+
@enc_ignore = "IGNORE"
|
|
55
53
|
|
|
56
54
|
class << self
|
|
57
|
-
|
|
58
55
|
attr_accessor :client_encoding, :enc_translit, :enc_ignore
|
|
59
56
|
|
|
60
57
|
##
|
|
61
58
|
# Parses a Spreadsheet Document and returns a Workbook object. At present,
|
|
62
59
|
# only Excel-Documents can be read.
|
|
63
|
-
def open io_or_path, mode="rb+"
|
|
60
|
+
def open io_or_path, mode = "rb+"
|
|
64
61
|
if io_or_path.respond_to? :seek
|
|
65
62
|
Excel::Workbook.open(io_or_path)
|
|
66
63
|
elsif block_given?
|
|
67
64
|
File.open(io_or_path, mode) do |fh|
|
|
68
|
-
yield open(fh)
|
|
65
|
+
yield open(fh) # standard:disable Security/Open
|
|
69
66
|
end
|
|
70
67
|
else
|
|
71
|
-
open File.open(io_or_path, mode)
|
|
68
|
+
open File.open(io_or_path, mode) # standard:disable Security/Open
|
|
72
69
|
end
|
|
73
70
|
end
|
|
74
71
|
|
|
75
72
|
##
|
|
76
73
|
# Returns a Writer object for the specified path. At present, only the
|
|
77
74
|
# Excel-Writer is available.
|
|
78
|
-
def writer io_or_path, type=Excel
|
|
75
|
+
def writer io_or_path, type = Excel
|
|
79
76
|
Excel::Writer::Workbook.new io_or_path
|
|
80
77
|
end
|
|
81
78
|
end
|
|
Binary file
|
data/test/excel/reader.rb
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
# Excel::TestReader -- Spreadsheet -- 22.01.2013
|
|
3
3
|
|
|
4
|
-
$: << File.expand_path(
|
|
4
|
+
$: << File.expand_path("../../../lib", File.dirname(__FILE__))
|
|
5
5
|
|
|
6
|
-
require
|
|
6
|
+
require "test/unit"
|
|
7
7
|
|
|
8
8
|
module Spreadsheet
|
|
9
9
|
module Excel
|
|
@@ -18,8 +18,8 @@ module Spreadsheet
|
|
|
18
18
|
|
|
19
19
|
def test_not_empty_file_error_on_setup
|
|
20
20
|
reader = Spreadsheet::Excel::Reader.new
|
|
21
|
-
data = File.expand_path File.join(
|
|
22
|
-
path = File.join data,
|
|
21
|
+
data = File.expand_path File.join("test", "data")
|
|
22
|
+
path = File.join data, "test_empty.xls"
|
|
23
23
|
not_empty_io = File.open(path, "rb")
|
|
24
24
|
assert_nothing_thrown do
|
|
25
25
|
reader.setup not_empty_io
|
|
@@ -27,11 +27,11 @@ module Spreadsheet
|
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
def test_not_frozen_stream_error_on_setup
|
|
30
|
-
return if Gem::Version.new(RUBY_VERSION) < Gem::Version.new(
|
|
30
|
+
return if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.3.0")
|
|
31
31
|
|
|
32
32
|
reader = Spreadsheet::Excel::Reader.new
|
|
33
|
-
data = File.expand_path File.join(
|
|
34
|
-
path = File.join data,
|
|
33
|
+
data = File.expand_path File.join("test", "data")
|
|
34
|
+
path = File.join data, "test_empty.xls"
|
|
35
35
|
content_string = File.read path
|
|
36
36
|
frozen_io = StringIO.new(content_string.freeze)
|
|
37
37
|
assert_nothing_thrown do
|
|
@@ -40,4 +40,4 @@ module Spreadsheet
|
|
|
40
40
|
end
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
|
-
end
|
|
43
|
+
end
|
data/test/excel/row.rb
CHANGED
|
@@ -1,40 +1,44 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
# Excel::TestRow -- Spreadsheet -- 12.10.2008 -- hwyss@ywesee.com
|
|
3
3
|
|
|
4
|
-
$: << File.expand_path(
|
|
4
|
+
$: << File.expand_path("../../lib", File.dirname(__FILE__))
|
|
5
5
|
|
|
6
|
-
require
|
|
7
|
-
require
|
|
6
|
+
require "test/unit"
|
|
7
|
+
require "spreadsheet"
|
|
8
8
|
|
|
9
9
|
module Spreadsheet
|
|
10
10
|
module Excel
|
|
11
|
-
class TestRow < Test::Unit::TestCase
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
11
|
+
class TestRow < Test::Unit::TestCase
|
|
12
|
+
def setup
|
|
13
|
+
@workbook = Excel::Workbook.new
|
|
14
|
+
@worksheet = Excel::Worksheet.new
|
|
15
|
+
@workbook.add_worksheet @worksheet
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def test_date
|
|
19
|
+
row = Row.new @worksheet, 0, [nil, 27627.6789]
|
|
20
|
+
assert_equal Date.new(1975, 8, 21), row.date(1)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def test_to_a
|
|
24
|
+
row = Row.new @worksheet, 0, [nil, 1, 27627.6789]
|
|
25
|
+
row.set_format(2, Format.new(number_format: "DD.MM.YYYY"))
|
|
26
|
+
assert_equal [nil, 1, Date.new(1975, 8, 21)], row.to_a
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def test_datetime
|
|
30
|
+
row = Row.new @worksheet, 0, [nil, 27627.765]
|
|
31
|
+
d1 = DateTime.new(1975, 8, 21) + 0.765
|
|
32
|
+
d2 = row.datetime 1
|
|
33
|
+
assert_equal d1, d2
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def test_datetime_overflow
|
|
37
|
+
row = Row.new @worksheet, 0, [nil, 40010.6666666666]
|
|
38
|
+
d1 = DateTime.new(2009, 0o7, 16, 16)
|
|
39
|
+
d2 = row.datetime 1
|
|
40
|
+
assert_equal d1, d2
|
|
41
|
+
end
|
|
42
|
+
end
|
|
39
43
|
end
|
|
40
44
|
end
|