Ich verwende win32.client in Python, um meine .xlsx- und .xls-Datei in eine .csv-Datei zu konvertieren. Wenn ich diesen Code ausführen, wird ein Fehler ausgegeben. Mein Code lautet:
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")
Ich kann den Fehler in diesem Code nicht finden. Bitte helfen.
Ich würde xlrd verwenden - es ist schneller, plattformübergreifend und arbeitet direkt mit der Datei. Eine Sache zu beachten - es funktioniert nicht bei xlsx-Dateien - Sie müssen Ihre Excel-Datei also als xls speichern. Edit: Ab Version 0.8.0 liest xlrd
sowohl XLS- als auch XLSX-Dateien.
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()
Ich würde pandas
verwenden. Die rechenintensiven Teile sind in Cython oder C-Erweiterungen geschrieben, um den Prozess zu beschleunigen, und die Syntax ist sehr sauber. Wenn Sie beispielsweise "Sheet1" aus der Datei "your_workbook.xls" in die Datei "your_csv.csv" umwandeln möchten, verwenden Sie einfach die oberste Funktion read_Excel
und die Methode to_csv
aus der Klasse DataFrame
wie folgt:
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')
Die Einstellung von encoding='utf-8'
verringert die in anderen Antworten erwähnte UnicodeEncodeError
.
Vielleicht findet jemand diesen gebrauchsfertigen Code nützlich. Es ermöglicht das Erstellen von CSVs aus allen Tabellenblättern in der Excel-Arbeitsmappe.
# -*- 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 __== "__main__":
csv_from_Excel(sys.argv[1])
Ich würde csvkit verwenden, das xlrd (für xls) und openpyxl (für xlsx) verwendet, um nahezu alle Tabellendaten in csv zu konvertieren.
Nach der Installation mit ihren Abhängigkeiten geht es um Folgendes:
python in2csv myfile > myoutput.csv
Es kümmert sich um alle Formaterkennungsprobleme, sodass Sie nahezu jede tabellarische Datenquelle übergeben können. Es ist auch plattformübergreifend (keine Win32-Abhängigkeit).
xlsx2csv ist schneller als Pandas und xlrd.
xlsx2csv -s 0 crunchbase_monthly_.xlsx cruchbase
Eine Excel-Datei wird normalerweise mit n Blattname geliefert.
-s is sheetname index.
anschließend wird der cruchbase-Ordner erstellt. Jedes zu xlsx gehörende Blatt wird in eine einzige CSV-Datei konvertiert.
p.s. csvkit ist auch großartig.
@andi Ich habe deinen Code getestet, es funktioniert super, ABER
In meinen Blättern steht eine Kolumne wie diese
2013-03-06T04: 00: 00
datum und Uhrzeit in derselben Zelle
Während des Exports wird es verstümmelt. Dies ist in der exportierten Datei so
41275.0416667
andere Spalten sind in Ordnung.
csvkit auf der anderen Seite ist mit dieser Spalte in Ordnung, exportiert jedoch nur ein Blatt, und meine Dateien enthalten viele.
Zitiert eine Antwort von Scott Ming , die mit einer Arbeitsmappe arbeitet, die mehrere Blätter enthält:
Hier ist ein Python-Skript getsheets.py ( mirror ). Sie sollten pandas
und xlrd
installieren, bevor Sie es verwenden.
Führen Sie das aus:
pip3 install pandas xlrd # or `pip install pandas xlrd`
Wie funktioniert es?
$ 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.
Konvertieren in mehrere xlsx:
$ python3 getsheets.py goods_temp.xlsx
Sheet.xlsx Done!
Sheet1.xlsx Done!
All Done!
Konvertieren Sie in mehrere CSV-Dateien:
$ 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()
Lesen Sie zuerst Ihre Excel-Tabelle in pandas. Der folgende Code importiert Ihre Excel-Tabelle in pandas als OrderedDict-Typ, der Ihr gesamtes Arbeitsblatt als Datenrahmen enthält. Verwenden Sie dann einfach worksheet_name als Schlüssel, um auf ein bestimmtes Arbeitsblatt zuzugreifen Speichern Sie als Datenframe nur das erforderliche Arbeitsblatt als CSV-Datei mithilfe von df.to_csv (). Hoffe, dies funktioniert in Ihrem Fall.
import pandas as pd
df = pd.read_Excel('YourExcel.xlsx', sheet_name=None)
df['worksheet_name'].to_csv('YourCsv.csv')
Wenn Ihre Excel-Datei nur ein Arbeitsblatt enthält, verwenden Sie einfach den folgenden Code:
import pandas as pd
df = pd.read_Excel('YourExcel.xlsx')
df.to_csv('YourCsv.csv')
Wenn jemand alle Excel-Arbeitsblätter von einer einzelnen Excel-Arbeitsmappe in die verschiedenen CSV-Dateien konvertieren möchte, versuchen Sie den folgenden Code:
import pandas as pd
def excelTOcsv(filename):
df = pd.read_Excel(filename, sheet_name=None)
for key, value in df.items():
return df[key].to_csv('%s.csv' %key)
Diese Funktion arbeitet als mehrere Excel-Tabellen derselben Excel-Arbeitsmappe in mehrere CSV-Dateikonverter. Wobei key der Blattname und value der Inhalt innerhalb des Blatts ist.
So sehr ich es hasse, mich auf die proprietäre Windows Excel-Software zu verlassen, die nicht plattformübergreifend ist, konnten meine Tests von csvkit
für .xls, die xlrd
unter der Haube verwenden, Daten nicht korrekt analysiert werden (Auch wenn die Befehlszeilenparameter zur Angabe des Strptime-Formats verwendet werden).
Beispiel: diese xls-Datei konvertiert beim Parsen mit csvkit
die Zelle G1
Von 12/31/2002
In 37621
über Excel nach csv konvertiert -> save_as (unter Verwendung von unten) Zelle G1
wird "December 31, 2002"
sein.
import re
import os
from win32com.client import Dispatch
xlCSVMSDOS = 24
class CsvConverter(object):
def __init__(self, *, input_dir, output_dir):
self._Excel = None
self.input_dir = input_dir
self.output_dir = output_dir
if not os.path.isdir(self.output_dir):
os.makedirs(self.output_dir)
def isSheetEmpty(self, sheet):
# https://archive.is/RuxR7
# WorksheetFunction.CountA(ActiveSheet.UsedRange) = 0 And ActiveSheet.Shapes.Count = 0
return \
(not self._Excel.WorksheetFunction.CountA(sheet.UsedRange)) \
and \
(not sheet.Shapes.Count)
def getNonEmptySheets(self, wb, as_name=False):
return [ \
(sheet.Name if as_name else sheet) \
for sheet in wb.Sheets \
if not self.isSheetEmpty(sheet) \
]
def saveWorkbookAsCsv(self, wb, csv_path):
non_empty_sheet_names = self.getNonEmptySheets(wb, as_name=True)
assert (len(non_empty_sheet_names) == 1), \
"Expected exactly 1 sheet but found %i non-empty sheets: '%s'" \
%(
len(non_empty_sheet_names),
"', '".join(name.replace("'", r"\'") for name in non_empty_sheet_names)
)
wb.Worksheets(non_empty_sheet_names[0]).SaveAs(csv_path, xlCSVMSDOS)
wb.Saved = 1
def isXlsFilename(self, filename):
return bool(re.search(r'(?i)\.xls$', filename))
def batchConvertXlsToCsv(self):
xls_names = Tuple( filename for filename in next(os.walk(self.input_dir))[2] if self.isXlsFilename(filename) )
self._Excel = Dispatch('Excel.Application')
try:
for xls_name in xls_names:
csv_path = os.path.join(self.output_dir, '%s.csv' %os.path.splitext(xls_name)[0])
if not os.path.isfile(csv_path):
workbook = self._Excel.Workbooks.Open(os.path.join(self.input_dir, xls_name))
try:
self.saveWorkbookAsCsv(workbook, csv_path)
finally:
workbook.Close()
finally:
if not len(self._Excel.Workbooks):
self._Excel.Quit()
self._Excel = None
if __== '__main__':
self = CsvConverter(
input_dir='C:\\data\\xls\\',
output_dir='C:\\data\\csv\\'
)
self.batchConvertXlsToCsv()
Das obige Beispiel nimmt einen input_dir
, Der .xls enthält, und gibt ihn als .csv an output_dir
Aus - es wird assert
, dass sich genau 1 nicht leeres Blatt in den .xls befindet ; Wenn Sie mehrere Blätter in mehrere CSVs verarbeiten müssen, müssen Sie saveWorkbookAsCsv
bearbeiten.
Die Verwendung von xlrd ist ein fehlerhafter Weg, dies zu tun, da Sie die Datumsformate in Excel verlieren.
Mein Anwendungsfall ist der folgende.
Nehmen Sie eine Excel-Datei mit mehr als einem Blatt und konvertieren Sie jedes in eine eigene Datei.
Ich habe dies mit der xlsx2csv-Bibliothek getan und dies mit einem Subprozess aufgerufen.
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()
Wir können Pandas lib von Python verwenden, um die xls-Datei in die csv-Datei zu konvertieren Der folgende Code konvertiert die xls-Datei in die csv-Datei ..__
Excel-Datei vom lokalen Pfad lesen:
df = pd.read_Excel("C:/Users/IBM_ADMIN/BU GPA Scorecard.xlsx",sheetname=1)
Zuschneidefelder auf Spalten:
df.columns = df.columns.str.strip()
Datenrahmen an CSV-Datei senden, die durch Pipesymbol getrennt und ohne Index dargestellt wird:
df.to_csv("C:/Users/IBM_ADMIN/BU GPA Scorecard csv.csv",sep="|",index=False)
Ich habe alle Antworten getestet, aber sie waren alle zu langsam für mich. Wenn Sie Excel installiert haben, können Sie COM verwenden.
Ich dachte anfangs, es würde langsamer sein, da es alles für die eigentliche Excel-Anwendung laden würde, aber es ist nicht für große Dateien. Vielleicht, weil der Algorithmus zum Öffnen und Speichern von Dateien einen stark optimierten kompilierten Code ausführt, verdienen Microsoft-Leute trotzdem viel Geld.
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 __== '__main__':
main(sys.argv[1])
Dies ist ein sehr unkomplizierter Code, der nicht auf Fehler, Druckhilfe oder irgendetwas prüft. Es wird nur eine CSV-Datei für jede Datei erstellt, die dem in der Funktion eingegebenen Muster entspricht. So können Sie viele Dateien stapeln, die nur die Excel-Anwendung starten Einmal.