javascript 使用指定的字符集下载 BLOB 内容

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18925210/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 13:42:05  来源:igfitidea点击:

Download BLOB content using specified charset

javascriptcharacter-encodingblob

提问by David Rodrigues

Is possible to change the Blob charset really? I'm trying it for hours but it doesn't workds. See this.

真的可以更改 Blob 字符集吗?我尝试了几个小时,但它不起作用。看到这个

jQuery("#download").click(function() {
    var csv_content = jQuery("#csv").val(),
        download = document.createElement("a"),
        blob = new Blob([csv_content], { type: "text/csv;charset=ISO-8859-1" });

    download.href = window.URL.createObjectURL(blob);
    download.download = "test.csv";

    var event = document.createEvent("MouseEvents");
    event.initMouseEvent(
        "click", true, false, window, 0, 0, 0, 0, 0
        , false, false, false, false, 0, null
    );
    download.dispatchEvent(event);    
});

I need export a CSV to open on Excel, but it always is save with UTF-8 and Excel can't handle it.

我需要导出一个 CSV 以在 Excel 上打开,但它总是用 UTF-8 保存,Excel 无法处理它。

回答by David Rodrigues

I found the solution before to post.

我在发布之前找到了解决方案。

The change of charset has not been resolved, in fact. However, I sent the UTF-8 header for the download process and Excel was able to understand the file format correctly. Thanks to this response of Erik T?yr?.

实际上,字符集的更改尚未解决。但是,我为下载过程发送了 UTF-8 标头,Excel 能够正确理解文件格式。感谢 Erik T?yr? .

blob = new Blob(["\ufeff", csv_content]);

回答by Adam Millerchip

In my case I was using Angular JS to receive an encoded CSV file from the server in response to an HTTP POST. The problem was that CSVs returned from XMLHttpRequests are represented as Unicode (I want to say UTF-8, but according to thisit is UTF-16) strings, not pre-encoded binary data. It looks like this is true in your example too, it is reading the CSV from a DOM element? In this case it ends up being represented as Unicode in memory, so it doesn't matter what value you set the encoding metadata to, the data is still Unicode.

就我而言,我使用 Angular JS 从服务器接收编码的 CSV 文件以响应 HTTP POST。问题是,从返回XMLHttpRequest的CSV格式被表示为Unicode(I想说UTF-8,但根据它是UTF-16)字符串,而不是预编码的二进制数据。在您的示例中看起来也是如此,它正在从 DOM 元素读取 CSV?在这种情况下,它最终在内存中表示为 Unicode,因此无论您将编码元数据设置为什么值,数据仍然是 Unicode。

My Angular code was doing something like this:

我的 Angular 代码正在做这样的事情:

$http.post('/url', postData, {}).then(handleResponse);

Inside handleResponse, the data was already represented in Unicode. According to Angular's $httpservice, not providing the responseTypeproperty on the config object causes it to default to string. Which according to Mozillaends up represented as a DOMStringin UTF-16, whereas we actually want it to be a Blob. Setting the responseTypeto blobon the config object successfully prevented the content from getting decoded. Without this, the response data was being inadvertently decoded before being placed into the Blob.

在 里面handleResponse,数据已经用 Unicode 表示了。根据 Angular 的$http服务,不提供responseTypeconfig 对象的属性会导致它默认为string. 这据Mozilla结束了表示为DOMString在UTF-16,而实际上我们希望它是一个斑点。在配置对象上设置responseTypetoblob成功阻止了内容被解码。如果没有这个,响应数据在被放入 Blob 之前会被无意中解码。

$http.post('/url', postData, {responseType: 'blob'}).then(handleResponse);

I then used saveAs()to get the browser to provide the file contents to the user.

然后我使用saveAs()让浏览器向用户提供文件内容。

function handleResponse(response) {
    let headers = response.headers();
    let blob = new Blob([response.data], {type: headers['content-type']});
    saveAs(blob, headers['x-filename']);
}

I got the idea to set responseTypefrom https://stackoverflow.com/a/16791296/1225617

responseTypehttps://stackoverflow.com/a/16791296/1225617得到了设置的想法

回答by Diwakar

If you have some symbols in the csv and the accepted solution is not solving the problem:

如果您在 csv 中有一些符号并且接受的解决方案不能解决问题:

blob = new Blob(["\ufeff", csv_content]);
// for csv_content you can try like below.
function b64DecodeUnicode(str: any) {        
        return decodeURIComponent(atob(str).split('').map((c: any) => {
            return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
        }).join(''));
    }

回答by Sunali Bandara

  const blob = new Blob([csvData], { type: 'text/csv;charset=utf-8;' });
    if (navigator.msSaveBlob) { // IE 10+
      navigator.msSaveBlob(blob, filename);
    } else {
      const link = document.createElement('a');
      if (link.download !== undefined) {
        // Browsers that support HTML5 download attribute
        const url = URL.createObjectURL(blob);
        link.setAttribute('href', url);
        link.setAttribute('download', filename);
        link.style.visibility = 'hidden';
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
      }
    }

this worked for csv export with excel format in vuejs.

这适用于vuejs 中excel 格式的 csv 导出。