Microsoft Excel在.csv文件中破坏了变音符号?

时间:2020-03-06 14:56:53  来源:igfitidea点击:

我正在以编程方式(使用PHP 5.2)将数据导出到.csv测试文件中。
示例数据:"数字1"(注意带重音符号e)。
数据为" utf-8"(无前置BOM)。

当我在MS Excel中打开此文件时,显示为" Num ?? ro 1"。

我可以在正确显示它的文本编辑器(UltraEdit)中打开它。 UE报告该字符是"十进制233"。

如何在.csv文件中导出文本数据,以便MS Excel正确呈现它,最好不要强制使用导入向导或者非默认向导设置?

解决方案

这只是字符编码的问题。好像我们将数据导出为UTF-8:在UTF-8中是两个字节的序列0xC3 0xA9,在Windows-1252中解释为??。当我们将数据导入Excel时,请确保告诉我们所使用的字符编码为UTF-8.

检查生成文件的编码,以使excel正确显示文件,我们必须使用系统默认代码页。

我们使用的是哪种语言?如果是.Net,则在生成文件时只需要使用Encoding.Default。

CSV格式在Excel中以ASCII而非unicode的形式实现,从而破坏了变音符号。我们遇到了同样的问题,这就是我如何跟踪官方CSV标准在Excel中定义为基于ASCII的问题。

格式正确的UTF8文件的前三个八位字节可以包含字节顺序标记。这些是十六进制值0xEF,0xBB,0xBF。这些八位位组用于将文件标记为UTF8(因为它们与"字节顺序"信息无关)。1如果不存在此BOM表,则使用方/读取方可以推断文本的编码类型。不支持UTF8的读取器将以其他编码方式(例如Windows-1252)读取字节,并在文件开头显示字符" ???"。

有一个已知的错误,即Excel在通过文件关联打开UTF8 CSV文件时,假定它们是单字节编码的,而无视UTF8 BOM的存在。任何系统默认的代码页或者语言设置都无法解决此问题。 BOM表在Excel中不会显示出来,只是无法正常工作。 (少数报告声称BOM有时会触发"导入文本"向导。)此错误似乎在Excel 2003和更早版本中存在。大多数报告(根据此处的答案)说这在Excel 2007和更高版本中已得到修复。

请注意,我们始终可以*使用"导入文本"向导在Excel中正确打开UTF8 CSV文件,该向导允许我们指定要打开的文件的编码。当然,这不太方便。

此答案的读者最有可能是在他们不特别支持Excel <2007的情况下,而是将原始UTF8文本发送到Excel,这会误解它,并在文本中加上和其他类似Windows-1252字符。添加UTF8 BOM表可能是我们最好,最快的解决方案。

如果我们对使用旧版Excel的用户不满意,而Excel是CSV的唯一使用者,则可以通过导出UTF16而不是UTF8来解决此问题。 Excel 2000和2003将正确双击这些文件。 (其他一些文本编辑器可能会对UTF16产生问题,因此我们可能需要仔细权衡一下选择。)

*除非我们不能这样做,否则(至少)Excel 2011 for Mac的"导入向导"实际上并不总是适用于所有编码,无论我们说什么。 </ anecdotal-evidence> :)

导入时选择UTF-8 enconning。如果我们使用Office 2007,则可以在其中进行选择:
在我们打开文件之后。

http://s4.tinypic.com/mv1bhi.jpg

在我之前安装BOM(\ uFEFF)对我有用(Excel 2007),因为Excel将该文件识别为UTF-8. 否则,可以保存它并使用导入向导有效,但是不太理想。

正如Fregal所说,\ uFEFF是必经之路。

<%@LANGUAGE="JAVASCRIPT" CODEPAGE="65001"%>
<%
Response.Clear();
Response.ContentType = "text/csv";
Response.Charset = "utf-8";
Response.AddHeader("Content-Disposition", "attachment; filename=excelTest.csv");
Response.Write("\uFEFF");
// csv text here
%>

我们可以保存带有扩展名'xls'的html文件,并且重音符号可以正常使用(至少在2007年之前)。

示例:将其保存(使用记事本中的另存为utf8)作为test.xls:

<html>
<meta http-equiv="Content-Type" content="text/html" charset="utf-8" />
<table>
<tr>
  <th>id</th>
  <th>name</th>
</tr>
<tr>
 <td>4</td>
 <td>Hélène</td>
</tr>
</table>
</html>

我还注意到,该问题已在一段时间前"得到解答",但我不理解无法使用文本向导无法在Excel中成功打开utf8编码的csv文件的故事。

我的可复制经验:
在记事本中键入" Old MacDonald has a farm ,?",然后按Enter,然后另存为(使用UTF-8选项)。

使用Python显示其中的实际内容:

>>> open('oldmac.csv', 'rb').read()
'\xef\xbb\xbfOld MacDonald had a farm,\xc3\x88\xc3\x8c\xc3\x89\xc3\x8d\xc3\x98\r\n'
>>> ^Z

好的。记事本已将BOM表放在最前面。

现在进入Windows资源管理器,双击文件名,或者右键单击并使用" Open with ...",然后按预期方式弹出带有显示的Excel(2003)。

以下是将Microsoft Excel发送给用户时在项目中使用的PHP代码:

/**
   * Export an array as downladable Excel CSV
   * @param array   $header
   * @param array   $data
   * @param string  $filename
   */
  function toCSV($header, $data, $filename) {
    $sep  = "\t";
    $eol  = "\n";
    $csv  =  count($header) ? '"'. implode('"'.$sep.'"', $header).'"'.$eol : '';
    foreach($data as $line) {
      $csv .= '"'. implode('"'.$sep.'"', $line).'"'.$eol;
    }
    $encoded_csv = mb_convert_encoding($csv, 'UTF-16LE', 'UTF-8');
    header('Content-Description: File Transfer');
    header('Content-Type: application/vnd.ms-excel');
    header('Content-Disposition: attachment; filename="'.$filename.'.csv"');
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: '. strlen($encoded_csv));
    echo chr(255) . chr(254) . $encoded_csv;
    exit;
  }

更新:文件名的改进和错误修复正确的长度计算。感谢TRiG和@ ivanhoe011

Excel 2007可以正确读取带有BOM(EF BB BF)编码的csv的UTF-8.

Excel 2003(可能更早)使用BOM(FF FE)读取UTF-16LE,但使用TAB而不是逗号或者分号。

我只能使CSV在Excel 2007中正确地解析为以正确的字节顺序标记开头的制表符分隔的小尾数UTF-16.