2013-10-21 435 views
38

我需要出口的JavaScript数组excel文件并下载我做这个代码。数据是一个JavaScript对象数组。的Javascript导出为CSV编码问题

var csvContent = "data:text/csv;charset=utf-8,"; 
data.forEach(function(dataMember, index) 
{ 
    dataString = dataMember.join(","); 
    csvContent += index < data.length ? dataString+ "\n" : dataString; 
}); 

var encodedUri = encodeURI(csvContent); 
var link = document.createElement("a"); 
link.setAttribute("href", encodedUri); 
link.setAttribute("download", "upload_data" + (new Date()).getTime() + ".csv"); 
link.click(); 

所有这些东西工作正常,直到我有字符串属性具有非英文字符,如西班牙语,阿拉伯语或希伯来语。我怎样才能让这一切的非ASCII值的出口?

+0

第一行说明utf-8,这是ASCII。也许如果你把它改为16这可能会使用unicode? – rfcoder89

+0

我改变了。同样的事情( – Boltosaurus

+0

@Boltosaurus,我在这里创建了一个演示:http://jsfiddle.net/8qPur/。它对我来说看起来没问题:下载的文件有特殊字符编码正确 –

回答

3

选项1个

使用iconv-lite库和编码您的输出为ASCII之前发回给用户。 实施例:

var iconv = require('iconv-lite'); 
buf = iconv.encode(str, 'win1255'); // return buffer with windows-1255 encoding 

选项2

写在文件上的UTF-8编码的BOM报头的头部。 实施例:

res.header('Content-type', 'text/csv; charset=utf-8'); 
res.header('Content-disposition', 'attachment; filename=excel.csv'); 
res.write(new Buffer('EFBBBF', 'hex')); // BOM header 

// rest of your code 

选项3

使用的base64 URL格式等data:text/csv;base64,77u/Zm9vLGJhcg0KYWFhLGJiYg==。此方法将在客户端的工作也(IE10 +,FF,铬,歌剧,Safari浏览器)。

例如:

window.location = "data:text/csv;base64,77u/" + btoa("foo,bar\r\naaa,bbb"); 
+0

嘿,谢谢你的回复。请问你可以举一个完整的例子2吗?究竟是什么.header()方法?什么是res对象? – Boltosaurus

+0

我正在使用[express.js] (http://expressjs.com)框架 在平面node.js上,您可以使用[setHeader](http://nodejs.org/api/http.html#http_response_setheader_name_value)。 –

+1

我不是在谈论节点。我使用纯粹的客户端JavaScript) – Boltosaurus

58

你应该添加UTF-8 BOM在文本的开始,如:

var csvContent = "data:text/csv;charset=utf-8,%EF%BB%BF"; 

它的工作,我用Excel 2013年

Demo Fiddle

+0

你可以在jsFiddle中提供一个完整的工作示例吗? – jlarson

+2

@jlarson here你是:[链接](http://jsfiddle.net/W432s/) 我使用了Benoit Blanchon的演示。 –

+1

在Mac上,我最终得到了这个:(https://www.dropbox。com/s/a36t99fvo43xhfe/Screen%20Shot%202014-03-04%20at%209.31.48%20 AM.png – jlarson

14

Excel是真的检测编码不好,特别是OSX上的Excel。

最好的解决办法是编码您的CSV在Excel的默认编码方式:windows-1252(也称为ANSI,这基本上是ISO-8859-1的子集)。

我把如何做到这一点,在一个完整的例子:https://github.com/b4stien/js-csv-encoding

2个主要部分是stringencoding(用于在Windows-1252中编码CSV的内容)和FileSaver.js(用于下载生成的Blob)。

它看起来像:

var csvContent = 'éà; ça; 12\nà@€; çï; 13', 
    textEncoder = new TextEncoder('windows-1252'); 


var csvContentEncoded = textEncoder.encode([csvContent]); 
var blob = new Blob([csvContentEncoded], {type: 'text/csv;charset=windows-1252;'}); 
saveAs(blob, 'some-data.csv'); 
+0

有史以来最佳答案!!!!也很棒的组件!完美地工作! – Vackup

+0

非常感谢!通过大量的SO页面和文档寻找一些东西来解决问题,在打开EXCEL并破坏CSV后,将它们保存在OSX上。这是唯一有效的工作。 –

+1

注意''TextEncoder'现在不再接受除utf-8以外的任何编码。 – tsh

1

莫名其妙地发现制表符分隔-CSV使用UTF-16LE编码,BOM工作在WIN/MAC的Excel

其次b4stien的答案,但要有点差别归档:

var csvContent = 'éà; ça; 12\nà@€; çï; 13', 
    textEncoder = new TextEncoder('utf-16le'); 
var csvContentEncoded = textEncoder.encode([csvContent]); 
var bom = new Uint8Array([0xFF, 0xFE]); 
var out = new Uint8Array(bom.byteLength + csvContentEncoded.byteLength); 
out.set(bom , 0); 
out.set(csvContentEncoded, bom.byteLength); 
var blob = new Blob([out]); 
saveAs(blob, 'some-data.csv'); 

使用Linux的/ usr/bin中/文件测试:

Little-endian UTF-16 Unicode text, with very long lines, with CRLF line terminators 
0

B4stien,谢谢你的回答! 在测试了几个基于字符集“utf8”的解决方案之后,编码windows-1252是唯一允许我在Excel 365中保留口音的解决方案!

Manetsus,b4stien的答案和他的链接对我的情况非常有用:我必须将法语和德语数据导出到csv文件中:没有基于“utf8”的解决方案工作......只有他的解决方案使用“ ANSI”(窗口-1252)编码器...

我给他的代码示例,您可以从链接下载取决于编码indexes.js,encoding.js和FileSaver.js ...

<!doctype html> 
    <html> 

    <head> 
     <meta charset="utf-8"> 
     <script type="text/javascript" src="encoding-indexes.js"></script> 
     <script type="text/javascript" src="encoding.js"></script> 
     <script type="text/javascript" src="FileSaver.js"></script> 
    </head> 

    <body> 
     <a href="#" id="download-csv">Click me to download a valid CSV !</a> 

     <script type="text/javascript"> 
      var csvContent = 'éà; ça; 12\nà@€; çï; 13', 
       textEncoder = new CustomTextEncoder('windows-1252', {NONSTANDARD_allowLegacyEncoding: true}), 
       fileName = 'some-data.csv'; 

      var a = document.getElementById('download-csv'); 
      a.addEventListener('click', function(e) { 
       var csvContentEncoded = textEncoder.encode([csvContent]); 
       var blob = new Blob([csvContentEncoded], {type: 'text/csv;charset=windows-1252;'}); 
       saveAs(blob, fileName); 
       e.preventDefault(); 
      }); 
     </script> 
    </body> 

    </html> 
尽管如此,由于Excel在支持语言和格式方面相对开放,所以我并不排除UTF8在我的开发环境中不受支持,因为它的方式不同安装...

注:我使用Firefox,Chrome和Windows 7上,用Excel 365 IE 11测试...

36

您可以先添加BOM,使用此代码,并尝试

var BOM = "\uFEFF"; 
var csvContent = BOM + csvContent; 

然后用数据打包文件标题:“text/csv; charset = utf-8”

+0

这个!永远找到可以发挥作用的东西。谢谢! – KyleFarris

+0

这对我来说,当我的东西转换为一个blob,然后使用锚点标签单击hack触发下载: 'var downloadLink = document.createElement(“a”); downloadLink.download = fileNameToSaveAs; downloadLink.href = window.URL.createObjectURL(textFileAsBlob); downloadLink.onclick = function(e){document.body.removeChild(e.target); }; downloadLink.style.display =“none”; document.body.appendChild(downloadLink); downloadLink.click();' – skrile

+0

Excel现在正确显示了像'ář'这样的Unicode字符。谢谢 – Karthik