Javascript 如何将.xlsx数据保存为blob文件
我有一个与这个问题类似的问题() 我正在尝试保存excelbuilder.js的Javascript 如何将.xlsx数据保存为blob文件,javascript,xlsx,bloburls,Javascript,Xlsx,Bloburls,我有一个与这个问题类似的问题() 我正在尝试保存excelbuilder.js的EB.createFile()函数创建的数据。如果我将文件数据作为链接的href属性值,则它可以工作。然而,当数据很大时,它会使Chrome浏览器崩溃。代码如下: //generate a temp <a /> tag var link = document.createElement("a"); link.href = 'data:application/vnd.openxmlformats-offic
EB.createFile()
函数创建的数据。如果我将文件数据作为链接的href
属性值,则它可以工作。然而,当数据很大时,它会使Chrome浏览器崩溃。代码如下:
//generate a temp <a /> tag
var link = document.createElement("a");
link.href = 'data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,' + encodeURIComponent(data);
link.style = "visibility:hidden";
link.download = fileName;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
var blob = new Blob(
[data],
{type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,"}
);
// Programatically create a link and click it:
var a = document.createElement("a");
a.href = URL.createObjectURL(blob);
a.download = fileName;
a.click();
正如类似问题()的答案所建议的,需要创建一个blob
我的问题是,文件中保存的内容不是可以由Excel打开的有效Excel文件。我用来保存blob
的代码如下:
//generate a temp <a /> tag
var link = document.createElement("a");
link.href = 'data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,' + encodeURIComponent(data);
link.style = "visibility:hidden";
link.download = fileName;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
var blob = new Blob(
[data],
{type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,"}
);
// Programatically create a link and click it:
var a = document.createElement("a");
a.href = URL.createObjectURL(blob);
a.download = fileName;
a.click();
如果我将上述代码中的[data]
替换为[Base64.decode(data)]
,则保存的文件中的内容看起来更像预期的excel数据,但excel仍无法打开
谢谢 试试
FileSaver.js
library。这可能会有帮助
我和你有同样的问题。事实证明,您需要将Excel数据文件转换为ArrayBuffer
var blob = new Blob([s2ab(atob(data))], {
type: ''
});
href = URL.createObjectURL(blob);
s2ab(字符串到数组缓冲区)方法(我从中获得)是:
答案是正确的。请确保数据变量中有base64中的字符串数据,没有任何前缀或类似的东西,只是原始数据
以下是我在服务器端(asp.net mvc core)所做的工作:
在客户端,我执行了以下代码:
const xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.setRequestHeader("Content-Type", "text/plain");
xhr.onload = () => {
var bin = atob(xhr.response);
var ab = s2ab(bin); // from example above
var blob = new Blob([ab], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;' });
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = 'demo.xlsx';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
};
xhr.send();
而且它对我非常有效。我的解决方案
步骤:1
<a onclick="exportAsExcel()">Export to excel</a>
步骤:3
let FileSaver = require('file-saver'); // path to file-saver
function exportAsExcel() {
let dataBlob = '...kAAAAFAAIcmtzaGVldHMvc2hlZXQxLnhtbFBLBQYAAAAACQAJAD8CAADdGAAAAAA='; // If have ; You should be split get blob data only
this.downloadFile(dataBlob);
}
function downloadFile(blobContent){
let blob = new Blob([base64toBlob(blobContent, 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')], {});
FileSaver.saveAs(blob, 'report.xlsx');
}
function base64toBlob(base64Data, contentType) {
contentType = contentType || '';
let sliceSize = 1024;
let byteCharacters = atob(base64Data);
let bytesLength = byteCharacters.length;
let slicesCount = Math.ceil(bytesLength / sliceSize);
let byteArrays = new Array(slicesCount);
for (let sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
let begin = sliceIndex * sliceSize;
let end = Math.min(begin + sliceSize, bytesLength);
let bytes = new Array(end - begin);
for (var offset = begin, i = 0; offset < end; ++i, ++offset) {
bytes[i] = byteCharacters[offset].charCodeAt(0);
}
byteArrays[sliceIndex] = new Uint8Array(bytes);
}
return new Blob(byteArrays, { type: contentType });
}
let FileSaver=require('file-saver');//文件保护程序的路径
函数exportAsExcel(){
让dataBlob='..kaaaafaaicmtzagvldhmvc2hlzxqxlnhtbfblbqyaaaaacqajad8caaddgaaaaa=';//如果有;您应该被拆分,只获取blob数据
此.downloadFile(dataBlob);
}
函数下载文件(blobContent){
设blob=newblob([base64toBlob(blobContent,'application/vnd.openxmlformats officedocument.spreadsheetml.sheet'),{});
FileSaver.saveAs(blob,'report.xlsx');
}
函数base64toBlob(base64Data,contentType){
contentType=contentType | |“”;
设切片大小为1024;
let byteCharacters=atob(base64Data);
让bytesLength=ByTechCharacters.length;
设slicescont=Math.ceil(bytesLength/sliceSize);
let byteArray=新阵列(切片扫描);
for(设sliceIndex=0;sliceIndex
为我工作^^ 这在以下情况下起作用:v0.14.0
下面是我使用fetchapi的实现。服务器端点发送一个字节流,客户端接收一个字节数组并从中创建一个blob。然后将生成一个.xlsx文件
return fetch(fullUrlEndpoint, options)
.then((res) => {
if (!res.ok) {
const responseStatusText = res.statusText
const errorMessage = `${responseStatusText}`
throw new Error(errorMessage);
}
return res.arrayBuffer();
})
.then((ab) => {
// BE endpoint sends a readable stream of bytes
const byteArray = new Uint8Array(ab);
const a = window.document.createElement('a');
a.href = window.URL.createObjectURL(
new Blob([byteArray], {
type:
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
}),
);
a.download = `${fileName}.XLSX`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
})
.catch(error => {
throw new Error('Error occurred:' + error);
});
我找到了一个适合我的解决方案:
const handleDownload = async () => {
const req = await axios({
method: "get",
url: `/companies/${company.id}/data`,
responseType: "blob",
});
var blob = new Blob([req.data], {
type: req.headers["content-type"],
});
const link = document.createElement("a");
link.href = window.URL.createObjectURL(blob);
link.download = `report_${new Date().getTime()}.xlsx`;
link.click();
};
我只指向一个响应类型:“blob”谢谢您的回复,但结果仍然是一样的。这似乎不适用于原始数据(即服务器按原样返回的excel文件)。事实上,“s”返回未定义的值。有什么线索吗?@Ron T什么是atob?@tjvg1991:是函数window.atob()。这里解释了它的含义和作用:谢谢你,大卫。我试图模拟上传的Excel文件进行测试,这使我能够让它工作。我不得不将类型改为“application/binary”,但在那之后它工作得非常好。最后,在一整天的搜索和尝试不同的解决方案之后。唯一能用fetch的东西。我想重点是在Unit8Array中,我必须探索并理解实际在做什么:)
/* generate array buffer */
var wbout = XLSX.write(wb, {type:"array", bookType:'xlsx'});
/* create data URL */
var url = URL.createObjectURL(new Blob([wbout], {type: 'application/octet-stream'}));
/* trigger download with chrome API */
chrome.downloads.download({ url: url, filename: "testsheet.xlsx", saveAs: true });
return fetch(fullUrlEndpoint, options)
.then((res) => {
if (!res.ok) {
const responseStatusText = res.statusText
const errorMessage = `${responseStatusText}`
throw new Error(errorMessage);
}
return res.arrayBuffer();
})
.then((ab) => {
// BE endpoint sends a readable stream of bytes
const byteArray = new Uint8Array(ab);
const a = window.document.createElement('a');
a.href = window.URL.createObjectURL(
new Blob([byteArray], {
type:
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
}),
);
a.download = `${fileName}.XLSX`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
})
.catch(error => {
throw new Error('Error occurred:' + error);
});
const handleDownload = async () => {
const req = await axios({
method: "get",
url: `/companies/${company.id}/data`,
responseType: "blob",
});
var blob = new Blob([req.data], {
type: req.headers["content-type"],
});
const link = document.createElement("a");
link.href = window.URL.createObjectURL(blob);
link.download = `report_${new Date().getTime()}.xlsx`;
link.click();
};