Javascript 到 csv 导出编码问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19492846/
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
Javascript to csv export encoding issue
提问by Boltosaurus
I need to export javascript array to excel file and download it I'm doing it in this code. data is a javascript object array.
我需要将 javascript 数组导出到 excel 文件并下载它我正在此代码中执行此操作。数据是一个javascript对象数组。
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();
All this stuff works fine till I have string properties that have non-english characters, like spanish, arabic or hebrew. How can I make an export with all this non-ASCII values?
所有这些东西都可以正常工作,直到我拥有包含非英语字符(如西班牙语、阿拉伯语或希伯来语)的字符串属性。如何使用所有这些非 ASCII 值进行导出?
回答by Gerg? Nagy
You should add the UTF-8 BOM at the start of the text, like:
您应该在文本的开头添加 UTF-8 BOM,例如:
var csvContent = "data:text/csv;charset=utf-8,%EF%BB%BF";
It worked for me with Excel 2013.
它在 Excel 2013 中对我有用。
回答by Marcelo Lujan
You can add the BOM at first, use this code and try
您可以首先添加 BOM,使用此代码并尝试
var BOM = "\uFEFF";
var csvContent = BOM + csvContent;
and then crate the file headers with the data: "text/csv;charset=utf-8"
然后用数据创建文件头:“text/csv;charset=utf-8”
回答by b4stien
Excel is really bad at detecting encoding, especially Excel on OSX.
Excel 在检测编码方面非常糟糕,尤其是 OSX 上的 Excel。
The best solution would be to encode your CSV in the default Excel encoding: windows-1252 (also called ANSI, which is basically a subset of ISO-8859-1).
最好的解决方案是使用默认的 Excel 编码对 CSV 进行编码:windows-1252(也称为 ANSI,基本上是 ISO-8859-1 的子集)。
I put a complete example of how to do that at: https://github.com/b4stien/js-csv-encoding.
我在https://github.com/b4stien/js-csv-encoding 上放了一个完整的例子来说明如何做到这一点。
The 2 main parts are stringencoding(to encode the content of your CSV in windows-1252) and FileSaver.js(to download the generated Blob).
两个主要部分是stringencoding(在 windows-1252 中对 CSV 的内容进行编码)和FileSaver.js(下载生成的 Blob)。
It looks like:
看起来像:
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');
回答by Moshe Simantov
Option 1
选项1
use iconv-lite
library and encode your output to ascii before send it back to the user.
Example:
使用iconv-lite
library 并将您的输出编码为 ascii,然后再将其发送回用户。例子:
var iconv = require('iconv-lite');
buf = iconv.encode(str, 'win1255'); // return buffer with windows-1255 encoding
Option 2
选项 2
Write on the head of the file the BOM header of UTF-8 encoding. Example:
在文件头部写入UTF-8编码的BOM头。例子:
res.header('Content-type', 'text/csv; charset=utf-8');
res.header('Content-disposition', 'attachment; filename=excel.csv');
res.write(Buffer.from('EFBBBF', 'hex')); // BOM header
// rest of your code
Option 3
选项 3
Use base64 url format like data:text/csv;base64,77u/Zm9vLGJhcg0KYWFhLGJiYg==
. This method will work on client-side also (IE10+, FF, Chrome, Opera, Safari).
使用 base64 url 格式,如data:text/csv;base64,77u/Zm9vLGJhcg0KYWFhLGJiYg==
. 此方法也适用于客户端(IE10+、FF、Chrome、Opera、Safari)。
For example:
例如:
window.location = "data:text/csv;base64,77u/" + btoa("foo,bar\r\naaa,bbb");
回答by gjchen
somehow found Tab-Separated-CSV with utf-16le encoding with BOM works on WIN/MAC Excel
不知何故发现带有 utf-16le 编码和 BOM 的 Tab-Separated-CSV 在 WIN/MAC Excel 上工作
followed b4stien's answer but make a little difference to archive:
遵循 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');
with Linux /usr/bin/file tests:
使用 Linux /usr/bin/file 测试:
Little-endian UTF-16 Unicode text, with very long lines, with CRLF line terminators
回答by Didier68
B4stien, thank you to you for your answer! After testing several solutions based on charset "utf8", encoding windows-1252 is the only solution that allowed me to keep my accent in Excel 365!
B4stien,谢谢你的回答!在测试了几种基于字符集“utf8”的解决方案后,编码 windows-1252 是唯一能让我在 Excel 365 中保持口音的解决方案!
Manetsus, the b4stien's answer and his link were very usefull for my case: i have to export french and german data into csv file: no solution based on "utf8" has worked... Only his solution which use an "ANSI" (window-1252) encoder...
Manetsus,b4stien 的回答和他的链接对我的情况非常有用:我必须将法语和德语数据导出到 csv 文件中:没有基于“utf8”的解决方案有效......只有他的解决方案使用“ANSI”(窗口-1252) 编码器...
I give his code sample, and you can download the depending encoding-indexes.js, encoding.js and FileSaver.js from the link...
我给出了他的代码示例,您可以从链接下载依赖的 encoding-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>
Nevertheless, as Excel is relatively open in the support of languages and formats, I do not exclude that UTF8 is not supported in my development environment because of the way it is installed ...
尽管如此,由于Excel在语言和格式的支持上相对开放,我不排除我的开发环境不支持UTF8,因为它的安装方式......
Note: I test it with Firefox, Chrome and IE 11 on windows 7, with Excel 365...
注意:我在 Windows 7 上使用 Firefox、Chrome 和 IE 11 以及 Excel 365 对其进行了测试...
回答by mikaelfs
To export CSV containing multibyte characters and make it readable on text editor and Excel in multiple OS platforms (Windows, Linux, MacOS), the following rules should be applied:
要导出包含多字节字符的 CSV 并使其在多个操作系统平台(Windows、Linux、MacOS)中的文本编辑器和 Excel 上可读,应应用以下规则:
- Separate the field with tab instead of comma (so that Excel on MacOS can properly display the generated CSV file)
- Encode the string / content with UTF-16 little endian (UTF16-LE) instead of UTF-8
- Add byte order mark (BOM) 0xFEFF as specified in RFC2781 section 3.2 at the beginning of the serialized stream to explicitly provide "signature" of content encoded with UTF16-LE
- 用制表符而不是逗号分隔字段(以便 MacOS 上的 Excel 可以正确显示生成的 CSV 文件)
- 使用 UTF-16 little endian (UTF16-LE) 而不是 UTF-8 对字符串/内容进行编码
- 在序列化流的开头添加 RFC2781 第 3.2 节中指定的字节顺序标记 (BOM) 0xFEFF,以明确提供使用 UTF16-LE 编码的内容的“签名”
Further elaboration, use cases and sample code with NodeJS can be seen in this article.
在这篇文章中可以看到 NodeJS 的进一步阐述、用例和示例代码。