2013-07-24 7 views
8

Ich wollte eine Datei mit Text, Zahlen und Daten mit Xlrd auf Python importieren.Python: xlrd anspruchsvolle Daten von schwimmt

habe ich versucht, so etwas wie:

if "/" in worksheet.cell_value: 
    do_this 
else: 
    do_that 

Aber das nützte nichts, wie ich letztere entdeckt Daten als Schwimmer gespeichert sind, keine Strings. So konvertieren sie Typ Datetime Ich habe:

try: 
    get_row = str(datetime.datetime(*xlrd.xldate_as_tuple(worksheet.cell_value(i, col - 1), workbook.datemode))) 
except: 
    get_row = unicode(worksheet.cell_value(i, col - 1)) 

Ich habe eine Ausnahme an Ort und Stelle für, wenn die Zelle Text enthält. Jetzt möchte ich die Zahlen als Zahlen und die Daten als Daten bekommen, weil gerade jetzt alle Zahlen in Daten umgewandelt werden.

Irgendwelche Ideen?

+0

Sie sollten nicht erwarten, Excel zu unterscheiden zwischen Daten und Zahlen, wenn Sie nicht können. – pnuts

Antwort

8

Nun, vergiss es, ich habe eine Lösung gefunden und hier ist es!

try: 
    cell = worksheet.cell(row - 1, i) 
    if cell.ctype == xlrd.XL_CELL_DATE: 
     date = datetime.datetime(1899, 12, 30) 
     get_ = datetime.timedelta(int(worksheet.cell_value(row - 1, i))) 
     get_col2 = str(date + get_)[:10] 
     d = datetime.datetime.strptime(get_col2, '%Y-%m-%d') 
     get_col = d.strftime('%d-%m-%Y') 
    else: 
     get_col = unicode(int(worksheet.cell_value(row - 1, i))) 
except: 
    get_col = unicode(worksheet.cell_value(row - 1, i)) 

Ein bisschen Erklärung: es stellt sich heraus, dass mit xlrd Sie tatsächlich den Typ einer Zelle überprüfen und überprüfen, ob es ein Datum ist oder nicht. Excel scheint auch eine seltsame Möglichkeit zu haben, Tageszeiten zu speichern. Es speichert sie als schwimmt (linker Teil für Tage, rechter Teil für Stunden) und dann dauert es ein bestimmtes Datum (1899, 12, 30, scheint OK zu arbeiten) und addiert die Tage und die Stunden vom Floss, um das Datum zu verursachen. Also, um das Datum zu erstellen, das ich wollte, fügte ich sie nur hinzu und behielt nur die 10 ersten Buchstaben ([: 10]), um die Stunden (00.00.00 oder etwas ...) loszuwerden. Ich änderte auch die Reihenfolge der Tage_Monate-Jahre, weil wir in Griechenland eine andere Reihenfolge verwenden. Schließlich überprüft dieser Code auch, ob er eine Zahl in eine Ganzzahl konvertieren kann (ich möchte keine Gleitkommazahlen in meinem Programm anzeigen ...) und wenn alles fehlschlägt, verwendet es einfach die Zelle, so wie sie ist (falls es solche gibt) Strings in den Zellen ...). Ich hoffe, dass Sie das nützlich finden, ich denke, es gibt andere Threads, die sagen, dass das unmöglich ist oder etwas ...

+1

Excel auf Windows/Mac unterscheiden sich auf den Ursprungspunkt - das ist, was das DateMode-Attribut auf der Arbeitsmappe ist - also sollten Sie das verwenden und nicht hart die Datetime codieren. Es ist auch möglich (obwohl unwahrscheinlich), dass Sie durch das Abschneiden von Elementen aus dem Float (wie Datum und Uhrzeit in Excel gespeichert werden) genügend Informationen abspeichern, die Ihr Datum um einen Tag verschieben. Was wäre näher dran an dieser Stelle ist Ihre ursprüngliche Frage, aber fügen Sie einfach in der Zelle.Typ überprüfen und Sie sind fertig ... –

+0

Die Stunden in Float enthalten sind alle 00.00.00, so ist es nichts ... Und Was ich in meiner ursprünglichen Frage verwendete, war schwierig zu handhaben, vielleicht sogar fehlerhaft, ich weiß nicht warum, also konnte ich die Reihenfolge des Datums nicht ändern (und das ist wichtig ...) – Antoni4040

+0

Die Formel stimmt nicht Windows zB, wenn 'cell_value = 30' Ihre Formel gibt '29-01-1900' zurück, dann sollte '30-01-1900' zurückgegeben werden, siehe [Wie konvertiert man eine bestimmte Ordnungszahl (aus Excel) in ein Datum] (http://stackoverflow.com/q/29387137/4279). ODER (besser) verwenden Sie 'xlrd' Methoden wie in [@chewynougat 'Antwort/Kommentare] (http://stackoverflow.com/a/18016189/4279) gezeigt. Auch "date + get_" ist bereits ein datetime Objekt: es muss nicht in str konvertiert werden, nur um es in datetime zurück zu konvertieren, nur um es in ein anderes Format zu konvertieren - einfach mit 'direkt in ein gewünschtes Format konvertieren. strftime() '. – jfs

9

Ich denke, Sie könnten dies viel einfacher machen, indem Sie die in xlrd verfügbaren Tools verwenden:

cell_type = worksheet.cell_type(row - 1, i) 
cell_value = worksheet.cell_value(row - 1, i) 

if cell_type == xlrd.XL_CELL_DATE: 
    # Returns a tuple. 
    dt_tuple = xlrd.xldate_as_tuple(cell_value, workbook.datemode) 
    # Create datetime object from this tuple. 
    get_col = datetime.datetime(
     dt_tuple[0], dt_tuple[1], dt_tuple[2], 
     dt_tuple[3], dt_tuple[4], dt_tuple[5] 
    ) 
elif cell_type == xlrd.XL_CELL_NUMBER: 
    get_col = int(cell_value) 
else: 
    get_col = unicode(cell_value) 
+6

Zwei Dinge. (1) Sie können ein Tupel mit dem Operator '*' entpacken, also 'get_col = datetime.datetime (* dt_tuple)'. (2) Ab xlrd 0.9.3 gibt es eine Funktion 'xldate.xldate_as_datetime', die anstelle von' xldate_as_tuple' verwendet werden kann. (Um fair zu sein, ist 0.9.3 neuer als diese Antwort.) –