Excel-Formeln auflösen (Openpyxl)

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
pixewakb
User
Beiträge: 1411
Registriert: Sonntag 24. April 2011, 19:43

Ich rufe Excel-Zellen ab, ich bekomme dann auch schon mal Formeln zurück und zwar der Form:

[1] "=2+2"

Da ich die Exel-Dateien selbst erstelle, kann ich ausschließen, dass dort gefährliche Inhalte enthalten sind. Ferner vermeide ich Zellen der Form:

[2] "=2+A2"

Ich habe bislang vor, Formeln der ersteren Form ([1]) mit eval in eine Zahl umzuwandeln, lese (und weiß) allerdings, dass eval nicht gut ist. Meine Fragen sind nun:
  • Warum ist eval eigentlich böse? Ausführen von Code?
  • Wie würdet ihr die Aufgabe angehen? Mein Verfahren funktioniert (technischer Demonstrator...), wäre aber für Denkanstöße durchaus dankbar.
Benutzeravatar
BigZ
User
Beiträge: 30
Registriert: Mittwoch 1. Juli 2015, 21:18
Wohnort: Hamburg
Kontaktdaten:

eval ist in sofern böse, weil es Dinge wie

Code: Alles auswählen

eval("__import__('os').remove('datei.txt')")
erlaubt.
Wenn du sicher weißt das solche Angaben niemals vorkommen, könntest du es benutzen, aber der beste Ansatz ist es nicht, da es das Programm anfällig für, ich nennen es mal, "Code Injection" ist.
Um das zu umgehen könntest Strings "whitelisten" die von eval verarbeitet werden sollen.
Stümperhaftes Beispiel:

Code: Alles auswählen

teststring = '2+2'
whitelist = ['+', '-', '*', '/']
result = [i for i in teststring if i.isdigit() or i in whitelist]
if len(''.join(result)) == len(teststring):
    print(eval(''.join(result)))
Ansonsten bietet Python, so wie es aussieht, Bibliotheken die sich um so was für dich kümmern könnten, laut Stackoverflow
"Ist noch λ?"
"Ja, aber das ϕ ist noch ϱ"
Benutzeravatar
pixewakb
User
Beiträge: 1411
Registriert: Sonntag 24. April 2011, 19:43

Ich habe inzwischen die Lösung gefunden, die von openpyxl bereitgestellt wird. Manchmal ist die Lösung so einfach :( Damit geht es m. E. simpel.

Ich habe :( ein Excel-Testfile mit folgenden Zellinhalten (A1:A5) erstellt:
[codebox=text file=Unbenannt.txt]1
2
=A1+A2
=1+A3
5[/code]
Nun führe ich folgenden Quellcode aus:

Code: Alles auswählen

from openpyxl import load_workbook

xlsxfile = "excelfile.xlsx"

wb = load_workbook(filename = xlsxfile, data_only = True) # 1

sheet_ranges = wb['raw']

for i in range(1,6):
    print(sheet_ranges['A{}'.format(i)].value)
Wichtig ist der Parameter (# 1) "data_only = True", der die im File gecachten Ergebnisse der berechneten Formeln ausliest. Problematisch ist hier nur, dass dieser Quellcode bei Zellen mit Formeln wohl None ausliefert, wenn das xlsx-file z. B. mit openpyxl geschrieben wurde und die Datei vor dem Lesen nicht mehr mit Excel geladen wurde. Excel hätte beim Öffnen nämlich die Formeln ausgelesen und dann dort Werte hinterlegt.

In der Konsole erhalte ich bei data_only = True dann folgendes Ergebnis:
[codebox=text file=Unbenannt.txt]1
2
3
4
5[/code]
Antworten