Top Level Namespace
Defined Under Namespace
Modules: CallerInfo, ConvertDateTime, Writeexcel Classes: BIFFWriter, ExcelFormulaParser, ExcelFormulaParserError, MaxSizeError, OLEStorageLite, OLEStorageLitePPS, OLEStorageLitePPSFile, OLEStorageLitePPSRoot, OLEWriter, String, Workbook, WriteExcel, WriteFile
Constant Summary collapse
- NonAscii =
/[^!"#\$%&'\(\)\*\+,\-\.\/\:\;<=>\?@0-9A-Za-z_\[\\\]\{\}^` ~\0\n]/
Instance Method Summary collapse
-
#create_doc_summary_property_set(properties) ⇒ Object
Create the DocSummaryInformation property set.
-
#create_summary_property_set(properties) ⇒ Object
create_summary_property_set().
- #is_utf8?(str) ⇒ Boolean
-
#pack_property_data(properties, offset = 0) ⇒ Object
_pack_property_data().
-
#pack_VT_FILETIME(localtime) ⇒ Object
_pack_VT_FILETIME().
-
#pack_VT_I2(value) ⇒ Object
_pack_VT_I2().
-
#pack_VT_LPSTR(str, codepage) ⇒ Object
_pack_VT_LPSTR().
-
#ruby_18 ⇒ Object
:nodoc:.
-
#ruby_19 ⇒ Object
:nodoc:.
- #utf16be_to_16le(utf16be) ⇒ Object
Instance Method Details
#create_doc_summary_property_set(properties) ⇒ Object
Create the DocSummaryInformation property set. This is mainly used for the Manager, Company and Category keywords.
The DocSummary also contains a stream for user defined properties. However this is a little arcane and probably not worth the implementation effort.
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/writeexcel/properties.rb', line 70 def create_doc_summary_property_set(properties) #:nodoc: byte_order = [0xFFFE].pack('v') version = [0x0000].pack('v') system_id = [0x00020105].pack('V') class_id = ['00000000000000000000000000000000'].pack('H*') num_property_sets = [0x0002].pack('V') format_id_0 = ['02D5CDD59C2E1B10939708002B2CF9AE'].pack('H*') format_id_1 = ['05D5CDD59C2E1B10939708002B2CF9AE'].pack('H*') offset_0 = [0x0044].pack('V') num_property_0 = [properties.size].pack('V') property_offsets_0 = '' # Create the property set data block and calculate the offsets into it. property_data_0, offsets = pack_property_data(properties) # Create the property type and offsets based on the previous calculation. 0.upto(properties.size-1) do |i| property_offsets_0 += [properties[i][0], offsets[i]].pack('VV') end # Size of size (4 bytes) + num_property (4 bytes) + the data structures. data_len = 8 + (property_offsets_0).bytesize + property_data_0.bytesize size_0 = [data_len].pack('V') # The second property set offset is at the end of the first property set. offset_1 = [0x0044 + data_len].pack('V') # We will use a static property set stream rather than try to generate it. property_data_1 = [%w( 98 00 00 00 03 00 00 00 00 00 00 00 20 00 00 00 01 00 00 00 36 00 00 00 02 00 00 00 3E 00 00 00 01 00 00 00 02 00 00 00 0A 00 00 00 5F 50 49 44 5F 47 55 49 44 00 02 00 00 00 E4 04 00 00 41 00 00 00 4E 00 00 00 7B 00 31 00 36 00 43 00 34 00 42 00 38 00 33 00 42 00 2D 00 39 00 36 00 35 00 46 00 2D 00 34 00 42 00 32 00 31 00 2D 00 39 00 30 00 33 00 44 00 2D 00 39 00 31 00 30 00 46 00 41 00 44 00 46 00 41 00 37 00 30 00 31 00 42 00 7D 00 00 00 00 00 00 00 2D 00 39 00 30 00 33 00 ).join('')].pack('H*') byte_order + version + system_id + class_id + num_property_sets + format_id_0 + offset_0 + format_id_1 + offset_1 + size_0 + num_property_0 + property_offsets_0 + property_data_0 + property_data_1 end |
#create_summary_property_set(properties) ⇒ Object
create_summary_property_set().
Create the SummaryInformation property set. This is mainly used for the Title, Subject, Author, Keywords, Comments, Last author keywords and the creation date.
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/writeexcel/properties.rb', line 25 def create_summary_property_set(properties) #:nodoc: byte_order = [0xFFFE].pack('v') version = [0x0000].pack('v') system_id = [0x00020105].pack('V') class_id = ['00000000000000000000000000000000'].pack('H*') num_property_sets = [0x0001].pack('V') format_id = ['E0859FF2F94F6810AB9108002B27B3D9'].pack('H*') offset = [0x0030].pack('V') num_property = [properties.size].pack('V') property_offsets = '' # Create the property set data block and calculate the offsets into it. property_data, offsets = pack_property_data(properties) # Create the property type and offsets based on the previous calculation. 0.upto(properties.size - 1) do |i| property_offsets += [properties[i][0], offsets[i]].pack('VV') end # Size of size (4 bytes) + num_property (4 bytes) + the data structures. size = 8 + (property_offsets).bytesize + property_data.bytesize size = [size].pack('V') byte_order + version + system_id + class_id + num_property_sets + format_id + offset + size + num_property + property_offsets + property_data end |
#is_utf8?(str) ⇒ Boolean
75 76 77 78 |
# File 'lib/writeexcel/helper.rb', line 75 def is_utf8?(str) ruby_18 { str =~ NonAscii } || ruby_19 { str.encoding == Encoding::UTF_8 } end |
#pack_property_data(properties, offset = 0) ⇒ Object
_pack_property_data().
Create a packed property set structure. Strings are null terminated and padded to a 4 byte boundary. We also use this function to keep track of the property offsets within the data structure. These offsets are used by the calling functions. Currently we only need to handle 4 property types: VT_I2, VT_LPSTR, VT_FILETIME.
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/writeexcel/properties.rb', line 139 def pack_property_data(properties, offset = 0) #:nodoc: packed_property = '' data = '' offsets = [] # Get the strings codepage from the first property. codepage = properties[0][2] # The properties start after 8 bytes for size + num_properties + 8 bytes # for each propety type/offset pair. offset += 8 * (properties.size + 1) properties.each do |property| offsets.push(offset) property_type = property[1] if property_type == 'VT_I2' packed_property = pack_VT_I2(property[2]) elsif property_type == 'VT_LPSTR' packed_property = pack_VT_LPSTR(property[2], codepage) elsif property_type == 'VT_FILETIME' packed_property = pack_VT_FILETIME(property[2]) else raise "Unknown property type: '#{property_type}'\n" end offset += packed_property.bytesize data += packed_property end [data, offsets] end |
#pack_VT_FILETIME(localtime) ⇒ Object
_pack_VT_FILETIME().
Pack an OLE property type: VT_FILETIME.
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 |
# File 'lib/writeexcel/properties.rb', line 224 def pack_VT_FILETIME(localtime) #:nodoc: type = 0x0040 epoch = DateTime.new(1601, 1, 1) t = localtime.getgm datetime = DateTime.new( t.year, t.mon, t.mday, t.hour, t.min, t.sec, t.usec ) bignum = (datetime - epoch) * 86400 * 1e7.to_i high, low = bignum.divmod 1 << 32 [type].pack('V') + [low, high].pack('V2') end |
#pack_VT_I2(value) ⇒ Object
_pack_VT_I2().
Pack an OLE property type: VT_I2, 16-bit signed integer.
179 180 181 182 |
# File 'lib/writeexcel/properties.rb', line 179 def pack_VT_I2(value) #:nodoc: type = 0x0002 [type, value].pack('VV') end |
#pack_VT_LPSTR(str, codepage) ⇒ Object
_pack_VT_LPSTR().
Pack an OLE property type: VT_LPSTR, String in the Codepage encoding. The strings are null terminated and padded to a 4 byte boundary.
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
# File 'lib/writeexcel/properties.rb', line 191 def pack_VT_LPSTR(str, codepage) #:nodoc: type = 0x001E string = ruby_18 { "#{str}\0" } || ruby_19 { str.force_encoding('BINARY') + "\0".encode('BINARY') } if codepage == 0x04E4 # Latin1 length = string.bytesize elsif codepage == 0xFDE9 # utf8 length = string.bytesize else raise "Unknown codepage: #{codepage}\n" end # Pack the data. data = [type, length].pack('VV') data += string # The packed data has to null padded to a 4 byte boundary. if (extra = length % 4) != 0 data += "\0" * (4 - extra) end data end |
#ruby_18 ⇒ Object
:nodoc:
48 49 50 |
# File 'lib/writeexcel/compatibility.rb', line 48 def ruby_18 #:nodoc: yield end |
#ruby_19 ⇒ Object
:nodoc:
52 53 54 |
# File 'lib/writeexcel/compatibility.rb', line 52 def ruby_19 #:nodoc: false end |
#utf16be_to_16le(utf16be) ⇒ Object
22 23 24 |
# File 'lib/writeexcel/helper.rb', line 22 def utf16be_to_16le(utf16be) utf16be.unpack('n*').pack('v*') end |