(data, options)
| 258 | } |
| 259 | |
| 260 | async load(data, options) { |
| 261 | let buffer; |
| 262 | if (options && options.base64) { |
| 263 | buffer = Buffer.from(data.toString(), 'base64'); |
| 264 | } else { |
| 265 | buffer = data; |
| 266 | } |
| 267 | |
| 268 | const model = { |
| 269 | worksheets: [], |
| 270 | worksheetHash: {}, |
| 271 | worksheetRels: [], |
| 272 | themes: {}, |
| 273 | media: [], |
| 274 | mediaIndex: {}, |
| 275 | drawings: {}, |
| 276 | drawingRels: {}, |
| 277 | comments: {}, |
| 278 | tables: {}, |
| 279 | vmlDrawings: {}, |
| 280 | }; |
| 281 | |
| 282 | const zip = await JSZip.loadAsync(buffer); |
| 283 | for (const entry of Object.values(zip.files)) { |
| 284 | /* eslint-disable no-await-in-loop */ |
| 285 | if (!entry.dir) { |
| 286 | let entryName = entry.name; |
| 287 | if (entryName[0] === '/') { |
| 288 | entryName = entryName.substr(1); |
| 289 | } |
| 290 | let stream; |
| 291 | if ( |
| 292 | entryName.match(/xl\/media\//) || |
| 293 | // themes are not parsed as stream |
| 294 | entryName.match(/xl\/theme\/([a-zA-Z0-9]+)[.]xml/) |
| 295 | ) { |
| 296 | stream = new PassThrough(); |
| 297 | stream.write(await entry.async('nodebuffer')); |
| 298 | } else { |
| 299 | // use object mode to avoid buffer-string convention |
| 300 | stream = new PassThrough({ |
| 301 | writableObjectMode: true, |
| 302 | readableObjectMode: true, |
| 303 | }); |
| 304 | let content; |
| 305 | // https://www.npmjs.com/package/process |
| 306 | if (process.browser) { |
| 307 | // running in browser, use TextDecoder if possible |
| 308 | content = bufferToString(await entry.async('nodebuffer')); |
| 309 | } else { |
| 310 | // running in node.js |
| 311 | content = await entry.async('string'); |
| 312 | } |
| 313 | const chunkSize = 16 * 1024; |
| 314 | for (let i = 0; i < content.length; i += chunkSize) { |
| 315 | stream.write(content.substring(i, i + chunkSize)); |
| 316 | } |
| 317 | } |
no test coverage detected