2013-03-08 103 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