使用Django创建包含Unicode的CSV文件,并可直接在Excel中打开

7
我想通过Django创建一个包含Unicode数据(希腊字符)的CSV文件,并希望可以直接从MS Excel打开。我曾经在其他地方读到过unicodecsv库,于是我决定使用它。所以,这是我的视图: def get_csv(request, id): response = HttpResponse(mimetype='text/csv') response['Content-Disposition'] = 'attachment; filename=csv.csv' writer = unicodecsv.writer(response, encoding='utf-16"') writer.writerow(['Second row', 'A', 'B', 'C', '"Testing"', "ελληνικά"]) return response 现在,除了utf-16之外,我确实尝试了编写器的编码参数中的所有选项,包括utf-8、utf-8-sig、utf-8-le、utf-16-le等等。每次我用Excel打开文件时,我总是看到希腊字符应该出现的地方都是垃圾字符。 Notepad++能够无问题地打开文件。我做错了什么? 更新:这是jd回答后我尝试的内容: import csv response = HttpResponse(mimetype='text/csv') response['Content-Disposition'] = 'attachment; filename=test.csv' response.write(u'\ufeff'.encode('utf8')) writer = csv.writer(response, delimiter=';' , dialect='excel') writer.writerow(['Second row', 'A', 'B', 'C', '"Testing"', "ελληνικά"]) return response 仍然没有成功 - 现在我也可以在Excel中看到BOM(作为垃圾字符) - 我也尝试使用unicodecsv和其他一些选项,但再次没有任何作用 :( 更新2: 在dda的建议后,我尝试了这个: writer = unicodecsv.writer(response, delimiter=';' , dialect='excel') writer.writerow(codecs.BOM_UTF16_LE) writer.writerow([ (u'ελληνικά').decode('utf8').encode('utf_16_le')]) 仍然没有成功 :( 这是我得到的错误: UnicodeEncodeError at /csv/559 'ascii' codec can't encode characters in position 0-7: ordinal not in range(128) 更新3: 我要疯了。为什么这么难?这是另一种尝试: response.write(codecs.BOM_UTF16_LE) writer = unicodecsv.writer(response, delimiter=';' , lineterminator='\n', dialect='excel', ) writer.writerow('ελληνικ') writer.writerow([ ('ελληνικά').decode('utf8').encode('utf_16_le')]) #A writer.writerow([ ('ελληνικά2').decode('utf8').encode('utf_16_le'), ('ελληνικά2').decode('utf8').encode('utf_16_le') ]) #B 这是Excel的内容:
我得到了一些希腊字符在行#A。但是完全相同的行B无法产生希腊字符$^#$#^$#$#^ @@%$#^#^$#$ 请帮帮我!

你是否在MacOS上使用Excel?这个SO答案是我发现BOM技巧的地方,显然它在MacOS上的Excel上不起作用。 - jd.
不好意思,我正在使用 Windows 版本的 Excel :( - Serafeim
(u'ελληνικά').decode('utf8').encode('utf_16_le'):你不应该对Unicode字符串进行解码,只能进行编码。 - jd.
你说得对,这就是为什么我在字符串前面删除了“u”的原因... 但是,正如你在更新3中看到的那样,我仍然遇到了问题:( - Serafeim
2
请不再花费精力在那个问题上了,我最后使用了xlwt!我也向每个人推荐它——我用了5分钟就把它搞定了! - Serafeim
2个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
12

使用Python的csv模块,如果你在文件开头放置BOM,则可以编写一个UTF-8文件,Excel将正确读取该文件。

with open('myfile.csv', 'wb') as f:
    f.write(u'\ufeff'.encode('utf8'))
    writer = csv.writer(f, delimiter=';', lineterminator='\n', quoting=csv.QUOTE_ALL, dialect='excel')
    ...

使用 unicodecsv 应该也可以实现相同的效果。如果不能在 HttpResponse 对象中直接写入 BOM,则可以先使用 StringIO 写入文件。

编辑:

这里提供一些示例代码,可编写带有非 ASCII 字符的 UTF-8 CSV 文件。为了简单起见,我将 Django 排除在外。我可以在 Excel 中读取该文件。

# -*- coding: utf-8 -*-
import csv
import os
response = open(os.path.expanduser('~/utf8_test.csv'), 'wb')
response.write(u'\ufeff'.encode('utf8'))
writer = csv.writer(response, delimiter=';' , dialect='excel')
writer.writerow(['Second row', 'A', 'B', 'C', '"Testing"', u"ελληνικά".encode('utf8')])
response.close()

我尝试了完全相同的代码,但无法读取文件 :( 怎么可能?我已将其保存在UTF-8 w/o BOM .py中。我真的要疯了吗???? 当我用Notepad ++打开时,此文件很好... 这是我在Excel 2003中看到的内容:ο»Ώ第二行ABC“测试”ελληνικά - Serafeim
它对我不起作用。我在Mac OS X上使用Office。但是OpenOffice可以毫无问题地打开该文件。 - tzuchien.chiu

1

我从未能够在Excel中打开UTF-8编码的(CSV)文件。我唯一成功让Excel正确导入文件的方法是使用UTF-16LE。结果可能因人而异。

编辑

首先

writer.writerow(codecs.BOM_UTF16_LE)

然后(根据需要重复多次;str是要编码和写入的字符串)

writer.writerow(str.decode('utf8').encode('utf_16_le'))

我不关心文件的实际编码。那么,我如何输出以UTF-16LE编码的文件,并能够用Excel读取它? - Serafeim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,