在Python中写入Unicode到文件时出错
这是我写的第一个Python程序,我需要一些帮助来将UTF-8数据写入文件。
我的目的是从Excel文件中读取数据,并将用逗号分隔的数据写入文本文件。下面是我正在运行的代码,但出现了下面的错误。
import xlrd
import csv
import codecs
wb = xlrd.open_workbook('/etl/dev/input/CustList.xls')
sh = wb.sheet_by_index(1)
file_output = codecs.open('/etl/dev/input/CustList.csv', 'w', 'utf-8')
for rownum in xrange(sh.nrows):
file_output.write(sh.row_values(rownum))
file_output.close()
这是错误信息:
Traceback (most recent call last):
File "TestXls2Csv.py", line 20, in <module>
file_output.write(sh.row_values(rownum))
File "/fstools/gptools/ext/python/lib/python2.6/codecs.py", line 686, in write
return self.writer.write(data)
File "/fstools/gptools/ext/python/lib/python2.6/codecs.py", line 351, in write
data, consumed = self.encode(object, self.errors)
TypeError: coercing to Unicode: need string or buffer, list found
任何帮助都非常感谢。
谢谢,
Zulfi
我尝试了以下方法:
row_values = [str(val) for val in sh.row_values(rownum)]
file_output.write(",".join(row_values) + "\n")
对于Excel的一个工作表,这个方法似乎可以正常工作,但对于另一个工作表却出现了以下错误:
错误追踪(最近的调用在前):
文件 "TestXls2Csv.py",第12行,
file_output.write(",".join(sh.row_values(rownum)) + "\n")
TypeError: sequence item 8: expected string or Unicode, float found。我最开始尝试使用csv.writer,但其中一个单元格里有一个\xa0字符,这让我遇到了很多麻烦,所以我安装了codecs并在努力让它工作。
以下是关于Excel文档的一些信息,希望能提供一些线索:
=== 文件: CustList.xls ===
打开耗时3.03秒
BIFF版本: 8; 数据模式: 0
代码页: 1200(编码: utf_16_le);国家: (1, 1)
最后保存者: u'Rajesh, Vatha'
数据表数量: 2
使用内存映射: 1; 格式化: 0; 按需: 0
不规则行: 0
加载时间: 0.01秒(阶段1)1.86秒(阶段2)
工作表0: 名称 = u'MEMBER'; 行数 = 29966; 列数 = 11
工作表1: 名称 = u'PHYSICANS'; 行数 = 1619; 列数 = 19
命令耗时0.20秒。请给出建议。
谢谢,
Zulfi
2 个回答
如果你想让输出文件里的值用逗号分隔,你可以简单地修改你的写入命令,把值的列表连接成一个用逗号分隔的字符串。
不过,首先你得把列表里的每个值都转换成字符串,因为 row_values()
返回的是一个包含字符串和浮点数的列表。
...
row_values = [str(val) for val in sh.row_values(rownum)]
file_output.write(",".join(row_values) + "\n")
...
dciriello 说得对,因为 file_output.write 这个函数需要字符串作为输入,但 sh.row_values(rownum) 返回的是一个列表,这就是主要原因。
如果你想把一个 xls 文件复制到 csv 文件,这里有一些步骤可以参考。
import xlrd
import csv
import codecs
wb = xlrd.open_workbook('/etl/dev/input/CustList.xls')
table = wb.sheet_by_index(1)
nrows = table.nrows
with codecs.open('/etl/dev/input/CustList.csv', 'w', 'utf-8') as file_output:
spamwriter = csv.writer(file_output)
for i in range(nrows):
spamwriter.writerow(table.row_values(i))