2013-03-08 130 views
7

我正在使用pyodbc连接到MS SQL服务器。此外,我正尝试使用openpyxl写入Excel 2007/10 .xlsx文件。将unicode字符串写入Excel 2007

这是我的代码(Python 2.7版):

import pyodbc 
from openpyxl import Workbook 

cnxn = pyodbc.connect(host = 'xxx',database='yyy',user='zzz',password='ppp') 
cursor = cnxn.cursor() 

sql = "SELECT TOP 10 [customer clientcode] AS Customer, \ 
       [customer dchl] AS DChl, \ 
       [customer name] AS Name, \ 
       ... 
       [name3] AS [name 3] \ 
     FROM mydb \ 
     WHERE [customer dchl] = '03' \ 
     ORDER BY [customer id] ASC" 

#load data 
cursor.execute(sql) 

#get colnames from openpyxl 
columns = [column[0] for column in cursor.description]  

#using optimized_write cause it will be about 120k rows of data 
wb = Workbook(optimized_write = True, encoding='utf-8') 

ws = wb.create_sheet() 
ws.title = '03' 

#append column names to header 
ws.append(columns) 

#append rows to 
for row in cursor: 
    ws.append(row) 

wb.save(filename = 'test.xlsx') 

cnxn.close() 

工作,至少直到我遇到一个客户点,例如,名称:"mún"。我的代码不会失败,一切都写入Excel,一切正常。这是直到我真正打开Excel文件 - 这会导致错误,说该文件已损坏,需要修复。修复文件后,所有数据都将丢失。

我知道代码适用于使用常规名称(仅ASCII)的客户,只要有重音字符或Excel文件被损坏的任何内容。

我试图打印一行(与一个困难的客户名称)。这是结果:

row是一个元组,以及指数的这一个:'Mee\xf9s Tilburg'因此,无论写\xf9 (ú)字符会导致一个错误,或者MS Excel无法应付它。我尝试过将各行编码成unicode(unicode(row,'utf-8')u''.join(row))等,尽管没有任何工作。要么我尝试一些愚蠢的东西导致错误,或者Excel文件仍然存在错误。

任何想法?

+0

连接字符串可能看起来很奇怪,因为我也尝试测试不同的方式给服务器,这种情况下它是pmssql。但我的问题不在于连接! – Rym 2013-03-08 15:05:24

+0

不是完全重复您的问题,但您可能会在这里找到解决方案:http://stackoverflow.com/questions/9148221/reading-unicode-from-sqlite-db-using-python – 2013-03-08 15:41:34

+0

无法用'pyodbc 3.0重现.6'和'openpyxl 1.6.1'。 'mún'在游标中被编码为'u'm \ xfan''。 – Bryan 2013-03-11 12:45:50

回答

5

最后,我发现了两种解决方案:

第一个是由光标给出的行转换成一个列表,并且该列表内的解码中的元素:

for row in cursor: 
    l = list(row) 
    l[5] = l[5].decode('ISO-8859-1') 
    (do this for all neccesary cols) 
    ws.append(l) 

我想这将有是地狱,因为有6列需要转换为unicode,而且有12万行,尽管实际上一切都非常快!最后,很明显,我可以/只应该将sql语句中的数据转换为unicode(cast(x as nvarchar)AS y),这使得替换变得不必要。起初我没有想到这一点,因为我认为它实际上是以unicode提供数据。我的错。

+0

您的问题包括一个'\ xf9'的例子,它不是有效的UTF-8。太糟糕了,你花了很长时间才意识到它。 – 2013-03-11 14:45:40

-1

您可以使用encode()到Unicode转换为字符串:

l=[u'asd',u'qw',u'fdf',u'sad',u'sadasd'] 
l[4]=l[4].encode('utf8') 
+0

它不提供一个很好的答案。请解释您的代码,并解决拼写错误 – 2015-12-12 13:41:49