2013-03-08 10 views
7

Łączę się z serwerem MS SQL przy użyciu pyodbc. Ponadto próbuję napisać do pliku Excel 2007/10 .xlsx przy użyciu openpyxl.Zapisywanie ciągów znaków Unicode w programie Excel 2007

To jest mój kod (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() 

Ten działa, przynajmniej aż do momentu spotykamy I klientowi, na przykład nazwa: "mún". Mój kod nie zawiedzie, wszystko zapisuje się do Excela i wszystko jest w porządku. Jest tak, dopóki nie otworzę pliku Excela - powoduje to błąd informujący, że plik jest uszkodzony i wymaga naprawy. Po naprawieniu pliku wszystkie dane zostaną utracone.

Wiem, że kod działa dla klientów o zwykłych nazwach (tylko ASCII), gdy tylko pojawi się znak akcentowany lub cokolwiek, że plik Excel zostanie uszkodzony.

Próbowałem wydrukować jeden wiersz (z trudnym nazwiskiem). Jest to wynikiem:

row jest krotka, a to jeden ze wskaźników: 'Mee\xf9s Tilburg' Więc albo pisanie charakter \xf9 (ú) powoduje błąd, lub MS Excel nie może sobie z tym poradzić. Próbowałem różnych sposobów kodowania wiersza do unicode (unicode(row,'utf-8') lub u''.join(row)) itp., Ale nic nie działa. Albo spróbuję czegoś idiotycznego, powodującego błąd, albo nadal błędy pliku Excel.

Wszelkie pomysły?

+0

Ciąg połączenia może się wydawać dziwne, jak również próbowałem testowania różnych sposobów na serwerze, to wystąpienie było pmssql. Ale moim problemem nie jest łączenie! – Rym

+0

Nie jest to dokładny duplikat twojego problemu, ale możesz znaleźć rozwiązanie tutaj: http://stackoverflow.com/questions/9148221/reading-unicode-from-sqlite-db-using-python –

+0

Nie można odtworzyć za pomocą 'pyodbc 3.0 .6' i 'openpyxl 1.6.1'. 'mún' jest zakodowany jako" u'm \ xfan'' w kursie. – Bryan

Odpowiedz

5

W końcu stwierdzono dwa rozwiązania:

pierwszy był konwersji wiersz danych przez kursor wykazu, i dekodowania elementów na liście:

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

I zdobione miałoby było piekło, ponieważ było 6 kolumn wymagających konwersji na Unicode, a było ich 120 tysięcy, chociaż wszystko poszło całkiem szybko! W końcu okazało się, że mogę/powinienem rzucić dane w instrukcji sql do unicode (cast (x as nvarchar) AS y), co spowodowało, że zamienniki stały się niepotrzebne. Nie myślałem o tym z początku, ponieważ myślałem, że to faktycznie dostarcza dane w unicode. Mój błąd.

+0

Twoje pytanie zawiera przykład z '\ xf9', który nie jest prawidłowym UTF-8. Szkoda, że ​​zajęło ci to tyle czasu. –

-1

Można użyć encode() przekonwertować ciąg Unicode:

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

nie zapewnia dobrej odpowiedzi. Wyjaśnij swój kod i napraw błędy pisowni –