2014-09-25 18 views
5

Wydaje się, że jest wiele postów na ten temat, a moje rozwiązanie jest zgodne z tym, co wydaje się najbardziej powszechną odpowiedzią, jednak napotykam błąd kodowania, który nie wiem jak adres.Python Konwertuj Excel na CSV

>>> def Excel2CSV(ExcelFile, SheetName, CSVFile): 
    import xlrd 
    import csv 
    workbook = xlrd.open_workbook(ExcelFile) 
    worksheet = workbook.sheet_by_name(SheetName) 
    csvfile = open(CSVFile, 'wb') 
    wr = csv.writer(csvfile, quoting=csv.QUOTE_ALL) 

    for rownum in xrange(worksheet.nrows): 
     wr.writerow(worksheet.row_values(rownum)) 

    csvfile.close() 

>>> Excel2CSV(r"C:\Temp\Store List.xls", "Open_Locations", 
       r"C:\Temp\StoreList.csv") 

Traceback (most recent call last): 
File "<pyshell#2>", line 1, in <module> 
Excel2CSV(r"C:\Temp\Store List.xls", "Open_Locations", r"C:\Temp\StoreList.csv") 
File "<pyshell#1>", line 10, in Excel2CSV 
wr.writerow(worksheet.row_values(rownum)) 
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa0' in position 14: 
ordinal not in range(128) 
>>> 

Każda pomoc lub wgląd są mile widziane.

Odpowiedz

10

Jak zauważa @davidism, moduł Python 2 csv nie działa z unikodem. Można obejść ten problem poprzez przekształcenie wszystkich unicode obiektów do str obiektów przed ich przedstawieniem csv:

def Excel2CSV(ExcelFile, SheetName, CSVFile): 
    import xlrd 
    import csv 
    workbook = xlrd.open_workbook(ExcelFile) 
    worksheet = workbook.sheet_by_name(SheetName) 
    csvfile = open(CSVFile, 'wb') 
    wr = csv.writer(csvfile, quoting=csv.QUOTE_ALL) 

    for rownum in xrange(worksheet.nrows): 
     wr.writerow(
      list(x.encode('utf-8') if type(x) == type(u'') else x 
        for x in worksheet.row_values(rownum))) 

    csvfile.close() 
2

Moduł Python 2 csv ma pewne problemy z danymi Unicode. Możesz zakodować wszystko do UTF-8 przed napisaniem lub użyć modułu unicodecsv, aby zrobić to za Ciebie.

Pierwsza pip install unicodecsv. Następnie zamiast import csv, tylko import unicodecsv as csv. Interfejs API jest taki sam (plus opcje kodowania), więc żadne inne zmiany nie są potrzebne.

0

Kolejna moda na ten sposób: obsady do łańcucha, tak jak masz ciąg, można skodyfikować go jako "utf-8".

str(worksheet.row_values(rownum)).encode('utf-8') 

Cała funkcja:

def Excel2CSV(ExcelFile, SheetName, CSVFile): 
    import xlrd 
    import csv 
    workbook = xlrd.open_workbook(ExcelFile) 
    worksheet = workbook.sheet_by_name(SheetName) 
    csvfile = open(CSVFile, 'wb') 
    wr = csv.writer(csvfile, quoting=csv.QUOTE_ALL) 

    for rownum in xrange(worksheet.nrows): 
     wr.writerow(str(worksheet.row_values(rownum)).encode('utf-8')) 

    csvfile.close()