writeexcel 0.3.5 → 0.4.0
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.
- data/.gitattributes +1 -0
- data/README.rdoc +12 -6
- data/VERSION +1 -1
- data/charts/chartex.rb +316 -315
- data/charts/demo1.rb +1 -0
- data/charts/demo2.rb +1 -0
- data/charts/demo3.rb +117 -116
- data/charts/demo4.rb +119 -118
- data/charts/demo5.rb +48 -47
- data/examples/a_simple.rb +1 -0
- data/examples/autofilter.rb +1 -0
- data/examples/bigfile.rb +30 -29
- data/examples/chart_area.rb +121 -120
- data/examples/chart_bar.rb +120 -119
- data/examples/chart_column.rb +120 -119
- data/examples/chart_line.rb +120 -119
- data/examples/chart_pie.rb +108 -107
- data/examples/chart_scatter.rb +121 -120
- data/examples/chart_stock.rb +148 -147
- data/examples/chess.rb +1 -0
- data/examples/colors.rb +1 -0
- data/examples/comments1.rb +1 -0
- data/examples/comments2.rb +3 -2
- data/examples/copyformat.rb +1 -0
- data/examples/data_validate.rb +1 -0
- data/examples/date_time.rb +1 -0
- data/examples/defined_name.rb +1 -0
- data/examples/demo.rb +1 -0
- data/examples/diag_border.rb +1 -0
- data/examples/formats.rb +1 -0
- data/examples/formula_result.rb +1 -0
- data/examples/header.rb +1 -0
- data/examples/hide_sheet.rb +1 -0
- data/examples/hyperlink.rb +1 -0
- data/examples/images.rb +1 -0
- data/examples/indent.rb +1 -0
- data/examples/merge1.rb +1 -0
- data/examples/merge2.rb +1 -0
- data/examples/merge3.rb +1 -0
- data/examples/merge4.rb +1 -0
- data/examples/merge5.rb +1 -0
- data/examples/merge6.rb +67 -66
- data/examples/outline.rb +1 -0
- data/examples/outline_collapsed.rb +1 -0
- data/examples/panes.rb +1 -0
- data/examples/properties.rb +1 -0
- data/examples/properties_jp.rb +1 -0
- data/examples/protection.rb +1 -0
- data/examples/regions.rb +1 -0
- data/examples/repeat.rb +1 -0
- data/examples/right_to_left.rb +1 -0
- data/examples/row_wrap.rb +1 -0
- data/examples/stats.rb +1 -0
- data/examples/stocks.rb +1 -0
- data/examples/tab_colors.rb +1 -0
- data/examples/write_arrays.rb +1 -0
- data/lib/writeexcel.rb +6 -1
- data/lib/writeexcel/biffwriter.rb +21 -20
- data/lib/writeexcel/chart.rb +25 -12
- data/lib/writeexcel/charts/area.rb +153 -152
- data/lib/writeexcel/charts/bar.rb +178 -177
- data/lib/writeexcel/charts/column.rb +157 -156
- data/lib/writeexcel/charts/external.rb +62 -61
- data/lib/writeexcel/charts/line.rb +153 -152
- data/lib/writeexcel/charts/pie.rb +170 -169
- data/lib/writeexcel/charts/scatter.rb +4 -3
- data/lib/writeexcel/charts/stock.rb +212 -211
- data/lib/writeexcel/compatibility.rb +320 -0
- data/lib/writeexcel/excelformulaparser.rb +587 -586
- data/lib/writeexcel/format.rb +12 -13
- data/lib/writeexcel/formula.rb +30 -28
- data/lib/writeexcel/helper.rb +23 -0
- data/lib/writeexcel/olewriter.rb +5 -16
- data/lib/writeexcel/properties.rb +43 -54
- data/lib/writeexcel/storage_lite.rb +981 -968
- data/lib/writeexcel/workbook.rb +94 -73
- data/lib/writeexcel/worksheet.rb +230 -210
- data/test/helper.rb +19 -0
- data/test/test_00_IEEE_double.rb +1 -0
- data/test/test_01_add_worksheet.rb +1 -0
- data/test/test_02_merge_formats.rb +3 -5
- data/test/test_04_dimensions.rb +3 -5
- data/test/test_05_rows.rb +6 -6
- data/test/test_06_extsst.rb +8 -8
- data/test/test_11_date_time.rb +3 -5
- data/test/test_12_date_only.rb +3 -5
- data/test/test_13_date_seconds.rb +4 -6
- data/test/test_21_escher.rb +3 -5
- data/test/test_22_mso_drawing_group.rb +20 -22
- data/test/test_23_note.rb +5 -7
- data/test/test_24_txo.rb +3 -5
- data/test/test_25_position_object.rb +84 -79
- data/test/test_26_autofilter.rb +3 -13
- data/test/test_27_autofilter.rb +3 -13
- data/test/test_28_autofilter.rb +3 -13
- data/test/test_29_process_jpg.rb +5 -0
- data/test/test_30_validation_dval.rb +3 -5
- data/test/test_31_validation_dv_strings.rb +3 -5
- data/test/test_32_validation_dv_formula.rb +3 -5
- data/test/test_40_property_types.rb +10 -9
- data/test/test_41_properties.rb +1 -0
- data/test/test_42_set_properties.rb +14 -15
- data/test/test_50_name_stored.rb +299 -302
- data/test/test_51_name_print_area.rb +357 -360
- data/test/test_52_name_print_titles.rb +454 -457
- data/test/test_53_autofilter.rb +203 -206
- data/test/test_60_chart_generic.rb +5 -0
- data/test/test_61_chart_subclasses.rb +95 -94
- data/test/test_62_chart_formats.rb +272 -267
- data/test/test_63_chart_area_formats.rb +649 -644
- data/test/test_biff.rb +12 -38
- data/test/test_compatibility.rb +627 -0
- data/test/test_example_match.rb +3 -18
- data/test/test_format.rb +46 -105
- data/test/test_formula.rb +1 -0
- data/test/test_ole.rb +3 -4
- data/test/test_storage_lite.rb +125 -146
- data/test/test_workbook.rb +2 -23
- data/test/test_worksheet.rb +4 -5
- data/utils/add_magic_comment.rb +80 -0
- data/writeexcel.gemspec +8 -2
- metadata +10 -4
data/lib/writeexcel/workbook.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
1
2
|
###############################################################################
|
2
3
|
#
|
3
4
|
# Workbook - A writer class for Excel Workbooks.
|
@@ -10,6 +11,8 @@
|
|
10
11
|
# original written in Perl by John McNamara
|
11
12
|
# converted to Ruby by Hideo Nakamura, cxn03651@msj.biglobe.ne.jp
|
12
13
|
#
|
14
|
+
require 'digest/md5'
|
15
|
+
require 'nkf'
|
13
16
|
require 'writeexcel/biffwriter'
|
14
17
|
require 'writeexcel/olewriter'
|
15
18
|
require 'writeexcel/formula'
|
@@ -24,15 +27,17 @@
|
|
24
27
|
require 'writeexcel/charts/pie'
|
25
28
|
require 'writeexcel/charts/scatter'
|
26
29
|
require 'writeexcel/charts/stock'
|
27
|
-
require 'writeexcel/properties'
|
28
|
-
require 'digest/md5'
|
29
30
|
require 'writeexcel/storage_lite'
|
31
|
+
require 'writeexcel/compatibility'
|
30
32
|
|
31
33
|
class Workbook < BIFFWriter
|
34
|
+
require 'writeexcel/properties'
|
35
|
+
require 'writeexcel/helper'
|
36
|
+
private :convert_to_ascii_if_ascii
|
37
|
+
|
32
38
|
BOF = 11 # :nodoc:
|
33
39
|
EOF = 4 # :nodoc:
|
34
40
|
SheetName = "Sheet" # :nodoc:
|
35
|
-
NonAscii = /[^!"#\$%&'\(\)\*\+,\-\.\/\:\;<=>\?@0-9A-Za-z_\[\\\]^` ~\0\n]/ # :nodoc:
|
36
41
|
|
37
42
|
#
|
38
43
|
# file is a filename (as string) or io object where to out spreadsheet data.
|
@@ -208,7 +213,8 @@ def close
|
|
208
213
|
return if @fileclosed # Prevent close() from being called twice.
|
209
214
|
|
210
215
|
@fileclosed = true
|
211
|
-
|
216
|
+
store_workbook
|
217
|
+
cleanup
|
212
218
|
end
|
213
219
|
|
214
220
|
# get array of Worksheet objects
|
@@ -489,11 +495,13 @@ def check_sheetname(name, encoding = 0, chart = 0) #:nodoc:
|
|
489
495
|
end
|
490
496
|
end
|
491
497
|
|
498
|
+
name = convert_to_ascii_if_ascii(name)
|
499
|
+
|
492
500
|
# Check that sheetname is <= 31 (1 or 2 byte chars). Excel limit.
|
493
|
-
raise "Sheetname $name must be <= 31 chars" if name.
|
501
|
+
raise "Sheetname $name must be <= 31 chars" if name.bytesize > limit
|
494
502
|
|
495
503
|
# Check that Unicode sheetname has an even number of bytes
|
496
|
-
if encoding == 1 && (name.
|
504
|
+
if encoding == 1 && (name.bytesize % 2 != 0)
|
497
505
|
raise "Odd number of bytes in Unicode worksheet name: #{name}"
|
498
506
|
end
|
499
507
|
|
@@ -514,8 +522,9 @@ def check_sheetname(name, encoding = 0, chart = 0) #:nodoc:
|
|
514
522
|
end
|
515
523
|
|
516
524
|
# Handle utf8 strings
|
517
|
-
if name
|
525
|
+
if name.encoding == Encoding::UTF_8
|
518
526
|
name = NKF.nkf('-w16B0 -m0 -W', name)
|
527
|
+
name.force_encoding('UTF-16BE')
|
519
528
|
encoding = 1
|
520
529
|
end
|
521
530
|
|
@@ -750,7 +759,7 @@ def set_custom_color(index = nil, red = nil, green = nil, blue = nil)
|
|
750
759
|
# Set the RGB value
|
751
760
|
@palette[index] = [red, green, blue, 0]
|
752
761
|
|
753
|
-
|
762
|
+
index + 8
|
754
763
|
end
|
755
764
|
|
756
765
|
###############################################################################
|
@@ -818,7 +827,7 @@ def set_palette_xl97 #:nodoc:
|
|
818
827
|
[0x33, 0x33, 0x99, 0x00], # 62
|
819
828
|
[0x33, 0x33, 0x33, 0x00] # 63
|
820
829
|
]
|
821
|
-
|
830
|
+
0
|
822
831
|
end
|
823
832
|
private :set_palette_xl97
|
824
833
|
|
@@ -956,7 +965,7 @@ def define_name(name, formula, encoding = 0)
|
|
956
965
|
}
|
957
966
|
)
|
958
967
|
|
959
|
-
index = @defined_names.
|
968
|
+
index = @defined_names.size
|
960
969
|
|
961
970
|
parser.set_ext_name(name, index)
|
962
971
|
end
|
@@ -1016,6 +1025,9 @@ def set_properties(params)
|
|
1016
1025
|
# Ignore if no args were passed.
|
1017
1026
|
return -1 if !params.kind_of?(Hash) || params.empty?
|
1018
1027
|
|
1028
|
+
params.each do |k, v|
|
1029
|
+
params[k] = convert_to_ascii_if_ascii(v) if v.kind_of?(String)
|
1030
|
+
end
|
1019
1031
|
# List of valid input parameters.
|
1020
1032
|
properties = {
|
1021
1033
|
:codepage => [0x0001, 'VT_I2' ],
|
@@ -1112,7 +1124,7 @@ def get_property_set_codepage(params, strings) #:nodoc:
|
|
1112
1124
|
else
|
1113
1125
|
strings.each do |string|
|
1114
1126
|
next unless params.has_key?(string.to_sym)
|
1115
|
-
return 0xFDE9 if params[string.to_sym]
|
1127
|
+
return 0xFDE9 if params[string.to_sym].encoding == Encoding::UTF_8
|
1116
1128
|
end
|
1117
1129
|
return 0x04E4; # Default codepage, Latin 1.
|
1118
1130
|
end
|
@@ -1248,8 +1260,6 @@ def store_OLE_file #:nodoc:
|
|
1248
1260
|
|
1249
1261
|
return ole.close
|
1250
1262
|
else
|
1251
|
-
# Write the OLE file using ruby-ole if data > 7MB
|
1252
|
-
|
1253
1263
|
# Create the Workbook stream.
|
1254
1264
|
stream = 'Workbook'.unpack('C*').pack('v*')
|
1255
1265
|
workbook = OLEStorageLitePPSFile.new(stream)
|
@@ -1327,7 +1337,7 @@ def calc_sheet_offsets #:nodoc:
|
|
1327
1337
|
offset += mso_size
|
1328
1338
|
|
1329
1339
|
@worksheets.each do |sheet|
|
1330
|
-
offset += _bof + sheet.name.
|
1340
|
+
offset += _bof + sheet.name.bytesize
|
1331
1341
|
end
|
1332
1342
|
|
1333
1343
|
offset += _eof
|
@@ -1483,7 +1493,7 @@ def process_images #:nodoc:
|
|
1483
1493
|
# Slurp the file into a string and do some size calcs.
|
1484
1494
|
# my $data = do {local $/; <$fh>};
|
1485
1495
|
data = fh.read
|
1486
|
-
size = data.
|
1496
|
+
size = data.bytesize
|
1487
1497
|
checksum1 = image_checksum(data, image_id)
|
1488
1498
|
checksum2 = checksum1
|
1489
1499
|
ref_count = 1
|
@@ -1594,7 +1604,7 @@ def process_png(data) #:nodoc:
|
|
1594
1604
|
width = data[16, 4].unpack("N")[0]
|
1595
1605
|
height = data[20, 4].unpack("N")[0]
|
1596
1606
|
|
1597
|
-
|
1607
|
+
[type, width, height]
|
1598
1608
|
end
|
1599
1609
|
private :process_png
|
1600
1610
|
|
@@ -1610,7 +1620,7 @@ def process_bmp(data, filename) #:nodoc:
|
|
1610
1620
|
type = 7 # Excel Blip type (MSOBLIPTYPE).
|
1611
1621
|
|
1612
1622
|
# Check that the file is big enough to be a bitmap.
|
1613
|
-
if data.
|
1623
|
+
if data.bytesize <= 0x36
|
1614
1624
|
raise "#{filename} doesn't contain enough data."
|
1615
1625
|
end
|
1616
1626
|
|
@@ -1643,7 +1653,7 @@ def process_bmp(data, filename) #:nodoc:
|
|
1643
1653
|
raise "#{filename}: compression not supported in bitmap image."
|
1644
1654
|
end
|
1645
1655
|
|
1646
|
-
|
1656
|
+
[type, width, height]
|
1647
1657
|
end
|
1648
1658
|
private :process_bmp
|
1649
1659
|
|
@@ -1657,7 +1667,7 @@ def process_jpg(data, filename) # :nodoc:
|
|
1657
1667
|
type = 5 # Excel Blip type (MSOBLIPTYPE).
|
1658
1668
|
|
1659
1669
|
offset = 2;
|
1660
|
-
data_length = data.
|
1670
|
+
data_length = data.bytesize
|
1661
1671
|
|
1662
1672
|
# Search through the image data to find the 0xFFC0 marker. The height and
|
1663
1673
|
# width are contained in the data for that sub element.
|
@@ -1675,7 +1685,7 @@ def process_jpg(data, filename) # :nodoc:
|
|
1675
1685
|
break
|
1676
1686
|
end
|
1677
1687
|
|
1678
|
-
offset
|
1688
|
+
offset += length + 2
|
1679
1689
|
break if marker == 0xFFDA
|
1680
1690
|
end
|
1681
1691
|
|
@@ -1762,21 +1772,21 @@ def store_all_fonts #:nodoc:
|
|
1762
1772
|
# Fonts that are marked as '_font_only' are always stored. These are used
|
1763
1773
|
# mainly for charts and may not have an associated XF record.
|
1764
1774
|
|
1765
|
-
@formats.each do |
|
1766
|
-
key =
|
1767
|
-
if
|
1775
|
+
@formats.each do |fmt|
|
1776
|
+
key = fmt.get_font_key
|
1777
|
+
if fmt.font_only == 0 and !fonts[key].nil?
|
1768
1778
|
# FONT has already been used
|
1769
|
-
|
1779
|
+
fmt.font_index = fonts[key]
|
1770
1780
|
else
|
1771
1781
|
# Add a new FONT record
|
1772
1782
|
|
1773
|
-
if
|
1783
|
+
if fmt.font_only == 0
|
1774
1784
|
fonts[key] = index
|
1775
1785
|
end
|
1776
1786
|
|
1777
|
-
|
1787
|
+
fmt.font_index = index
|
1778
1788
|
index += 1
|
1779
|
-
font =
|
1789
|
+
font = fmt.get_font
|
1780
1790
|
print "#{__FILE__}(#{__LINE__}) \n" if defined?($debug)
|
1781
1791
|
append(font)
|
1782
1792
|
end
|
@@ -2038,10 +2048,10 @@ def store_window1 #:nodoc:
|
|
2038
2048
|
# Writes Excel BIFF BOUNDSHEET record.
|
2039
2049
|
#
|
2040
2050
|
def store_boundsheet(sheetname, offset, type, hidden, encoding) #:nodoc:
|
2041
|
-
record = 0x0085
|
2042
|
-
length = 0x08 + sheetname.
|
2051
|
+
record = 0x0085 # Record identifier
|
2052
|
+
length = 0x08 + sheetname.bytesize # Number of bytes to follow
|
2043
2053
|
|
2044
|
-
cch = sheetname.
|
2054
|
+
cch = sheetname.bytesize # Length of sheet name
|
2045
2055
|
|
2046
2056
|
grbit = type | hidden
|
2047
2057
|
|
@@ -2097,11 +2107,14 @@ def store_num_format(format, ifmt, encoding) #:nodoc:
|
|
2097
2107
|
record = 0x041E # Record identifier
|
2098
2108
|
# length # Number of bytes to follow
|
2099
2109
|
# Char length of format string
|
2100
|
-
cch = format.
|
2110
|
+
cch = format.bytesize
|
2111
|
+
|
2112
|
+
format = convert_to_ascii_if_ascii(format)
|
2101
2113
|
|
2102
2114
|
# Handle utf8 strings
|
2103
|
-
if format
|
2115
|
+
if format.encoding == Encoding::UTF_8
|
2104
2116
|
format = NKF.nkf('-w16B0 -m0 -W', format)
|
2117
|
+
format.force_encoding('UTF-16BE')
|
2105
2118
|
encoding = 1
|
2106
2119
|
end
|
2107
2120
|
|
@@ -2112,14 +2125,15 @@ def store_num_format(format, ifmt, encoding) #:nodoc:
|
|
2112
2125
|
format = format.unpack('n*').pack('v*')
|
2113
2126
|
end
|
2114
2127
|
|
2128
|
+
=begin
|
2115
2129
|
# Special case to handle Euro symbol, 0x80, in non-Unicode strings.
|
2116
2130
|
if encoding == 0 and format =~ /\x80/
|
2117
2131
|
format = format.unpack('C*').pack('v*')
|
2118
2132
|
format.gsub!(/\x80\x00/, "\xAC\x20")
|
2119
2133
|
encoding = 1
|
2120
2134
|
end
|
2121
|
-
|
2122
|
-
length = 0x05 + format.
|
2135
|
+
=end
|
2136
|
+
length = 0x05 + format.bytesize
|
2123
2137
|
|
2124
2138
|
header = [record, length].pack("vv")
|
2125
2139
|
data = [ifmt, cch, encoding].pack("vvC")
|
@@ -2187,18 +2201,18 @@ def store_externsheet # :nodoc:
|
|
2187
2201
|
ext = ext_refs.keys.sort
|
2188
2202
|
|
2189
2203
|
# Change the external refs from stringified "1:1" to [1, 1]
|
2190
|
-
ext.map! {|e| e.split(/:/).map! {|
|
2204
|
+
ext.map! {|e| e.split(/:/).map! {|v| v.to_i} }
|
2191
2205
|
|
2192
2206
|
cxti = ext.size # Number of Excel XTI structures
|
2193
2207
|
rgxti = '' # Array of XTI structures
|
2194
2208
|
|
2195
2209
|
# Write the XTI structs
|
2196
2210
|
ext.each do |e|
|
2197
|
-
rgxti
|
2211
|
+
rgxti += [0, e[0], e[1]].pack("vvv")
|
2198
2212
|
end
|
2199
2213
|
|
2200
2214
|
data = [cxti].pack("v") + rgxti
|
2201
|
-
header = [record, data.
|
2215
|
+
header = [record, data.bytesize].pack("vv")
|
2202
2216
|
|
2203
2217
|
print "#{__FILE__}(#{__LINE__}) \n" if defined?($debug)
|
2204
2218
|
append(header, data)
|
@@ -2212,10 +2226,12 @@ def store_externsheet # :nodoc:
|
|
2212
2226
|
# and _store_name_long().
|
2213
2227
|
#
|
2214
2228
|
def store_name(name, encoding, sheet_index, formula) # :nodoc:
|
2229
|
+
formula = convert_to_ascii_if_ascii(formula)
|
2230
|
+
|
2215
2231
|
record = 0x0018 # Record identifier
|
2216
2232
|
|
2217
|
-
text_length = name.
|
2218
|
-
formula_length = formula.
|
2233
|
+
text_length = name.bytesize
|
2234
|
+
formula_length = formula.bytesize
|
2219
2235
|
|
2220
2236
|
# UTF-16 string length is in characters not bytes.
|
2221
2237
|
text_length /= 2 if encoding != 0
|
@@ -2230,9 +2246,9 @@ def store_name(name, encoding, sheet_index, formula) # :nodoc:
|
|
2230
2246
|
|
2231
2247
|
# Set grbit built-in flag and the hidden flag for autofilters.
|
2232
2248
|
if text_length == 1
|
2233
|
-
grbit = 0x0020 if name
|
2234
|
-
grbit = 0x0020 if name
|
2235
|
-
grbit = 0x0021 if name
|
2249
|
+
grbit = 0x0020 if name.ord == 0x06 # Print area
|
2250
|
+
grbit = 0x0020 if name.ord == 0x07 # Print titles
|
2251
|
+
grbit = 0x0021 if name.ord == 0x0D # Autofilter
|
2236
2252
|
end
|
2237
2253
|
|
2238
2254
|
data = [grbit].pack("v")
|
@@ -2249,7 +2265,7 @@ def store_name(name, encoding, sheet_index, formula) # :nodoc:
|
|
2249
2265
|
data += name
|
2250
2266
|
data += formula
|
2251
2267
|
|
2252
|
-
header = [record, data.
|
2268
|
+
header = [record, data.bytesize].pack("vv")
|
2253
2269
|
|
2254
2270
|
print "#{__FILE__}(#{__LINE__}) \n" if defined?($debug)
|
2255
2271
|
append(header, data)
|
@@ -2280,7 +2296,7 @@ def store_name_short(index, type, ext_ref, rowmin, rowmax, colmin, colmax, hidde
|
|
2280
2296
|
cch = 0x01 # Length of text name
|
2281
2297
|
cce = 0x000b # Length of text definition
|
2282
2298
|
unknown01 = 0x0000 #
|
2283
|
-
ixals = index +1
|
2299
|
+
ixals = index + 1 # Sheet index
|
2284
2300
|
unknown02 = 0x00 #
|
2285
2301
|
cchCustMenu = 0x00 # Length of cust menu text
|
2286
2302
|
cchDescription = 0x00 # Length of description text
|
@@ -2343,7 +2359,7 @@ def store_name_long(index, type, ext_ref, rowmin, rowmax, colmin, colmax)
|
|
2343
2359
|
cch = 0x01 # Length of text name
|
2344
2360
|
cce = 0x001a # Length of text definition
|
2345
2361
|
unknown01 = 0x0000 #
|
2346
|
-
ixals = index +1
|
2362
|
+
ixals = index + 1 # Sheet index
|
2347
2363
|
unknown02 = 0x00 #
|
2348
2364
|
cchCustMenu = 0x00 # Length of cust menu text
|
2349
2365
|
cchDescription = 0x00 # Length of description text
|
@@ -2408,7 +2424,7 @@ def store_palette #:nodoc:
|
|
2408
2424
|
|
2409
2425
|
# Pack the RGB data
|
2410
2426
|
@palette.each do |p|
|
2411
|
-
data
|
2427
|
+
data += p.pack('CCCC')
|
2412
2428
|
end
|
2413
2429
|
|
2414
2430
|
header = [record, length, ccv].pack("vvv")
|
@@ -2505,7 +2521,7 @@ def calculate_extern_sizes # :nodoc:
|
|
2505
2521
|
end
|
2506
2522
|
|
2507
2523
|
@defined_names.each do |defined_name|
|
2508
|
-
length += 19 + defined_name[:name].
|
2524
|
+
length += 19 + defined_name[:name].bytesize + defined_name[:formula].bytesize
|
2509
2525
|
end
|
2510
2526
|
|
2511
2527
|
@worksheets.each do |worksheet|
|
@@ -2571,7 +2587,7 @@ def calculate_extern_sizes # :nodoc:
|
|
2571
2587
|
# The EXTERNSHEET record is 6 bytes + 6 bytes for each external ref
|
2572
2588
|
length += 6 * (1 + ext_ref_count)
|
2573
2589
|
|
2574
|
-
|
2590
|
+
length
|
2575
2591
|
end
|
2576
2592
|
|
2577
2593
|
###############################################################################
|
@@ -2620,7 +2636,7 @@ def calculate_shared_string_sizes #:nodoc:
|
|
2620
2636
|
|
2621
2637
|
strings.each do |string|
|
2622
2638
|
|
2623
|
-
string_length = string.
|
2639
|
+
string_length = string.bytesize
|
2624
2640
|
encoding = string.unpack("xx C")[0]
|
2625
2641
|
split_string = 0
|
2626
2642
|
|
@@ -2730,7 +2746,7 @@ def calculate_shared_string_sizes #:nodoc:
|
|
2730
2746
|
length += 4 + block_sizes.shift # CONTINUEs
|
2731
2747
|
end
|
2732
2748
|
|
2733
|
-
|
2749
|
+
length
|
2734
2750
|
end
|
2735
2751
|
private :calculate_shared_string_sizes
|
2736
2752
|
|
@@ -2788,7 +2804,7 @@ def store_shared_strings #:nodoc:
|
|
2788
2804
|
return if strings.empty?
|
2789
2805
|
strings.each do |string|
|
2790
2806
|
|
2791
|
-
string_length = string.
|
2807
|
+
string_length = string.bytesize
|
2792
2808
|
encoding = string.unpack("xx C")[0]
|
2793
2809
|
split_string = 0
|
2794
2810
|
bucket_string = 0 # Used to track EXTSST bucket offsets.
|
@@ -2906,7 +2922,7 @@ def store_shared_strings #:nodoc:
|
|
2906
2922
|
length = block_sizes.shift
|
2907
2923
|
|
2908
2924
|
header = [record, length].pack("vv")
|
2909
|
-
header
|
2925
|
+
header += [encoding].pack("C") if continue != 0
|
2910
2926
|
|
2911
2927
|
print "#{__FILE__}(#{__LINE__}) \n" if defined?($debug)
|
2912
2928
|
append(header)
|
@@ -2963,7 +2979,7 @@ def calculate_extsst_size #:nodoc:
|
|
2963
2979
|
@extsst_buckets = buckets
|
2964
2980
|
@extsst_bucket_size = bucket_size
|
2965
2981
|
|
2966
|
-
|
2982
|
+
6 + 8 * buckets
|
2967
2983
|
end
|
2968
2984
|
|
2969
2985
|
###############################################################################
|
@@ -2983,7 +2999,7 @@ def store_extsst #:nodoc:
|
|
2983
2999
|
data = [bucket_size].pack('v')
|
2984
3000
|
|
2985
3001
|
offsets.each do |offset|
|
2986
|
-
data
|
3002
|
+
data += [offset[0], offset[1], 0].pack('Vvv')
|
2987
3003
|
end
|
2988
3004
|
|
2989
3005
|
print "#{__FILE__}(#{__LINE__}) \n" if defined?($debug)
|
@@ -3009,20 +3025,20 @@ def add_mso_drawing_group #:nodoc:
|
|
3009
3025
|
length = 0x0000 # Number of bytes to follow
|
3010
3026
|
|
3011
3027
|
data = store_mso_dgg_container
|
3012
|
-
data
|
3013
|
-
data
|
3028
|
+
data += store_mso_dgg(*@mso_clusters)
|
3029
|
+
data += store_mso_bstore_container
|
3014
3030
|
@images_data.each do |image|
|
3015
|
-
data
|
3031
|
+
data += store_mso_images(*image)
|
3016
3032
|
end
|
3017
|
-
data
|
3018
|
-
data
|
3033
|
+
data += store_mso_opt
|
3034
|
+
data += store_mso_split_menu_colors
|
3019
3035
|
|
3020
|
-
length = data.
|
3036
|
+
length = data.bytesize
|
3021
3037
|
header = [record, length].pack("vv")
|
3022
3038
|
|
3023
3039
|
add_mso_drawing_group_continue(header + data)
|
3024
3040
|
|
3025
|
-
|
3041
|
+
header + data # For testing only.
|
3026
3042
|
end
|
3027
3043
|
private :add_mso_drawing_group
|
3028
3044
|
|
@@ -3051,7 +3067,7 @@ def add_mso_drawing_group_continue(data) #:nodoc:
|
|
3051
3067
|
@ignore_continue = 1
|
3052
3068
|
|
3053
3069
|
# Case 1 above. Just return the data as it is.
|
3054
|
-
if data.
|
3070
|
+
if data.bytesize <= limit
|
3055
3071
|
print "#{__FILE__}(#{__LINE__}) \n" if defined?($debug)
|
3056
3072
|
append(data)
|
3057
3073
|
return
|
@@ -3065,7 +3081,7 @@ def add_mso_drawing_group_continue(data) #:nodoc:
|
|
3065
3081
|
append(tmp)
|
3066
3082
|
|
3067
3083
|
# Add MSODRAWINGGROUP and CONTINUE blocks for Case 3 above.
|
3068
|
-
while data.
|
3084
|
+
while data.bytesize > limit
|
3069
3085
|
if block_count == 1
|
3070
3086
|
# Add extra MSODRAWINGGROUP block header.
|
3071
3087
|
header = [mso_group, limit].pack("vv")
|
@@ -3082,7 +3098,7 @@ def add_mso_drawing_group_continue(data) #:nodoc:
|
|
3082
3098
|
end
|
3083
3099
|
|
3084
3100
|
# Last CONTINUE block for remaining data. Case 2 and 3 above.
|
3085
|
-
header = [continue, data.
|
3101
|
+
header = [continue, data.bytesize].pack("vv")
|
3086
3102
|
print "#{__FILE__}(#{__LINE__}) \n" if defined?($debug)
|
3087
3103
|
append(header, data)
|
3088
3104
|
|
@@ -3104,7 +3120,7 @@ def store_mso_dgg_container #:nodoc:
|
|
3104
3120
|
data = ''
|
3105
3121
|
length = @mso_size -12 # -4 (biff header) -8 (for this).
|
3106
3122
|
|
3107
|
-
|
3123
|
+
add_mso_generic(type, version, instance, data, length)
|
3108
3124
|
end
|
3109
3125
|
private :store_mso_dgg_container
|
3110
3126
|
|
@@ -3133,10 +3149,10 @@ def store_mso_dgg(max_spid, num_clusters, shapes_saved, drawings_saved, clusters
|
|
3133
3149
|
drawing_id = aref[0]
|
3134
3150
|
shape_ids_used = aref[1]
|
3135
3151
|
|
3136
|
-
data
|
3152
|
+
data += [drawing_id, shape_ids_used].pack("VV")
|
3137
3153
|
end
|
3138
3154
|
|
3139
|
-
|
3155
|
+
add_mso_generic(type, version, instance, data, length)
|
3140
3156
|
end
|
3141
3157
|
private :store_mso_dgg
|
3142
3158
|
|
@@ -3155,7 +3171,7 @@ def store_mso_bstore_container #:nodoc:
|
|
3155
3171
|
data = ''
|
3156
3172
|
length = @images_size +8 *instance
|
3157
3173
|
|
3158
|
-
|
3174
|
+
add_mso_generic(type, version, instance, data, length)
|
3159
3175
|
end
|
3160
3176
|
private :store_mso_bstore_container
|
3161
3177
|
|
@@ -3187,7 +3203,7 @@ def store_mso_images(ref_count, image_type, image, size, checksum1, checksum2)
|
|
3187
3203
|
checksum2
|
3188
3204
|
)
|
3189
3205
|
|
3190
|
-
|
3206
|
+
blip_store_entry + blip
|
3191
3207
|
end
|
3192
3208
|
private :store_mso_images
|
3193
3209
|
|
@@ -3218,7 +3234,7 @@ def store_mso_blip_store_entry(ref_count, image_type, size, checksum1) #:n
|
|
3218
3234
|
[0x00].pack('C') + # Unused
|
3219
3235
|
[0x00].pack('C') # Unused
|
3220
3236
|
|
3221
|
-
|
3237
|
+
add_mso_generic(type, version, instance, data, length)
|
3222
3238
|
end
|
3223
3239
|
private :store_mso_blip_store_entry
|
3224
3240
|
|
@@ -3250,7 +3266,7 @@ def store_mso_blip(image_type, image_data, size, checksum1, checksum2) #:n
|
|
3250
3266
|
[0xFF].pack('C') + # Tag
|
3251
3267
|
image_data # Image
|
3252
3268
|
|
3253
|
-
|
3269
|
+
add_mso_generic(type, version, instance, data, length)
|
3254
3270
|
end
|
3255
3271
|
private :store_mso_blip
|
3256
3272
|
|
@@ -3269,7 +3285,7 @@ def store_mso_opt #:nodoc:
|
|
3269
3285
|
|
3270
3286
|
data = ['BF0008000800810109000008C0014000'+'0008'].pack("H*")
|
3271
3287
|
|
3272
|
-
|
3288
|
+
add_mso_generic(type, version, instance, data, length)
|
3273
3289
|
end
|
3274
3290
|
private :store_mso_opt
|
3275
3291
|
|
@@ -3288,7 +3304,12 @@ def store_mso_split_menu_colors #:nodoc:
|
|
3288
3304
|
|
3289
3305
|
data = ['0D0000080C00000817000008F7000010'].pack("H*")
|
3290
3306
|
|
3291
|
-
|
3307
|
+
add_mso_generic(type, version, instance, data, length)
|
3292
3308
|
end
|
3293
3309
|
private :store_mso_split_menu_colors
|
3310
|
+
|
3311
|
+
def cleanup
|
3312
|
+
super
|
3313
|
+
sheets.each { |sheet| sheet.cleanup }
|
3314
|
+
end
|
3294
3315
|
end
|