我有一个使用xlwt / xlrd处理excel文件的python脚本。在我的脚本开头,我有以下代码:
#if you got a csv in parameters, convert it to an xls file
if '.csv' in sys.argv[1]:
#name of new file after conversion is finished
name = sys.argv[1]
csvfile = open(sys.argv[1], 'rb')
try:
#extract data from .csv
csvReader = csv.reader(csvfile, delimiter=' ', quotechar='|')
csvData = list(csv.reader(open(name, 'rb')))
# write to a xls file
outFile = xlwt.Wrokbook()
newSheet = outFile.add_sheet('Sheet 1')
# traverse over 2d array to write each individual cell
for row in range(len(csvData)):
for col in range(len(csvData[0])):
newSheet.write(row, col, csvData[row][col].encode('utf8'))
name = name[:-4] + ".xls" #change extension of file
outFile.save(name)
wb = open_workbook(name)
finally:
csvfile.close()
哪个给出了错误
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 44: ordinal not in range(128)
在行outFile.save(名称)
上到目前为止我发现的唯一有用的东西是UnicodeDecodeError: 'ascii' codec can't decode byte 0xef in position 1,但我的终端使用utf8作为其编码。
编辑: 完全忘了提这个,很抱歉。
我认为带.encode的行会以某种方式导致错误,但我无法思考如何。我最初没有.encode,然后我添加.encode('utf8'),也尝试.encode('utf-8')和unicode(字符串,'utf8')。我不确定还有什么可以解决这个问题。
编辑: 我试过Brian的建议无济于事。另外,我尝试了codecs.open建议,并尝试在创建工作簿时指定编码。这些都不会改变错误。我尝试过的唯一改变错误的是使用newSheet.write在行上添加.encode。没有它,我得到:
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2013' in position 44: ordinal no in range(128)
有了它,我得到了:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 44: ordinal not in range(128)
答案 0 :(得分:1)
根据docs:
csv模块不直接支持读写Unicode, 但是对于ASCII NUL的一些问题,它是8位清除 字符。所以你可以编写处理函数的函数或类 只要你避免像编码一样编码和解码 使用NUL的UTF-16。建议使用UTF-8。
尝试使用以下代码段,该代码段为您提供了一个使用unicode数据读取csv的生成器。请注意,此代码直接来自上面链接的文档:
import csv
def unicode_csv_reader(unicode_csv_data, dialect=csv.excel, **kwargs):
# csv.py doesn't do Unicode; encode temporarily as UTF-8:
csv_reader = csv.reader(utf_8_encoder(unicode_csv_data),
dialect=dialect, **kwargs)
for row in csv_reader:
# decode UTF-8 back to Unicode, cell by cell:
yield [unicode(cell, 'utf-8') for cell in row]
def utf_8_encoder(unicode_csv_data):
for line in unicode_csv_data:
yield line.encode('utf-8')
作为如何使用上述代码的示例,而不是
csvReader = csv.reader(csvfile, delimiter=' ', quotechar='|')
使用
csvReader = unicode_csv_reader(csvfile, delimiter=' ', quotechar='|')
yield
是生成器函数的返回等价物。该函数返回一个生成器对象,它是python中的一种可迭代类型。 **kwargs
表示关键字参数,这是您在编写delimiter=' ', quotechar='|'
答案 1 :(得分:0)
问题是当你的输入中有非ascii字符时,你不会以它期望的状态将它们传递给xlwt。
根据xlwt的文档:
unicode实例按原样编写。使用在创建Workbook实例时指定的编码(默认值:'ascii')将str实例转换为unicode。
https://secure.simplistix.co.uk/svn/xlwt/trunk/xlwt/doc/xlwt.html?p=4966#xlwt.Worksheet.write-method
也就是说,当您的输入csv文件包含使用utf-8编码的非ascii字符时,读取器会将其作为编码的Python字符串拉入 - 如果您直接查看它,则会看到多个十六进制字节,例如{ {1}}小写a-acute。当您将其写入工作表时,它必须解码它。在创建工作簿时,您没有指定编码,因此它尝试使用默认的'\xc3\xa1'
编码执行此操作。如你所见,这不起作用,因为那些不是ascii字节。
您的选择是将Unicode字符串传递给工作表,从csv阅读器的结果解码它们(或将csv阅读器包装在解码所有内容的东西中 - 它是相同的东西)或者在创建时在工作簿上设置编码它
答案 2 :(得分:0)
尝试使用内置编解码器库打开文件:
#!/usr/bin/env python2.7
# -*- coding: UTF-8 -*-
import codecs
with codecs.open(sys.argv[1], "rb", encoding="utf-8") as csvfile:
csvReader = csv.reader(csvfile, delimiter=' ', quotechar='|')
# snipped the rest of the code