2017-01-29 5 views
-2

Gibt es eine einfache Möglichkeit, festzustellen, wann Sie beim Arbeiten mit openpyx das Ende einer Arbeitsblattdatei erreicht haben? Oder hat jemand eine einfache Idee, wie man diese Aufgabe in Python3 programmiert? Ich arbeite an einem Programm, das durch Zeilen iteriert, wählt & schreibt bestimmte Daten neu. Ich möchte, dass das Programm eigenständig aus der Schleife springen kann, ohne am Anfang eine Zahl eingeben zu müssen.Ermitteln des Dateiendes in Tabellenkalkulationen

Derzeit bin ich nur die folgende Schleife, aber es funktioniert nur, weil ich die Datei einfach an den Leitungsenden 49:

while i <=50: 

Ich war etwas bedenkt, dass für mehrere leere Zeilen in einer Reihe überprüfen würde, wie dieses Stück Code, um die Schleife zu starten, aber es scheint sehr unvollkommen:

while sheet["A"+str(i)].value!=0 and sheet["A"+str(i+1)].value!=0 and sheet["A"+str(i+2)].value!=0: 

Alle Vorschläge wären hilfreich.

Dank


Die einfache Antwort lautet:

lastrow=sheet.max_row

Der Zähler in der Schleife kann dann bei lastrow beenden eingestellt werden.

Danke für Ihre Eingabe Roland.

Leider enthält die Dokumentation für openpyx, die ich verwendet habe, diese Funktion nicht, Charlie.

+0

Dies ist definitiv nicht der Weg, um die API zu verwenden. Bitte verbringen Sie ein wenig mehr Zeit mit dem Lesen der openpyxl Dokumentation. –

Antwort

1

Sie können mit den Methoden openpyxl.worksheet.Worksheet.iter_rows() oder openpyxl.worksheet.Worksheet.iter_columns() über ein Arbeitsblatt iterieren. Alternativ können Sie auch die openpyxl.worksheet.Worksheet.rows oder openpyxl.worksheet.Worksheet.colums Eigenschaften verwenden. Das sind Iteratoren, die über die gesamte Datei funktionieren sollen.


Aber für meine eigenen begrenzten Zwecke xlsx Dateien lesen, neige ich dazu, sie einfach zu öffnen, als ZipFile und die Daten greifen, die ich von den einzelnen Blättern mit regulären Ausdrücken will. Funktioniert gut für mich.

Unten ist ein Beispiel. Es extrahiert die Stunden, die an verschiedenen Projekten gearbeitet wurden, aus einer xlsx-Datei mit Stundenzetteln für ein ganzes Jahr. Für jedes Blatt (das einen einzelnen Arbeitstag darstellt) muss ich die Projektnummern und Stunden aus einem bestimmten Bereich von Zellen extrahieren.

from collections import defaultdict 
from zipfile import ZipFile 
import os.path 
import re 
import sys 

__version__ = '1.1.0' 


if len(sys.argv) == 1: 
    binary = os.path.basename(sys.argv[0]) 
    print("{} ver. {}".format(binary, __version__), file=sys.stderr) 
    print("Usage: {} [file ...]".format(binary), file=sys.stderr) 
    sys.exit(0) 
del sys.argv[0] # delete the name of the script. 
# Real work starts here. 
projects = defaultdict(int) 
wbre = re.compile('<sheet name="[0-9]{4}-?[0-9]{1,2}-?[0-9]{1,2}' 
       '".*?"rId([0-9]{1,3})"/>') 
Anum = re.compile('<c r="A([0-9]{1,2})" s="[^"]+"><v>(.*?)</v></c>') 
Astr = re.compile('<c r="A([0-9]{1,2})" s="[^"]+" t="s"><v>(.*?)</v></c>') 
shre = re.compile('<t[^>]*>(.*?)</t>') 
Fre = re.compile('<c r="F([0-9]{1,2})" s="[^"]+"><f.*?><v>(.*?)</v></c>') 
for fn in sys.argv: 
    z = ZipFile(fn) 
    # Create a list of the shared strings. 
    with z.open('xl/sharedStrings.xml') as sstr: 
     ssdata = sstr.read().decode('utf-8') 
    shstr = shre.findall(ssdata) 
    # Create a list of worksheet numbers. The name of the workheets matches 
    # NNNN-NN-NN where N is in 0--9. 
    with z.open('xl/workbook.xml') as wb: 
     wbdata = wb.read().decode('utf-8') 
    matches = wbre.findall(wbdata) 
    for shnum in matches: 
     with z.open('xl/worksheets/sheet{}.xml'.format(shnum)) as ws: 
      wsdata = ws.read().decode('utf-8') 
     # Extract the data from column A, rows 4 - 22. 
     A = {int(k): v for k, v in Anum.findall(wsdata) if 3 < int(k) < 23} 
     As = {int(k): shstr[int(v)] for k, v in Astr.findall(wsdata) 
      if 3 < int(k) < 23} 
     A.update(As) 
     # Extract the data from column F, rows 4 - 22. 
     F = {int(k): float(v) for k, v in Fre.findall(wsdata) 
      if 3 < int(k) < 23} 
     idxA, idxF = set(A.keys()), set(F.keys()) 
     # Cross-reference project numbers and hours. 
     for k in idxA & idxF: 
      projects[A[k]] += F[k] 
     for k in idxF - idxA: 
      projects['geen'] += F[k] 
    z.close() 
    t = sorted([(k, v) for k, v in projects.items()], key=lambda x: x[1], 
      reverse=True) 
    total = sum(d[1] for d in t) 
    for k, v in t: 
     print('{:5}: {:.1f} uur ({:.1f}%)'.format(k, v, 100*v/total)) 
    print('totaal: {:.0f} uur'.format(sum(projects.values()))) 

diesen Code zu entwickeln, ich eine xlsx-Datei entpackt und listete die XML-Dateien in es mit xmllint --format sie vom Menschen lesbar zu machen.

+0

Eigentlich funktioniert das auch nicht. "iter_rows()" benötigt die gleichen Werte, die ich im einfachen Zähler eingestellt habe. Ich versuche einen Weg zu finden, wie das Programm selbst entscheiden kann, was diese Werte sind. Auch die Art und Weise, wie diese Tabellenkalkulationen formatiert sind, möchte ich nicht in jeder Zeile sehen. Durch die Erhöhung der einfachen Zählerschleife kann ich diejenigen vermeiden, die ich nicht möchte. Also bin ich meinem Problem wirklich nicht näher als zuvor. – Reuben

Verwandte Themen