2012-03-27 18 views
37

Sto usando win32.client in python per convertire il mio file .xlsx e .xls in un file .csv. Quando eseguo questo codice sta dando un errore. Il mio codice è:convertitore xls-csv

def convertXLS2CSV(aFile): 
    '''converts a MS Excel file to csv w/ the same name in the same directory''' 

    print "------ beginning to convert XLS to CSV ------" 

    try: 
     import win32com.client, os 
     from win32com.client import constants as c 
     excel = win32com.client.Dispatch('Excel.Application') 

     fileDir, fileName = os.path.split(aFile) 
     nameOnly = os.path.splitext(fileName) 
     newName = nameOnly[0] + ".csv" 
     outCSV = os.path.join(fileDir, newName) 
     workbook = excel.Workbooks.Open(aFile) 
     workbook.SaveAs(outCSV, c.xlCSVMSDOS) # 24 represents xlCSVMSDOS 
     workbook.Close(False) 
     excel.Quit() 
     del excel 

     print "...Converted " + nameOnly + " to CSV" 
    except: 
     print ">>>>>>> FAILED to convert " + aFile + " to CSV!" 

convertXLS2CSV("G:\\hello.xlsx") 

Non riesco a trovare l'errore in questo codice. Per favore aiuto.

+2

Si prega di inviare l'errore e full taceback – agf

+7

rimuovere la prova/tranne prima, non si otterrà un errore utile come quello. – SpliFF

risposta

50

Vorrei usare xlrd - è più veloce, multipiattaforma e funziona direttamente con il file. Una cosa da notare - non funziona sui file xlsx - quindi dovresti salvare il tuo file Excel come xls. Modifica: Dalla versione 0.8.0, xlrd legge sia i file XLS che XLSX.

import xlrd 
import csv 

def csv_from_excel(): 

    wb = xlrd.open_workbook('your_workbook.xls') 
    sh = wb.sheet_by_name('Sheet1') 
    your_csv_file = open('your_csv_file.csv', 'wb') 
    wr = csv.writer(your_csv_file, quoting=csv.QUOTE_ALL) 

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

    your_csv_file.close() 
+2

Non dovrebbe essere 'wr.writerow (sh.row_values ​​(rownum))'? Vedi [qui] (https://secure.simplistix.co.uk/svn/xlrd/trunk/xlrd/doc/xlrd.html#sheet.Sheet.row_values-method). – kuujo

+2

Supporta la conversione datetime da xls datmode al normale datetime – sharafjaffri

+0

La versione più recente funziona per i file xlsx: https://pypi.python.org/pypi/xlrd/0.9.2 – Jetse

17

userei csvkit, che utilizza XLRD (per xls) e openpyxl (per xlsx) per convertire quasi tutti i dati tabulari in formato CSV.

Una volta installato, con le sue dipendenze, è una questione di:

python in2csv myfile > myoutput.csv 

Si prende cura di tutte le questioni di rilevamento del formato, in modo da poter passare praticamente qualsiasi fonte di dati tabulari. È anche cross-platform (nessuna dipendenza da win32).

+0

Come questo strumento anche. Non abbastanza pertinente a questa domanda, ma ho incontrato una menzione di questa cosa csvkit in [questo libro] (http://shop.oreilly.com/product/0636920032823.do) insieme ad altri strumenti di elaborazione dati che ti consentono per trasformare i dati direttamente all'interno della tua shell. – devforfu

27

Forse qualcuno trova utile questo pezzo di codice pronto all'uso. Permette di creare CSV da tutti i fogli di lavoro nella cartella di lavoro di Excel.

enter image description here

# -*- coding: utf-8 -*- 
import xlrd 
import csv 
from os import sys 

def csv_from_excel(excel_file): 
    workbook = xlrd.open_workbook(excel_file) 
    all_worksheets = workbook.sheet_names() 
    for worksheet_name in all_worksheets: 
     worksheet = workbook.sheet_by_name(worksheet_name) 
     with open('{}.csv'.format(worksheet_name), 'wb') as your_csv_file: 
      wr = csv.writer(your_csv_file, quoting=csv.QUOTE_ALL) 
      for rownum in xrange(worksheet.nrows): 
       wr.writerow([unicode(entry).encode("utf-8") for entry in worksheet.row_values(rownum)]) 

if __name__ == "__main__": 
    csv_from_excel(sys.argv[1]) 
+0

solo un paio di annotazioni: alcuni fogli di lavoro potrebbero essere vuoti. Non vedo alcuna utilità nella generazione di file CSV vuoti, meglio fare una valutazione precedente su worksheet.nrows> 0 prima di fare qualsiasi cosa. –

+0

anche, sarebbe meglio usare i contesti per il file CSV;) –

+1

Puoi saltare i fogli vuoti con 'se worksheet.nrows == 0: continue' – duhaime

25

userei pandas. Le parti computazionalmente pesanti sono scritte in cython o c-extensions per velocizzare il processo e la sintassi è molto pulita. Ad esempio, se si desidera trasformare "Sheet1" dal file "your_workbook.xls" nel file "your_csv.csv", si utilizza semplicemente la funzione di livello superiore read_excel e il metodo dalla classe DataFrame come segue:

import pandas as pd 
data_xls = pd.read_excel('your_workbook.xls', 'Sheet1', index_col=None) 
data_xls.to_csv('your_csv.csv', encoding='utf-8') 

L'impostazione encoding='utf-8' allevia lo UnicodeEncodeError menzionato in altre risposte.

+0

non funziona nel caso in cui tu abbia testo in altre lingue in rows.it mostra ?? ? nel testo –

+1

@philE Questo è troppo lento. Usa xlsx2csv – CodeFarmer

+0

qualche consiglio su come gestire i caratteri di nuova riga che potrebbero trovarsi nei contenuti delle celle Excel? – Gyan

2

@Andi Ho provato il codice, funziona benissimo, MA

Nei miei fogli c'è una colonna come questo

2013-03-06T04: 00: 00

la data e l'ora nel stessa cella

ottiene confuso durante l'esportazione, è come questo nel file esportato

41275,0416667

altre colonne sono ok.

csvkit, dall'altra parte, funziona bene con quella colonna ma esporta solo un foglio ei miei file ne hanno molti.

3

xlsx2csv è più veloce rispetto a panda e xlrd.

xlsx2csv -s 0 crunchbase_monthly_.xlsx cruchbase 

file di Excel solitamente fornito con n nome foglio.

-s is sheetname index. 

poi, verrà creata la cartella cruchbase, ciascun foglio appartiene xlsx saranno convertiti in un singolo csv.

p.s. csvkit è fantastico anche.

0

L'utilizzo di xlrd è un modo imperfetto per fare ciò, perché si perdono i formati di data in Excel.

Il mio caso d'uso è il seguente.

Acquisisci un file Excel con più di un foglio e converti ciascuno in un file a sé stante.

Ho fatto questo usando la libreria xlsx2csv e chiamandolo usando un sottoprocesso.

import csv 
import sys, os, json, re, time 
import subprocess 

def csv_from_excel(fname): 
    subprocess.Popen(["xlsx2csv " + fname + " --all -d '|' -i -p " 
         "'<New Sheet>' > " + 'test.csv'], shell=True) 

    return 

lstSheets = csv_from_excel(sys.argv[1]) 

time.sleep(3) # system needs to wait a second to recognize the file was written 

with open('[YOUR PATH]/test.csv') as f: 
    lines = f.readlines() 
    firstSheet = True 

    for line in lines: 
     if line.startswith('<New Sheet>'): 
      if firstSheet: 
       sh_2_fname = line.replace('<New Sheet>', '').strip().replace(' - ', '_').replace(' ','_') 
       print(sh_2_fname) 
       sh2f = open(sh_2_fname+".csv", "w") 
       firstSheet = False 
      else: 
       sh2f.close() 
       sh_2_fname = line.replace('<New Sheet>', '').strip().replace(' - ', '_').replace(' ','_') 
       print(sh_2_fname) 
       sh2f = open(sh_2_fname+".csv", "w") 
     else: 
      sh2f.write(line) 
sh2f.close() 
0

Ho testato tutti gli autori, ma erano tutti troppo lenti per me. Se hai installato Excel puoi usare il COM.

Inizialmente pensavo che sarebbe stato più lento poiché caricherà tutto per l'effettiva applicazione Excel, ma non per file enormi. Forse perché l'algoritmo per l'apertura e il salvataggio dei file esegue un codice compilato altamente ottimizzato, dopotutto i ragazzi di Microsoft guadagnano un sacco di soldi.

import sys 
import os 
import glob 
from win32com.client import Dispatch 

def main(path): 
    excel = Dispatch("Excel.Application") 
    if is_full_path(path): 
     process_file(excel, path) 
    else: 
     files = glob.glob(path) 
     for file_path in files: 
      process_file(excel, file_path) 
    excel.Quit() 

def process_file(excel, path): 
    fullpath = os.path.abspath(path) 
    full_csv_path = os.path.splitext(fullpath)[0] + '.csv' 
    workbook = excel.Workbooks.Open(fullpath) 
    workbook.Worksheets(1).SaveAs(full_csv_path, 6) 
    workbook.Saved = 1 
    workbook.Close() 


def is_full_path(path): 
    return path.find(":") > -1 

if __name__ == '__main__': 
    main(sys.argv[1]) 

Questo è un codice molto crudo e non verifica la presenza di errori, aiuto stampa o nulla, sarà solo creare un file CSV per ogni file che corrisponde al modello immesso nella funzione in modo da poter in batch processo di molti file che lanciano l'applicazione Excel una sola volta.

1

Citando un answer da Scott Ming, che lavora con cartella di lavoro contenente più fogli:

Ecco uno script python getsheets.py (mirror), è necessario installare pandas e xlrd prima di utilizzarlo.

Esegui questo:

pip3 install pandas xlrd # or `pip install pandas xlrd` 

come funziona?

$ python3 getsheets.py -h 
Usage: getsheets.py [OPTIONS] INPUTFILE 

Convert a Excel file with multiple sheets to several file with one sheet. 

Examples: 

    getsheets filename 

    getsheets filename -f csv 

Options: 
-f, --format [xlsx|csv] Default xlsx. 
-h, --help    Show this message and exit. 

Converti in diversi xlsx:

$ python3 getsheets.py goods_temp.xlsx 
Sheet.xlsx Done! 
Sheet1.xlsx Done! 

All Done! 

Conversione in diversi csv:

$ python3 getsheets.py goods_temp.xlsx -f csv 
Sheet.csv Done! 
Sheet1.csv Done! 

All Done! 

getsheets.py:

# -*- coding: utf-8 -*- 

import click 
import os 
import pandas as pd 


def file_split(file): 
    s = file.split('.') 
    name = '.'.join(s[:-1]) # get directory name 
    return name 


def getsheets(inputfile, fileformat): 
    name = file_split(inputfile) 
    try: 
     os.makedirs(name) 
    except: 
     pass 

    df1 = pd.ExcelFile(inputfile) 
    for x in df1.sheet_names: 
     print(x + '.' + fileformat, 'Done!') 
     df2 = pd.read_excel(inputfile, sheetname=x) 
     filename = os.path.join(name, x + '.' + fileformat) 
     if fileformat == 'csv': 
      df2.to_csv(filename, index=False) 
     else: 
      df2.to_excel(filename, index=False) 
    print('\nAll Done!') 


CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help']) 


@click.command(context_settings=CONTEXT_SETTINGS) 
@click.argument('inputfile') 
@click.option('-f', '--format', type=click.Choice([ 
    'xlsx', 'csv']), default='xlsx', help='Default xlsx.') 
def cli(inputfile, format): 
    '''Convert a Excel file with multiple sheets to several file with one sheet. 

    Examples: 

    \b 
     getsheets filename 

    \b 
     getsheets filename -f csv 
    ''' 
    if format == 'csv': 
     getsheets(inputfile, 'csv') 
    else: 
     getsheets(inputfile, 'xlsx') 


cli() 
0

possiamo usare Pandas lib di Python per conevert xls file nel file csv Sotto il codice convertiremo il file xls nel file csv. panda di importazione come pd

Leggi file Excel da Percorso locale:

df = pd.read_excel("C:/Users/IBM_ADMIN/BU GPA Scorecard.xlsx",sheetname=1) 

gli ambienti, Trim presenti su colonne:

df.columns = df.columns.str.strip() 

Invia frame di dati in un file CSV, che sarà simbolo di pipe delimted e senza Indice:

df.to_csv("C:/Users/IBM_ADMIN/BU GPA Scorecard csv.csv",sep="|",index=False)