16

我正在尝试使用 javascript 在客户端生成一个 CSV 文件。我已经关注了这个 stackoverflow question 的答案。我的内容中有 unicode 字符(在我的例子中是希伯来字符)。

文件生成成功,但是当我在 Excel 中打开文件时 - 所有 unicode 字符都显示为有趣的字符。ASCII 字符(英文和数字)呈现良好。

奇怪的是,如果我在记事本中打开文件,unicode 字符显示得很好。所以我想这与 Excel 以及我保存文件的方式有关。

有任何想法吗?

4

3 回答 3

38

在 Jack Cole 的评论和这个问题之后,解决我的问题是\uFEFF在文件开头添加 BOM 前缀 ()。

这是工作代码:

var csvContent = "...csv content...";
var encodedUri = encodeURI(csvContent);
var link = document.createElement("a");
link.setAttribute("href", "data:text/csv;charset=utf-8,\uFEFF" + encodedUri);
link.setAttribute("download","report.csv");
link.click();
于 2013-08-15T10:57:04.573 回答
4

建议的解决方案不适用于所有浏览器,但我找到了一种方法让它在所有浏览器(Chrome、Firefox、IE11 甚至 Edge,...不知道 IE9-10,因为我没有不再访问它们)。

我必须使用外部库对encoding.js 进行编码,它与 unicode 配合得非常好(我可以在 Excel 中的 CSV 导出中看到我的独角兽表情符号)。

所以这是代码

data = new TextEncoder('utf-16be').encode(csvContent);

// create a Blob object for the download
const blob = new Blob(['\uFEFF', data], {
  type: 'text/csv;charset=utf-8';
});

// when using IE/Edge, then use different download call
if (typeof navigator.msSaveOrOpenBlob === 'function') {
  navigator.msSaveOrOpenBlob(blob, filename);
} else {
  // this trick will generate a temp <a /> tag that you can trigger a hidden click for it to start downloading
  const link = document.createElement('a');
  const csvUrl = URL.createObjectURL(blob);

  link.textContent = 'download';
  link.href = csvUrl;
  link.setAttribute('download', filename);

  // set the visibility hidden so there is no effect on your web-layout
  link.style.visibility = 'hidden';

  // this part will append the anchor tag and remove it after automatic click
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
}

就是这样,它适用于IE / Edge / Chrome / Firefox

在此处输入图像描述

于 2018-02-16T00:25:51.617 回答
3

在 Node/Express 服务器上,我尝试了 Shay 的回答,但我的标题中出现了无效字符错误。相反,我\uFEFF在回复正文的开头添加了它,它起作用了。

app.get('/', function (req, res) {
    var csv = Papa.unparse(...);
    res.set({
       'Content-Type': 'text/csv; charset=UTF-8',
       'Content-Disposition': 'attachment; filename="file.csv"',
    });
    res.send('\uFEFF' + csv)
})
于 2016-12-08T16:54:43.310 回答