我想通过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行,这是exaclty同样没有产生我的希腊字符$ ^#$#^ $#$#^ @@%$#^#^ $#$ Pls hlep!
答案 0 :(得分:11)
使用Python的csv
模块,您可以编写一个UTF-8文件,如果您将BOM放在文件的开头,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
。我想您可以直接将BOM写入HttpResponse
对象,否则您可以使用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()
答案 1 :(得分:1)
我以前从未能在Excel中打开UTF-8编码(CSV)文件。我设法正确导入Excel文件的唯一方法是使用UTF-16LE。 YMMV。
修改
第一
writer.writerow(codecs.BOM_UTF16_LE)
然后(根据需要多次; str是要编码和写入的字符串)
writer.writerow(str.decode('utf8').encode('utf_16_le'))