Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/475.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何将.xlsx数据保存为blob文件_Javascript_Xlsx_Bloburls - Fatal编程技术网

Javascript 如何将.xlsx数据保存为blob文件

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

我有一个与这个问题类似的问题()

我正在尝试保存excelbuilder.js的
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();
 };