在Javascript中保存base64数据中的二进制文件

时间:2018-02-16 23:58:18

标签: javascript

我正在尝试使用javascript下载xlsx电子表格。我测试了base64数据。我像这样解码它:

var data = atob(validBase64Data);

之后,我这样做:

save(name, data, type) {
  const blob = new Blob([data], {type: type});
  let objectURL = window.URL.createObjectURL(blob);
  let anchor = document.createElement('a');

  anchor.href = objectURL;
  anchor.download = name;
  anchor.click();

  URL.revokeObjectURL(objectURL);
}

其中name是filename.xlsx,data是解码数据,type是mime类型字符串。

excel文件已下载但不会以excel格式打开。数据以某种方式被破坏。

另外:我使用unix终端命令测试相同的数据到base64解码并将xlsx直接写入该文件,并生成工作文件。测试是这样完成的:

  1. 我将base64数据保存到test_excel.txt`
  2. Ran命令base64 -D -i test_excel.txt -o test_excel.xlsx
  3. test_excel.xlsx由excel识别。
  4. 我的代码出了什么问题?

2 个答案:

答案 0 :(得分:1)

好的,所以,在任何人试图“错误地”解释问题之前,先澄清一些事情。

原始.xlsx是二进制编码文件,这意味着数据将包含0x000xFF的完整范围内的字节。

在问题中,假设此字符串已成功编码为有效的base64字符串,没有无关的字符(如使用base64的测试成功所示-i标志),并存储到validBase64Data

问题是atob(validBase64Data)生成一个解码为utf-8的字符串,而不是二进制。正如我之前所说,原始二进制字符串包含0x800xFF范围内的非ASCII字节。在utf-8中,这些代码点存储为两个字节而不是一个,因此Creating a Blob from a base64 string in JavaScript中描述的解决方案是转换utf-8字符串data中每个字符的代码点。存储为Uint8Array的字节,然后从中构造Blob

一个天真的解决方案可能看起来像这样,但请参考Creating a Blob from a base64 string in JavaScript以获得更高效的解决方案:

const blob = new Blob([Uint8Array.from(data, c => c.charCodeAt(0))], { type });
//...

这使用TypedArray.from(iterable, mapFn)

答案 1 :(得分:0)

以下是解决它的代码:

export default {
 save(name, data, type, isBinary) {
  if (isBinary) {
    var bytes = new Array(data.length);
    for (var i = 0; i < data.length; i++) {
        bytes[i] = data.charCodeAt(i);
    }
    data = new Uint8Array(bytes);
  }

  var blob = new Blob([data], {type: type});
  let objectURL = window.URL.createObjectURL(blob);
  let anchor = document.createElement('a');

  anchor.href = objectURL;
  anchor.download = name;
  anchor.click();

  URL.revokeObjectURL(objectURL);
 }
}

感谢所有参与解决的人。 此外,还可以获得:Creating a Blob from a base64 string in JavaScript