spreadsheet 1.2.9 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a831e5c252775858cbdba547a3ac3228028cb6c9a56a92a77ab8fdc393de0658
|
4
|
+
data.tar.gz: 1240cd6a3b8362fa9c807c26d36fd6f8df19872e195ce09e98583597f73fa8cc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 35dd4c09f32c793bf85f4290a497eb25a298b2f59e107eb4ecebf3c37e1e6a1ee505eaec3409057c0914754ca9036fb8a4c173c8d251e448ef932e38489d0c04
|
7
|
+
data.tar.gz: b20106050e1370ced689559af16e97efc4b19abde21165091d9f4a1ebea02758625713f09e20be0ccf7b8be2075fc59567c5bf581e583a2250ccc81ee04b2e5f
|
@@ -241,81 +241,6 @@ class Worksheet
|
|
241
241
|
end
|
242
242
|
write_multiples row, first_idx, multiples if multiples
|
243
243
|
end
|
244
|
-
def write_changes reader, endpos, sst_status
|
245
|
-
|
246
|
-
## FIXME this is not smart solution to update outline_level.
|
247
|
-
# without this process, outlines in row disappear in MS Excel.
|
248
|
-
@worksheet.row_count.times do |i|
|
249
|
-
if @worksheet.row(i).outline_level > 0
|
250
|
-
@worksheet.row(i).outline_level = @worksheet.row(i).outline_level
|
251
|
-
end
|
252
|
-
end
|
253
|
-
|
254
|
-
reader.seek @worksheet.offset
|
255
|
-
blocks = row_blocks
|
256
|
-
lastpos = reader.pos
|
257
|
-
offsets = {}
|
258
|
-
row_offsets = []
|
259
|
-
changes = @worksheet.changes
|
260
|
-
@worksheet.offsets.each do |key, pair|
|
261
|
-
if changes.include?(key) \
|
262
|
-
|| (sst_status == :complete_update && key.is_a?(Integer))
|
263
|
-
offsets.store pair, key
|
264
|
-
end
|
265
|
-
end
|
266
|
-
## FIXME it may be smarter to simply write all rowblocks, instead of doing a
|
267
|
-
# song-and-dance routine for every row...
|
268
|
-
work = offsets.invert
|
269
|
-
work.each do |key, (pos, len)|
|
270
|
-
case key
|
271
|
-
when Integer
|
272
|
-
row_offsets.push [key, [pos, len]]
|
273
|
-
when :dimensions
|
274
|
-
row_offsets.push [-1, [pos, len]]
|
275
|
-
end
|
276
|
-
end
|
277
|
-
row_offsets.sort!
|
278
|
-
row_offsets.reverse!
|
279
|
-
control = changes.size
|
280
|
-
@worksheet.each do |row|
|
281
|
-
key = row.idx
|
282
|
-
if changes.include?(key) && !work.include?(key)
|
283
|
-
row, pair = row_offsets.find do |idx, _| idx <= key end
|
284
|
-
work.store key, pair
|
285
|
-
end
|
286
|
-
end
|
287
|
-
if changes.size > control
|
288
|
-
warn <<-EOS
|
289
|
-
Your Worksheet was modified while it was being written. This should not happen.
|
290
|
-
Please contact the author (hannes dot wyss at gmail dot com) with a sample file
|
291
|
-
and minimal code that generates this warning. Thanks!
|
292
|
-
EOS
|
293
|
-
end
|
294
|
-
work = work.sort_by do |key, (pos, len)|
|
295
|
-
[pos, key.is_a?(Integer) ? key : -1]
|
296
|
-
end
|
297
|
-
work.each do |key, (pos, len)|
|
298
|
-
@io.write reader.read(pos - lastpos) if pos > lastpos
|
299
|
-
if key.is_a?(Integer)
|
300
|
-
if block = blocks.find do |rows| rows.any? do |row| row.idx == key end end
|
301
|
-
write_rowblock block
|
302
|
-
blocks.delete block
|
303
|
-
end
|
304
|
-
else
|
305
|
-
send "write_#{key}"
|
306
|
-
end
|
307
|
-
lastpos = pos + len
|
308
|
-
reader.seek lastpos
|
309
|
-
end
|
310
|
-
|
311
|
-
# Necessary for outline (grouping) and hiding functions
|
312
|
-
# but these below are not necessary to run
|
313
|
-
# if [Row|Column]#hidden? = false and [Row|Column]#outline_level == 0
|
314
|
-
write_colinfos
|
315
|
-
write_guts
|
316
|
-
|
317
|
-
@io.write reader.read(endpos - lastpos)
|
318
|
-
end
|
319
244
|
def write_colinfo bunch
|
320
245
|
col = bunch.first
|
321
246
|
width = col.width.to_f * 256
|
@@ -164,93 +164,6 @@ class Workbook < Spreadsheet::Writer
|
|
164
164
|
end
|
165
165
|
end
|
166
166
|
##
|
167
|
-
# Copy unchanged data verbatim, adjust offsets and write new records for
|
168
|
-
# changed data.
|
169
|
-
def write_changes workbook, io
|
170
|
-
sanitize_worksheets workbook.worksheets
|
171
|
-
collect_formats workbook, :existing_document => true
|
172
|
-
reader = workbook.ole
|
173
|
-
sheet_data = {}
|
174
|
-
sst_status, sst_total, sst_strings = complete_sst_update? workbook
|
175
|
-
sst = {}
|
176
|
-
sst_strings.each_with_index do |str, idx| sst.store str, idx end
|
177
|
-
sheets = worksheets(workbook)
|
178
|
-
positions = []
|
179
|
-
newsheets = []
|
180
|
-
sheets.each do |sheet|
|
181
|
-
@sst[sheet] = sst
|
182
|
-
pos, len = workbook.offsets[sheet.worksheet]
|
183
|
-
if pos
|
184
|
-
positions.push pos
|
185
|
-
sheet.write_changes reader, pos + len, sst_status
|
186
|
-
else
|
187
|
-
newsheets.push sheet
|
188
|
-
sheet.write_from_scratch
|
189
|
-
end
|
190
|
-
sheet_data[sheet.worksheet] = sheet.data
|
191
|
-
end
|
192
|
-
Ole::Storage.open io do |ole|
|
193
|
-
ole.file.open 'Workbook', 'w' do |writer|
|
194
|
-
reader.seek lastpos = 0
|
195
|
-
workbook.offsets.select do |key, pair|
|
196
|
-
workbook.changes.include? key
|
197
|
-
end.sort_by do |key, (pos, _)|
|
198
|
-
pos
|
199
|
-
end.each do |key, (pos, len)|
|
200
|
-
data = reader.read(pos - lastpos)
|
201
|
-
writer.write data
|
202
|
-
case key
|
203
|
-
when Spreadsheet::Worksheet
|
204
|
-
writer.write sheet_data[key]
|
205
|
-
when :boundsheets
|
206
|
-
## boundsheets are hard to calculate. The offset below is only
|
207
|
-
# correct if there are no more changes in the workbook globals
|
208
|
-
# string after this.
|
209
|
-
oldoffset = positions.min - len
|
210
|
-
lastpos = pos + len
|
211
|
-
bytechange = 0
|
212
|
-
buffer = StringIO.new ''.dup
|
213
|
-
if tuple = workbook.offsets[:sst]
|
214
|
-
write_sst_changes workbook, buffer, writer.pos,
|
215
|
-
sst_total, sst_strings
|
216
|
-
pos, len = tuple
|
217
|
-
if offset = workbook.offsets[:extsst]
|
218
|
-
len += offset[1].to_i
|
219
|
-
end
|
220
|
-
bytechange = buffer.size - len
|
221
|
-
write_boundsheets workbook, writer, oldoffset + bytechange
|
222
|
-
reader.seek lastpos
|
223
|
-
writer.write reader.read(pos - lastpos)
|
224
|
-
buffer.rewind
|
225
|
-
writer.write buffer.read
|
226
|
-
elsif sst.empty? || workbook.biff_version < 8
|
227
|
-
write_boundsheets workbook, writer, oldoffset + bytechange
|
228
|
-
else
|
229
|
-
write_sst workbook, buffer, writer.pos
|
230
|
-
write_boundsheets workbook, writer, oldoffset + buffer.size
|
231
|
-
pos = lastpos
|
232
|
-
len = positions.min - lastpos
|
233
|
-
if len > OPCODE_SIZE
|
234
|
-
reader.seek pos
|
235
|
-
writer.write reader.read(len - OPCODE_SIZE)
|
236
|
-
end
|
237
|
-
buffer.rewind
|
238
|
-
writer.write buffer.read
|
239
|
-
write_eof workbook, writer
|
240
|
-
end
|
241
|
-
else
|
242
|
-
send "write_#{key}", workbook, writer
|
243
|
-
end
|
244
|
-
lastpos = [pos + len, reader.size - 1].min
|
245
|
-
reader.seek lastpos
|
246
|
-
end
|
247
|
-
writer.write reader.read
|
248
|
-
newsheets.each do |sheet|
|
249
|
-
writer.write sheet.data
|
250
|
-
end
|
251
|
-
end
|
252
|
-
end
|
253
|
-
end
|
254
167
|
def write_datemode workbook, writer
|
255
168
|
mode = @date_base.year == 1899 ? 0x00 : 0x01
|
256
169
|
data = [
|
@@ -639,8 +552,7 @@ class Workbook < Spreadsheet::Writer
|
|
639
552
|
write_op writer, 0x003d, data.pack('v*')
|
640
553
|
end
|
641
554
|
##
|
642
|
-
# The main writer method. Calls #write_from_scratch
|
643
|
-
# depending on the class and state of _workbook_.
|
555
|
+
# The main writer method. Calls #write_from_scratch.
|
644
556
|
def write_workbook workbook, io
|
645
557
|
unless workbook.is_a?(Excel::Workbook) && workbook.io
|
646
558
|
@date_base = Date.new 1899, 12, 31
|
@@ -650,7 +562,8 @@ class Workbook < Spreadsheet::Writer
|
|
650
562
|
if workbook.changes.empty?
|
651
563
|
super
|
652
564
|
else
|
653
|
-
|
565
|
+
@date_base = Date.new 1899, 12, 31
|
566
|
+
write_from_scratch workbook, io
|
654
567
|
end
|
655
568
|
end
|
656
569
|
ensure
|
@@ -243,84 +243,6 @@ class Worksheet
|
|
243
243
|
end
|
244
244
|
write_multiples row, first_idx, multiples if multiples
|
245
245
|
end
|
246
|
-
def write_changes reader, endpos, sst_status
|
247
|
-
|
248
|
-
## FIXME this is not smart solution to update outline_level.
|
249
|
-
# without this process, outlines in row disappear in MS Excel.
|
250
|
-
@worksheet.row_count.times do |i|
|
251
|
-
if @worksheet.row(i).outline_level > 0
|
252
|
-
@worksheet.row(i).outline_level = @worksheet.row(i).outline_level
|
253
|
-
end
|
254
|
-
end
|
255
|
-
|
256
|
-
reader.seek @worksheet.offset
|
257
|
-
blocks = row_blocks
|
258
|
-
lastpos = reader.pos
|
259
|
-
offsets = {}
|
260
|
-
row_offsets = []
|
261
|
-
changes = @worksheet.changes
|
262
|
-
@worksheet.offsets.each do |key, pair|
|
263
|
-
if changes.include?(key) \
|
264
|
-
|| (sst_status == :complete_update && key.is_a?(Integer))
|
265
|
-
offsets.store pair, key
|
266
|
-
end
|
267
|
-
end
|
268
|
-
## FIXME it may be smarter to simply write all rowblocks, instead of doing a
|
269
|
-
# song-and-dance routine for every row...
|
270
|
-
work = offsets.invert
|
271
|
-
work.each do |key, (pos, len)|
|
272
|
-
case key
|
273
|
-
when Integer
|
274
|
-
row_offsets.push [key, [pos, len]]
|
275
|
-
when :dimensions
|
276
|
-
row_offsets.push [-1, [pos, len]]
|
277
|
-
end
|
278
|
-
end
|
279
|
-
row_offsets.sort!
|
280
|
-
row_offsets.reverse!
|
281
|
-
control = changes.size
|
282
|
-
@worksheet.each do |row|
|
283
|
-
key = row.idx
|
284
|
-
if changes.include?(key) && !work.include?(key)
|
285
|
-
row, pair = row_offsets.find do |idx, _| idx <= key end
|
286
|
-
work.store key, pair
|
287
|
-
end
|
288
|
-
end
|
289
|
-
if changes.size > control
|
290
|
-
warn <<-EOS
|
291
|
-
Your Worksheet was modified while it was being written. This should not happen.
|
292
|
-
Please contact the author (hannes dot wyss at gmail dot com) with a sample file
|
293
|
-
and minimal code that generates this warning. Thanks!
|
294
|
-
EOS
|
295
|
-
end
|
296
|
-
work = work.sort_by do |key, (pos, _)|
|
297
|
-
[pos, key.is_a?(Integer) ? key : -1]
|
298
|
-
end
|
299
|
-
work.each do |key, (pos, len)|
|
300
|
-
@io.write reader.read(pos - lastpos) if pos > lastpos
|
301
|
-
if key.is_a?(Integer)
|
302
|
-
if block = blocks.find do |rows| rows.any? do |row| row.idx == key end end
|
303
|
-
write_rowblock block
|
304
|
-
blocks.delete block
|
305
|
-
end
|
306
|
-
else
|
307
|
-
send "write_#{key}"
|
308
|
-
end
|
309
|
-
lastpos = pos + len
|
310
|
-
reader.seek lastpos
|
311
|
-
end
|
312
|
-
|
313
|
-
# Necessary for outline (grouping) and hiding functions
|
314
|
-
# but these below are not necessary to run
|
315
|
-
# if [Row|Column]#hidden? = false and [Row|Column]#outline_level == 0
|
316
|
-
write_merged_cells
|
317
|
-
write_pagesetup
|
318
|
-
write_margins
|
319
|
-
write_colinfos
|
320
|
-
write_guts
|
321
|
-
|
322
|
-
@io.write reader.read(endpos - lastpos)
|
323
|
-
end
|
324
246
|
def write_colinfo bunch
|
325
247
|
col = bunch.first
|
326
248
|
width = col.width.to_f * 256
|
data/lib/spreadsheet/version.rb
CHANGED
data/test/integration.rb
CHANGED
@@ -1401,6 +1401,30 @@ module Spreadsheet
|
|
1401
1401
|
assert_equal(:visible, book2.worksheet(1).visibility)
|
1402
1402
|
end
|
1403
1403
|
|
1404
|
+
def test_append_and_reopen
|
1405
|
+
filename = path = File.join @var, 'test.xls'
|
1406
|
+
sheet_name = 'Test Sheet'
|
1407
|
+
|
1408
|
+
# Create excel
|
1409
|
+
excel = Spreadsheet::Workbook.new(filename)
|
1410
|
+
sheet = excel.create_worksheet(name: sheet_name)
|
1411
|
+
sheet.row(1).replace ['Data']
|
1412
|
+
excel.write(filename)
|
1413
|
+
|
1414
|
+
# Append something
|
1415
|
+
excel = Spreadsheet.open(filename, 'a+')
|
1416
|
+
sheet = excel.worksheet(sheet_name)
|
1417
|
+
sheet.row(2).replace ['Data2']
|
1418
|
+
filename = "test2.xls"
|
1419
|
+
excel.write(filename)
|
1420
|
+
|
1421
|
+
# Reopen
|
1422
|
+
excel = Spreadsheet.open filename
|
1423
|
+
sheet = excel.worksheet sheet_name
|
1424
|
+
ensure
|
1425
|
+
File.delete filename if File.exist? filename
|
1426
|
+
end
|
1427
|
+
|
1404
1428
|
def test_text_drawing
|
1405
1429
|
path = File.join @data, 'test_text_drawing.xls'
|
1406
1430
|
book = Spreadsheet.open path
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spreadsheet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hannes F. Wyss, Masaomi Hatakeyama, Zeno R.R. Davatz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-09-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ruby-ole
|