2013-03-08 3 views
7

Я подключаюсь к серверу MS SQL, используя pyodbc. Кроме того, я пытаюсь написать файл Excel 2007/10 .xlsx с помощью openpyxl.Запись строк 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 поврежден.

Я попытался напечатать один ряд (со сложным названием cust). Это результат:

row является кортежем, и это один из показателей: 'Mee\xf9s Tilburg' Так что либо писать \xf9 (ú) характер вызывает ошибку, или MS Excel не может справиться с ней. Я пробовал различные способы кодирования строки в unicode (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

В конце концов я нашел два решения:

Первой был преобразование строки заданного курсора в список, и декодирование элементов в списке:

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 столбцов, нуждающихся в преобразовании в Юникод, и было 120 тыс. строк, хотя на самом деле все прошло довольно быстро! В конце концов стало очевидно, что я мог/должен просто передавать данные в инструкции sql в unicode (cast (x as nvarchar) AS y), что сделало ненужные замены. Я не думал об этом сначала, потому что думал, что он действительно снабжает данные в Юникоде. Виноват.

+0

В ваш вопрос включен пример с '\ xf9', что недопустимо UTF-8. Жаль, что вам так долго нужно было это осознать. –

-1

Вы можете использовать encode() для преобразования Юникода в строку:

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

он не дает хорошего ответа. Пожалуйста, объясните свой код и исправьте свои орфографические ошибки. –