2013-03-08 20 views
7

pyodbcを使用してMS SQLサーバーに接続しています。さらに、openpyxlを使用してExcel 2007/10 .xlsxファイルに書き込もうとしています。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ファイルが破損するとすぐに機能することが分かります。

私は、1つの行を印刷しようとしました。これが結果です:

rowはタプルで、指標のこの1:'Mee\xf9s Tilburg'だからどちらか\xf9 (ú)文字を書くと、エラーが発生し、またはMS Excelが、それに対処することはできません。私はユニコード(unicode(row,'utf-8')またはu''.join(row))などに行をエンコードするさまざまな方法を試しましたが、何も動作しません。どちらかといえば、何かばかげたことが起こってエラーが発生したり、Excelファイルがエラーになったりします。

アイデア?最後に

+0

接続文字列は、奇妙に思えるかもしれませんが、それはpmssqlこのインスタンスでした。しかし、私の問題は接続ではありません! – Rym

+0

あなたの問題と正確には重複しませんが、ここで解決策を見つけることができます:http://stackoverflow.com/questions/9148221/reading-unicode-from-sqlite-db-using-python –

+0

'pyodbc 3.0で再現できません.6 'と' 'openpyxl 1.6.1'。 'mún'は' u'm \ xfan''としてカーソルにエンコードされます。 – Bryan

答えて

5

Iは、2つの解決策を見つけた:

最初のものはリストにカーソルによって指定された行を変換し、リスト内の要素を復号した

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つの列があり、すべてが実際にはかなり速くなったにもかかわらず、120k行があったためです!結局、私はsqlステートメントのデータをunicode(キャスト(xはnvarchar)AS y)にキャストして、置換えを不要にできるはずです。私はこれが実際にユニコードでデータを供給していると思ったからです。私の悪い。

+0

あなたの質問には、有効なUTF-8ではない '\ xf9'の例が含まれています。あまりにも悪いことに、それを実現するためにあなたが長くかかりました。 –

-1

あなたは文字列にUnicodeを変換するためにencode()を使用することができます。私はまた、サーバーへのさまざまな方法をテストしようとしたとして

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

それは良い答えを提供しません。あなたのコードを説明し、あなたのスペルミスを修正してください –

関連する問題