无法正确编码CSV文件?

我有这个确切的问题: https : //www.en.adwords-community.com/t5/Basics-for-New-Advertisers/Character-Encoding-used-by-the-editor/td-p/100244 (t1;博士:试图上传文件到谷歌,包含外国字符,他们看起来很有趣,当在Excel中打开,谷歌拒绝他们没有正确编码)

我有以下代码。 请注意,我已经尝试在http响应对象的开头添加一个字节顺序标记,并尝试将所有string编码为utf-8。

<some code where workbook is created and populated via xlwt> output = StringIO.StringIO() workbook.save(output) wb = open_workbook(file_contents=output.getvalue()) sheet = wb.sheet_by_name(spreadsheet) response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = 'attachment; filename='+(account.name+'-'+spreadsheet).replace(',', '')+'.csv' response.write('\xEF\xBB\xBF') writer = csv.writer(response) for rownum in xrange(sheet.nrows): newRow = [] for s in sheet.row_values(rownum): if isinstance(s,unicode): newRow.append(s.encode("utf-8")) elif isinstance(s, float): newRow.append(int(s)) else: newRow.append(s.decode('utf-8')) writer.writerow(newRow) return response 

但在Excel中打开时他们仍然看起来不正确! 为什么?

每当你写一个Unicodestring到一个文件或stream,它必须被编码。 你可以自己做编码,或者你可以让各种模块和库函数为你做。 如果您不确定要为您select哪种编码,并且您知道要编写哪种编码,最好自己进行编码。

在input中遇到Unicodestring时,您已经遵循了此build议。 但是,如果遇到已经编码为UTF-8的string,则将其decode为Unicode! 这导致在编辑器中进行反向转换,显然它不是selectutf-8作为默认编码。 通过单独的string,而不是解码它, writerow将写出完全按照你的意图。

你想总是编码的数据,但是对于string值,你正在解码为Unicode值:

 else: newRow.append(s.decode('utf-8')) 

在这种情况下,最有可能的是您的Web框架将该数据编码为Latin-1。

只需附加值而不解码:

 for s in sheet.row_values(rownum): if isinstance(s, unicode): s = s.encode("utf-8")) elif isinstance(s, float): s = int(s) newRow.append(s) 

更多提示:

  • 在响应头文件中传递字符集也是一个好主意:

     response = HttpResponse(content_type='text/csv; charset=utf-8') 
  • 使用codecs.BOM_UTF8写入BOM,而不是硬编码值。 更不容易出错。

     response.write(codecs.BOM_UTF8)