Microsoft Excel在.csv文件中损坏变音符号?
我编程导出数据(使用PHP 5.2)到.csvtesting文件。
示例数据: Numéro 1
(注意重音e)。 数据是utf-8
(不包含BOM)。
当我在MS Excel中打开这个文件时,显示为Numéro 1
。
我可以在文本编辑器(UltraEdit)中正确显示它。 UE报告字符是decimal 233
。
如何导出 .csv文件中的文本数据,以便MS Excel能正确呈现它,最好不强制使用导入向导或非默认的向导设置?
格式正确的UTF8文件可以有一个字节顺序标记作为其前三个八位位组。 这些是hex值0xEF,0xBB,0xBF。 这些八位字节用于将文件标记为UTF8(因为它们与“字节顺序”信息无关)。 1如果这个BOM不存在,消费者/阅读器可以推断文本的编码types。 不支持UTF8的读取器将读取字节,如Windows-1252等其他编码,并在文件开始时显示字符。
有一个已知的错误,Excel在通过文件关联打开UTF8 CSV文件时,假定它们是单字节编码, 而不考虑 UTF8 BOM的存在。 这不能通过任何系统默认代码页或语言设置来解决。 BOM不会在Excel中提供线索 – 它不会工作。 (less数报告声称BOM有时会触发“导入文本”向导)。此错误似乎存在于Excel 2003及更早的版本中。 大多数报告(在这里的答案)说,这是在Excel 2007和更新的固定。
请注意,您始终可以使用“导入文本”向导在Excel中正确打开UTF8 CSV文件,该向导允许您指定要打开的文件的编码。 当然这不太方便。
这个答案的读者最有可能的情况是,他们并不特别支持Excel <2007,但发送原始的UTF8文本到Excel,这是错误的解释和洒文字与其他类似的Windows-1252字符。 添加UTF8 BOM可能是您的最佳和最快的解决scheme。
如果您在较早的Excels上遇到了用户,而Excel是您的CSV的唯一使用者,则可以通过导出UTF16而不是UTF8来解决此问题。 Excel 2000和2003将双击 – 正确打开这些。 (其他一些文本编辑器可能会遇到UTF16问题,因此您可能需要仔细权衡您的选项。)
*除非你不能,至less(至less)Excel 2011 for Mac的导入向导实际上并不总是适用于所有的编码,无论你怎么说。 </ anecdotal-evidence> 🙂
预先为我(Excel 2007)工作的物料清单(\ uFEFF),因为Excel将文件识别为UTF-8。 否则,保存并使用导入向导工作,但不太理想。
下面是我发送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; }
更新:文件名改进和BUG修复正确的长度计算。 感谢TRiG和@ ivanhoe011
导入时selectUTF-8编译。 如果您使用的是Office 2007,则在您select它的位置:打开文件之后。
Excel版本(2003 + 2007)和文件types的所有组合的答案
大多数其他答案只关心他们的Excel版本,并不一定会帮助你,因为他们的答案可能不适用于你的Excel版本。
例如,添加BOM字符引入了自动列分隔符识别的问题,但不是每个Excel版本。
有3个variables决定它是否在大多数Excel版本中工作:
- 编码
- BOM字符的存在
- 细胞分离器
有人沉溺于SAP尝试每一个组合,并报告结果。 最终结果? 使用带有BOM和制表符的UTF16le作为分隔符,可以在大多数Excel版本中使用。
你不相信我? 我也不会,但在这里阅读和哭泣: http : //wiki.sdn.sap.com/wiki/display/ABAP/CSV+tests+of+encoding+and+column+separator
在输出CSV数据之前回显UTF-8 BOM。 这修复了Windows中的所有字符问题,但不适用于Mac。
echo "\xEF\xBB\xBF";
它适用于我,因为我需要生成一个文件,将只在Windows PC上使用。
没有任何服务包,有或没有BOM(U + ffef或0xEF,0xBB,0xBF,既不可用),UTF-8在我的office 2007中也不工作。安装sp3时,UTF-8在0xEF,0xBB,0xBF BOM前缀。
当使用“utf-16-le”编码python时,utf-16工作,前缀为0xff 0xef,并使用tab作为分隔符。 我必须手工写出BOM,然后使用“utf-16-le”而不是“utf-16”,否则每一个encode()都会将BOM前面的每一行写出来,在第一列第二行和之后。
无法确定UTF-16是否可以在没有安装sp的情况下工作,因为我现在不能回去了。 叹
这是在Windows上,不知道MAC的办公室。
对于这两种工作情况,直接从浏览器启动下载时,导入工作,文本导入向导不介入,它的工作方式就像你所期望的。
正如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 %>
我也注意到,这个问题是前段时间“回答”的,但是我不明白那些说不能在Excel中成功打开utf8编码的csv文件而不使用文本向导的故事。
我的可重现的经验:typesOld MacDonald had a farm,ÈÌÉÍØ
进入记事本,点击回车,然后另存为(使用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资源pipe理器,双击文件名,或右键单击并使用“打开方式…”,popupExcel(2003)与预期的显示。
你可以保存一个扩展名为“xls”的html文件,重音符号可以工作(至less在2007年之前)。
例如:保存这个(在记事本中使用Save As 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>
请注意,包含UTF-8 BOM并不一定是个好主意–Mac版本的Excel会忽略它,并会实际将BOM显示为ASCII …电子表格第一个字段开头的三个令人讨厌的字符…
这只是一个字符编码的问题。 它看起来像是以UTF-8格式导出数据:UTF-8中的双字节序列是0xC3 0xA9,当在Windows-1252中解释时是é。 将数据导入到Excel中时,请确保告诉您正在使用的字符编码是UTF-8。
在输出CSV文件中写入物料清单在Django中确实为我工作:
def handlePersoonListExport(request): # Retrieve a query_set ... template = loader.get_template("export.csv") context = Context({ 'data': query_set, }) response = HttpResponse() response['Content-Disposition'] = 'attachment; filename=export.csv' response['Content-Type'] = 'text/csv; charset=utf-8' response.write("\xEF\xBB\xBF") response.write(template.render(context)) return response
更多信息http://crashcoursing.blogspot.com/2011/05/exporting-csv-with-special-characters.html谢谢你们!;
我发现的另一个解决scheme就是将结果编码为Windows代码页1252(Windows-1252或CP1252)。 这可以通过例如将Content-Type
恰当地设置为像text/csv; charset=Windows-1252
这样的东西来完成text/csv; charset=Windows-1252
text/csv; charset=Windows-1252
,同样设置响应stream的字符编码。
检查你正在生成的文件的编码,使Excel正确显示文件,你必须使用系统默认的代码页。
你用的是什么语言? 如果是.Net,则只需在生成文件时使用Encoding.Default。
CSV格式在Excel中被实现为ASCII而不是Unicode,因此改变了变音符号。 我们遇到了同样的问题,就是我们如何跟踪官方CSV标准在Excel中被定义为基于ASCII的。
Excel 2007正确读取带有BOM(EF BB BF)编码的csv的UTF-8。
Excel 2003(也可能更早)使用BOM(FF FE)读取UTF-16LE,但使用TAB而不是逗号或分号。
我只能得到CSV才能在Excel 2007中正确parsing为制表符分隔的小尾数UTF-16,从正确的字节顺序标记开始。
如果你像vb.net那样有遗留的代码,下面的代码对我有用:
Response.Clear() Response.ClearHeaders() Response.ContentType = "text/csv" Response.Expires = 0 Response.AddHeader("Content-Disposition", "attachment; filename=export.csv;") Using sw As StreamWriter = New StreamWriter(Context.Response.OutputStream, System.Text.Encoding.Unicode) sw.Write(csv) sw.Close() End Using Response.End()
我find了解决问题的方法。 这是一个讨厌的黑客,但它的工作原理:与Open Office打开文档,然后将其保存到任何Excel格式; 生成的.xls
或.xlsx
将显示加重的字符。
在Ruby 1.8.7中,我将每个字段编码为UTF-16,并丢弃BOM(也许)。
以下代码是从active_scaffold_export中提取的:
<% require 'fastercsv' fcsv_options = { :row_sep => "\n", :col_sep => params[:delimiter], :force_quotes => @export_config.force_quotes, :headers => @export_columns.collect { |column| format_export_column_header_name(column) } } data = FasterCSV.generate(fcsv_options) do |csv| csv << fcsv_options[:headers] unless params[:skip_header] == 'true' @records.each do |record| csv << @export_columns.collect { |column| # Convert to UTF-16 discarding the BOM, required for Excel (> 2003 ?) Iconv.conv('UTF-16', 'UTF-8', get_export_column_value(record, column))[2..-1] } end end -%><%= data -%>
重要的路线是:
Iconv.conv('UTF-16', 'UTF-8', get_export_column_value(record, column))[2..-1]
select转换为UTF-8(不转换为UTF-8(不含BOM))用excel打开双击clic使用记事本++ clic打开文件希望帮助Christophe GRISON