【发布时间】:2019-09-08 17:12:20
【问题描述】:
我正在解决以下问题:我想下载一个 .xlsx 文件(单击时),使用 SheetJS 创建工作簿并使用 FileSaver 保存文件。我遇到的问题是,当超过大约 100k 行时,无法写入文件。 我如何构建整个过程的代码sn-p(主要取自sheetjs示例和以下教程https://www.youtube.com/watch?v=41rOAt-zCu4):
let wb = XLSX.utils.book_new()
wb.Props = {
Title: 'Test Sheet',
Subject: 'Test file',
Author: 'Firstname Lastname'
}
// create worksheet in new workbook, write data, use array of arrays
wb.SheetNames.push('Sheet1')
// rowData is the array of arrays bigger than 90k
let wsData = rowData
let ws = XLSX.utils.aoa_to_sheet(wsData)
wb.Sheets['Sheet1'] = ws
let wbout = XLSX.write(wb, {bookType: 'xlsx', type: 'binary'})
// until here the workbook with the test sheet is created, but not ready to be downloaded by user
// for saving, we use file-saver. it needs a different format (octet), which can be generated
// using the s2ab function
function s2ab (s) {
let buf = new ArrayBuffer(s.length)
let view = new Uint8Array(buf)
for (var i = 0; i < s.length; i++) view[i] = s.charCodeAt(i) & 0xFF
return buf
}
FileSaver.saveAs(new Blob([s2ab(wbout)], {type: 'application/octet-stream'}), 'test.xlsx')
我有写几个 excel 表的想法,每个表有 90000 行,但我认为这没关系,因为我想写的对象对于本地内存来说太大了?而且我认为错误是由文件保护程序在生成八位字节格式时产生的,但我不确定。
所以,我正在寻找解决方案,我想到了流。我不想生成整个对象然后尝试编写它,而是想在生成行的同时编写并逐行编写。这应该不会占用我的内存吧?
但我找不到任何关于如何做到这一点的信息(之前从未使用过流等)。主要问题是内存,因为项目必须离线并且必须在本地 RAM/系统上运行)。
【问题讨论】:
-
我不知道你的文件大小和内存大小,但
FileSaver.js的github第一段是:If you need to save really large files bigger then the blob's size limitation or don't have enough RAM, then have a look at the more advanced StreamSaver.js that can save data directly to the hard drive asynchronously with the power of the new streams API. That will have support for progress, cancelation and knowing when it's done writing -
我现在已经深入挖掘,你是对的,BLOB 的大小限制是问题所在。到目前为止,我正在尝试其他解决方案,例如附加。但我也会深入研究 StreamSaver.js,谢谢!
标签: javascript out-of-memory js-xlsx sheetjs