2013-03-08 14 views
7

Connessione a un server MS SQL tramite pyodbc. Inoltre, sto cercando di scrivere in un file Excel 2007/10 .xlsx utilizzando openpyxl.Scrittura stringhe unicode in Excel 2007

Questo è il mio codice (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() 

Questo funziona, almeno fino al punto ho incontrato un cliente con, per esempio, il nome: "mún". Il mio codice non fallisce, tutto scrive su Excel e tutto va bene. Cioè fino a quando non apro effettivamente il file Excel, questo causa un errore che dice che il file è corrotto e deve essere riparato. Al momento di riparare il file, tutti i dati vengono persi.

So che il codice funziona per i clienti con nomi regolari (solo ASCII), è non appena c'è un carattere accentato o qualcosa che il file di Excel viene danneggiato.

Ho provato a stampare una singola riga (con un nome difficile). Questo è il risultato:

row è una tupla, e questo uno degli indici: 'Mee\xf9s Tilburg' Quindi, o scrivendo il carattere \xf9 (ú) causa un errore, o MS Excel non possono far fronte con essa. Ho provato vari modi di codificare una riga in unicode (unicode(row,'utf-8') o u''.join(row)), anche se non funziona nulla. O provo qualcosa di idiota risultante in un errore, o il file di Excel ancora errori.

Qualche idea?

+0

La stringa di connessione potrebbe sembrare strano, come ho provato anche testare diversi modi al server, questo caso è stato pmssql. Ma il mio problema non riguarda la connessione! – Rym

+0

Non è un duplicato esatto per il tuo problema, ma potresti trovare una soluzione qui: http://stackoverflow.com/questions/9148221/reading-unicode-from-sqlite-db-using-python –

+0

Impossibile riprodurre con 'pyodbc 3.0 .6' e 'openpyxl 1.6.1'. 'mún' è codificato come' u'm \ xfan'' nel cursore. – Bryan

risposta

5

Alla fine ho trovato due soluzioni:

primo era convertire la riga in cursore a un elenco, e decodificare gli elementi all'interno dell'elenco:

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

ho pensato questo avrebbe è stato un inferno, perché c'erano 6 colonne che necessitano di conversione in unicode, e c'erano 120k righe, anche se in realtà tutto è andato abbastanza veloce! Alla fine è apparso chiaro che avrei potuto/dovevo semplicemente trasmettere i dati nell'istruzione sql in unicode (cast (x as nvarchar) AS y) che rendeva superflue le sostituzioni. Non ho pensato a questo in un primo momento ho pensato che in realtà forniva i dati in unicode. Colpa mia.

+0

La tua domanda includeva un esempio con '\ xf9', che non è UTF-8 valido. Peccato, ti ci è voluto così tanto tempo per realizzarlo. –

-1

È possibile utilizzare encode() per convertire unicode a stringa:

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

non fornisce una buona risposta. Per favore spiega il tuo codice e correggi i tuoi errori di ortografia –

Problemi correlati