我们有一个 Web 应用程序,可以导出包含 UTF-8 外来字符的 CSV 文件,没有 BOM。 Windows 和 Mac 用户在 Excel 中都会得到乱码。我尝试使用 BOM 转换为 UTF-8; Excel/Win 没问题,Excel/Mac 显示乱码。我正在使用 Excel 2003/Win、Excel 2011/Mac。这是我尝试过的所有编码:
Encoding BOM Win Mac
-------- --- ---------------------------- ------------
utf-8 -- scrambled scrambled
utf-8 BOM WORKS scrambled
utf-16 -- file not recognized file not recognized
utf-16 BOM file not recognized Chinese gibberish
utf-16LE -- file not recognized file not recognized
utf-16LE BOM characters OK, same as Win
row data all in first field
最好的一个是带有 BOM 的 UTF-16LE,但 CSV 不被识别。字段分隔符是逗号,但分号不会改变事情。
是否有任何编码适用于这两个世界?
mb_convert_encoding($str, "UTF-16LE");
在我的导出代码中并在此处发布结果。
Excel 编码
我发现 WINDOWS-1252
编码在处理 Excel 时最不令人沮丧。由于它基本上是微软自己的专有字符集,因此可以假设它可以在 Mac 和 Windows 版本的 MS-Excel 上运行。两个版本都至少包含一个相应的“文件来源”或“文件编码”选择器,可以正确读取数据。
根据您的系统和您使用的工具,此编码还可以命名为 CP1252
、ANSI
、Windows (ANSI)
、MS-ANSI
或仅命名为 Windows
,以及其他变体。
此编码是 ISO-8859-1
(又名 LATIN1
和其他)的超集,因此如果由于某种原因无法使用 WINDOWS-1252
,您可以回退到 ISO-8859-1
。请注意,ISO-8859-1
缺少 WINDOWS-1252
中的一些字符,如下所示:
| Char | ANSI | Unicode | ANSI Hex | Unicode Hex | HTML entity | Unicode Name | Unicode Range |
| € | 128 | 8364 | 0x80 | U+20AC | € | euro sign | Currency Symbols |
| ‚ | 130 | 8218 | 0x82 | U+201A | ‚ | single low-9 quotation mark | General Punctuation |
| ƒ | 131 | 402 | 0x83 | U+0192 | ƒ | Latin small letter f with hook | Latin Extended-B |
| „ | 132 | 8222 | 0x84 | U+201E | „ | double low-9 quotation mark | General Punctuation |
| … | 133 | 8230 | 0x85 | U+2026 | … | horizontal ellipsis | General Punctuation |
| † | 134 | 8224 | 0x86 | U+2020 | † | dagger | General Punctuation |
| ‡ | 135 | 8225 | 0x87 | U+2021 | ‡ | double dagger | General Punctuation |
| ˆ | 136 | 710 | 0x88 | U+02C6 | ˆ | modifier letter circumflex accent | Spacing Modifier Letters |
| ‰ | 137 | 8240 | 0x89 | U+2030 | ‰ | per mille sign | General Punctuation |
| Š | 138 | 352 | 0x8A | U+0160 | Š | Latin capital letter S with caron | Latin Extended-A |
| ‹ | 139 | 8249 | 0x8B | U+2039 | ‹ | single left-pointing angle quotation mark | General Punctuation |
| Œ | 140 | 338 | 0x8C | U+0152 | Œ | Latin capital ligature OE | Latin Extended-A |
| Ž | 142 | 381 | 0x8E | U+017D | | Latin capital letter Z with caron | Latin Extended-A |
| ‘ | 145 | 8216 | 0x91 | U+2018 | ‘ | left single quotation mark | General Punctuation |
| ’ | 146 | 8217 | 0x92 | U+2019 | ’ | right single quotation mark | General Punctuation |
| “ | 147 | 8220 | 0x93 | U+201C | “ | left double quotation mark | General Punctuation |
| ” | 148 | 8221 | 0x94 | U+201D | ” | right double quotation mark | General Punctuation |
| • | 149 | 8226 | 0x95 | U+2022 | • | bullet | General Punctuation |
| – | 150 | 8211 | 0x96 | U+2013 | – | en dash | General Punctuation |
| — | 151 | 8212 | 0x97 | U+2014 | — | em dash | General Punctuation |
| ˜ | 152 | 732 | 0x98 | U+02DC | ˜ | small tilde | Spacing Modifier Letters |
| ™ | 153 | 8482 | 0x99 | U+2122 | ™ | trade mark sign | Letterlike Symbols |
| š | 154 | 353 | 0x9A | U+0161 | š | Latin small letter s with caron | Latin Extended-A |
| › | 155 | 8250 | 0x9B | U+203A | › | single right-pointing angle quotation mark | General Punctuation |
| œ | 156 | 339 | 0x9C | U+0153 | œ | Latin small ligature oe | Latin Extended-A |
| ž | 158 | 382 | 0x9E | U+017E | | Latin small letter z with caron | Latin Extended-A |
| Ÿ | 159 | 376 | 0x9F | U+0178 | Ÿ | Latin capital letter Y with diaeresis | Latin Extended-A |
请注意,缺少欧元符号。此表可在 Alan Wood 中找到。
转换
每种工具和语言的转换方式都不同。但是,假设您有一个文件 query_result.csv
,您知道该文件是 UTF-8
编码的。使用 iconv
将其转换为 WINDOWS-1252
:
iconv -f UTF-8 -t WINDOWS-1252 query_result.csv > query_result-win.csv
对于带有 BOM 的 UTF-16LE,如果您使用制表符而不是逗号作为分隔符,Excel 将识别这些字段。它起作用的原因是 Excel 实际上最终使用了它的 Unicode *.txt 解析器。
警告:如果文件在 Excel 中编辑并保存,它将被保存为制表符分隔的 ASCII。现在的问题是,当您重新打开文件时,Excel 假定它是真正的 CSV(带逗号),发现它不是 Unicode,因此将其解析为逗号分隔 - 因此会对它进行哈希处理!
更新: 至少今天在 Excel 2010 (Windows) 中,上述警告似乎没有发生在我身上,尽管在以下情况下保存行为似乎有所不同:
您编辑并退出 Excel(尝试另存为 'Unicode *.txt')
相比:
仅编辑和关闭文件(按预期工作)。
sep=,
和 UTF16LE 编码对我有用,不需要不同的分隔符(它仍然是逗号)。通过双击打开文件正确加载了文件,单元格内的特殊字符和换行符完好无损。缺点:据我所知,除了 Excel 之外,任何程序都无法识别 sep=,
标头。但是 OpenOffice / LibreOffice 无论如何都不需要这种 hack(单元格内容中的换行符工作得很好,而从文本文件加载/使用文本到 Excel 中的列助手不能正确处理单元格中的换行符)。
内幕是:没有解决方案。 Excel 2011/Mac 无法正确解释包含变音符号和变音符号的 CSV 文件,无论您执行何种编码或跳圈。我很高兴听到有人告诉我不同的!
您只尝试过逗号分隔和分号分隔的 CSV。如果您尝试过制表符分隔的 CSV(也称为 TSV),您会找到答案:
带有 BOM(字节顺序标记)的 UTF-16LE,制表符分隔
但是:在评论中,您提到 TSV 不适合您(尽管我无法在您的问题中找到此要求)。这真遗憾。这通常意味着您允许手动编辑 TSV 文件,这可能不是一个好主意。 TSV 文件的目视检查不是问题。此外,可以将编辑器设置为显示特殊字符来标记选项卡。
是的,我在 Windows 和 Mac 上试过了。
这是将 utf8 编码的 CSV 导入 Excel 2011 for Mac 的关键:微软说:“Excel for Mac 目前不支持 UTF-8。” Excel for Mac 2011 and UTF-8
是的,去MS的路!
在 Mac 上使用 UTF-8 读取 CSV 文件的最佳解决方法是将它们转换为 XLSX 格式。我找到了一个由 Konrad Foerstner 制作的脚本,我通过添加对不同分隔符的支持对其进行了一些改进。
从 Github https://github.com/brablc/clit/blob/master/csv2xlsx.py 下载脚本。为了运行它,您需要为 Excel 文件操作安装一个 python 模块 openpyxl:sudo easy_install openpyxl
。
在我的情况下,这有效(Mac,Excel 2011,带有捷克变音符号的西里尔字母和拉丁字符):
字符集 UTF-16LE(仅 UTF-16 还不够)
物料清单“\xFF\xFE”
\t(制表符)作为分隔符
不要忘记对分隔符和 CRLF 进行编码 :-)
使用 iconv 而不是 mb_convert_encoding
在我看来,Mac OS 的 Excel 2011 没有像我想的那样使用 Encoding.GetEncoding("10000") 并且浪费了 2 天时间,但与 Microsoft OS 上的 iso 相同。最好的证明是在 Excel 2011 for MAC 中制作一个带有特殊字符的文件,将其另存为 CSV,然后在 MAC 文本编辑器中打开它,字符就会被打乱。
对我来说,这种方法有效 - 这意味着 MAC OS 上 Excel 2011 上的 csv 导出内部具有特殊的西欧字符:
Encoding isoMacOS = Encoding.GetEncoding("iso-8859-1");
Encoding defaultEncoding = Encoding.Default;
// Convert the string into a byte array.
byte[] defaultEncodingBytes = defaultEncoding.GetBytes(exportText);
// Perform the conversion from one encoding to the other.
byte[] ansiBytes = Encoding.Convert(defaultEncoding, isoMacOS, defaultEncodingBytes);
decodedString = isoMacOS.GetString(ansiBytes);
没有 BOM 的 UTF-8 目前在 Excel Mac 2011 14.3.2 中适用于我。
UTF-8 + BOM 有点工作,但 BOM 呈现为乱码。
如果您导入文件并完成向导,则 UTF-16 有效,但如果您只是双击它,则无效。
以下在 Excel for Mac 2011 和 Windows Excel 2002 上对我有用:
在 Mac 上使用 iconv,将文件转换为 UTF-16 Little-Endian + 将其命名为 *.txt(.txt 扩展名强制 Excel 运行文本导入向导): iconv -f UTF-8 -t UTF-16LE filename.csv >filename_UTF-16LE.csv.txt 在 Excel 中打开文件并在文本导入向导中选择: 第 1 步:文件来源:忽略它,无论您选择什么第 2 步:为分隔符和文本限定符选择适当的值 步骤3:如有必要,选择列格式
PS iconv 创建的 UTF-16LE 开头有 BOM 字节 FF FE。
PPS 我的原始 csv 文件是在 Windows 7 计算机上创建的,采用 UTF-8 格式(开头是 BOM 字节 EF BB BF)并使用了 CRLF 换行符。逗号用作字段分隔符,单引号用作文本限定符。它包含 ASCII 字母以及带有波浪线、变音符号等的不同拉丁字母,以及一些西里尔字母。所有都在 Excel for Win 和 Mac 中正确显示。
PPPS 确切的软件版本:* Mac OS X 10.6.8 * Excel for Mac 2011 v.14.1.3 * Windows Server 2003 SP2 * Windows Excel 2002 v.10.2701.2625
在我的 Mac OS 上,Text Wrangler 将使用 Excel 创建的 CSV 文件识别为具有“西方”编码。
经过一番谷歌搜索后,我制作了这个小脚本(我不确定 Windows 的可用性,也许是 Cygwin?):
$ cat /usr/local/bin/utf8.sh
#!/bin/bash
INPUTFILE="$1"
iconv -f macroman -c -t UTF-8 $INPUTFILE |tr '\r' '\n' >/tmp/file.$$.csv
mv $INPUTFILE ms_trash
mv /tmp/file.$$.csv $INPUTFILE
在我的情况下,将 Preamble 添加到文件解决了我的问题:
var data = Encoding.UTF8.GetBytes(csv);
var result = Encoding.UTF8.GetPreamble().Concat(data).ToArray();
return File(new MemoryStream(result), "application/octet-stream", "data.csv");
而不是 csv,尝试输出带有 XLS 扩展名和“application/excel”mime 类型的 html。我知道这适用于 Windows,但不能代表 MacOS
br
标记),Excel for Mac 会忽略(适用于 Windows)CSS mso-data-placement:same-cell;
这对我有用
在 BBEdit 或 TextWrangler* 中打开文件。将文件设置为 Unicode (UTF-16 Little-Endian)(行结尾可以是 Unix 或 Windows)。节省!在 Excel 中:数据 > 获取外部数据 > 导入文本文件...
现在关键点,选择 MacIntosh 作为 File Origin(应该是首选)。
这是使用 Excel 2011(版本 14.4.2)
*窗口底部有一个小下拉菜单
使用 java ( UTF-16LE 和 BOM ) 解决这个问题:
String csvReportStr = getCsvReport();
byte[] data = Charset.forName("UTF-16LE").encode(csvReportStr)
.put(0, (byte) 0xFF)
.put(1, (byte) 0xFE)
.array();
请注意,CSV 文件应使用 TAB
作为分隔符。您可以在 Windows 和 MAC OS X 上读取 CSV 文件。
参考:How do I encode/decode UTF-16LE byte arrays with a BOM?
WINDOS-1252
,Mac 和 Windows Excel 很可能都能正确解释它。