在 Mac 和 Windows 上,哪种编码能够用 Excel 正确地打开 CSV 文件?

我们有一个网络应用程序,导出 CSV 文件包含 UTF-8的外国字符,没有 BOM。Windows 和 Mac 用户都在 Excel 中获取垃圾字符。我试着用 BOM 转换成 UTF-8; Excel/Win 可以,Excel/Mac 显示的是胡言乱语。我使用的是 Excel2003/Win,Excel2011/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 不能被认为是这样的。字段分隔符是逗号,但分号不会改变内容。

有没有什么编码可以同时在两个世界中工作?

166683 次浏览

代替 csv,尝试用 XLS 扩展名和“ application/excel”mime-type 输出 html。我知道这在 Windows 上可行,但不能代表 MacOS

在我看来,用于 Mac OS 的 Excel2011没有使用编码。GetEncoding (“10000”)正如我想的那样,浪费了两天时间,但是和微软操作系统上的 ISO 是一样的。 最好的证明就是在 Excel2011中为 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-16LE,如果使用制表符作为分隔符而不是逗号,Excel 将识别字段。它工作的原因是 Excel 实际上最终使用它的 Unicode * 。Txt 解析器。

警告 : 如果文件在 Excel 中编辑并保存,它将被保存为以制表符分隔的 ASCII。现在的问题是,当您重新打开该文件时,Excel 假定它是真正的 CSV (带有逗号) ,看到它不是 Unicode,因此将其解析为逗号分隔的文件,因此将对其进行散列处理!

更新 : 至少在今天的 Excel2010(Windows)中,我似乎没有遇到上述警告,尽管在以下情况下保存行为似乎有所不同:

  • 编辑并退出 Excel (尝试保存为“ Unicode * . txt”)

相比之下:

  • 编辑和关闭 只有文件(按预期工作)。

真相是: 没有解决办法。Excel2011/Mac 不能正确解释包含变音符号和发音符号的 CSV 文件,无论您进行什么编码或跳箍。我很高兴听到有人告诉我不同的!

下面是关于将 UTf8编码的 CSV 导入到用于 Mac 的 Excel 2011的决定性因素: Microsoft 说: “ Excel for Mac 目前不支持 UTF-8。”用于 Mac 2011和 UTF-8的 Excel

好样的,多发性硬化症!

没有 BOM 的 UTF-8目前可以在 Excel Mac 201114.3.2中使用。

UTF-8 + BOM 类型的工程,但 BOM 呈现为胡言乱语。

如果导入文件并完成向导,则 UTF-16可以工作,但如果只是双击该向导,则无法工作。

在 Mac 上读取具有 UTF-8的 CSV 文件的最佳解决方案是将它们转换为 XLSX 格式。我发现了一个由 Konrad Foerstner 编写的脚本,通过添加对不同分隔符的支持,我对它进行了一些改进。

从 Githubhttps://github.com/brablc/clit/blob/master/csv2xlsx.py下载脚本。为了运行它,您需要安装一个用于 Excel 文件操作的 python 模块 Openpyxl: sudo easy_install openpyxl

Excel 编码

在处理 Excel 时,我发现 WINDOWS-1252编码是最不令人沮丧的。由于微软基本上拥有自己的专有字符集,人们可以假设它将在 Mac 和 Windows 版本的 MS-Excel 上都可以使用。这两个版本至少包括一个相应的“文件起源”或“文件编码”选择器,正确读取数据。

取决于您的系统和您使用的工具,这种编码也可以命名为 CP1252ANSIWindows (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         |

请注意,欧元标志不见了。 这张表可以在 艾伦 · 伍德找到。

转换

每种工具和语言的转换都是不同的。但是,假设您有一个 query_result.csv文件,您知道它是 UTF-8编码的。使用 iconv将其转换为 WINDOWS-1252:

iconv -f UTF-8 -t WINDOWS-1252 query_result.csv > query_result-win.csv

在我的 Mac 操作系统上,TextWrangler 识别出用 Excel 创建的 CSV 文件具有“ Western”编码。

经过一番搜索,我写了这个小脚本(我不确定 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

这对我有用

  1. 用 BBEdit 或 TextWrangler * 打开文件。
  2. 将文件设置为 Unicode (UTF-16 Little-Endian)(行结尾可以是 Unix 或 Windows)。保存!
  3. 在 Excel 中: 数据 > 获取外部数据 > 导入文本文件..。

现在的关键点,选择 麦金托什作为文件起源(它应该是第一选择)。

这是使用 Excel2011(版本14.4.2)

窗户底下有个小小的下拉窗口 *

在我的案例中,这种方法起作用了(Mac,Excel 2011,包括带有捷克发音符号的西里尔字母和拉丁字母) :

  • Charset UTF-16LE (仅仅 UTF-16是不够的)
  • BOM“ xFF xFE”
  • T (tab)作为分隔符
  • 不要忘记也编码分隔符和 CRLF: -)
  • 使用 iconv 而不是 mb _ trans _ coding

以下内容适用于 Mac 2011和 Windows Excel2002的 Excel:

  1. 在 Mac 上使用 iconv,将文件转换为 UTF-16 Little-Endian + name it * 。文本。Txt 扩展强制 Excel 运行文本导入向导) :

    iconv -f UTF-8 -t UTF-16LE filename.csv >filename_UTF-16LE.csv.txt

  2. 在 Excel 中打开该文件,并在“文本导入向导”中选择:

    • 第一步: 文件来源: 忽略它,你选择什么并不重要
    • 步骤2: 为 分界线文字修饰语选择合适的值
    • 步骤3: 如果需要,选择列格式

PS iconv 创建的 UTF-16LE 在开头有 BOM 字节 FF FE。

PPS 我最初的 csv 文件是在 Windows 7计算机上创建的,UTF-8格式(BOM 字节 EF BB BF 开头) ,并使用了 CRLF 换行符。逗号用作字段分隔符,单引号用作文本限定符。它包含 ASCII 字母加上不同的拉丁字母与波浪形,元音等,加上一些西里尔字母。所有正确显示在 Excel 中的 Win 和 Mac。

PPPS 软件版本:
* MacOSX10.6.8
* Excel for Mac 2011 v. 14.1.3
* WindowsServer2003SP2
* Windows Excel 2002 v. 10.2701.2625

您只尝试了逗号分隔和分号分隔的 CSV。如果你尝试过制表符分隔的 CSV (也称为 TSV) ,你就会找到答案:

UTF-16LE BOM(字节顺序标记) ,< strong > tab- 分隔


但是 : 在评论中你提到 TSV 不是你的一个选项(尽管我没能在你的问题中找到这个要求)。真可惜。这通常意味着您允许手动编辑 TSV 文件,这可能不是一个好主意。可视化地检查 TSV 文件不是问题。此外,还可以将编辑器设置为显示标记选项卡的特殊字符。

是的,我在 Windows 和 Mac 上都试过了。

使用 java (带 BOM 的 UTF-16LE)解决这个问题:

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 文件。

Refer to: 如何使用 BOM 对 UTF-16LE 字节数组进行编码/解码?

在我的案例中,添加序言文件解决了我的问题:

var data = Encoding.UTF8.GetBytes(csv);
var result = Encoding.UTF8.GetPreamble().Concat(data).ToArray();
return File(new MemoryStream(result), "application/octet-stream", "data.csv");