[Excel-Export] Design Python OOo-SpreadSheet-Modul

Du hast eine Idee für ein Projekt?
Antworten
tabellar
User
Beiträge: 186
Registriert: Mittwoch 4. September 2002, 15:28

Hier koennen wir unser neues OOo-SpreadSheet-Modul designen... :)

Edit (Leonidas): Topic verändert und verschoben.
tabellar
User
Beiträge: 186
Registriert: Mittwoch 4. September 2002, 15:28

joerg hat geschrieben: ...Das sind also beste Voraussetzungen für ein solches Python-Modul. Vielleicht sollten wir mal grob entwerfen, wie die Struktur des/der Module ungefähr aussehen könnte. Ich denke, für den Anfang reicht es, wenn wir nur die Daten des Spreadsheets füllen, und später dann Funktionalität für die Formatierungen dazunehmen...
Ich haette mal einen Vorschlag, wie die Benutzung des OOo-Moduls aussehen koennte:

Code: Alles auswählen

from OOSpSheet import *

#Neue OOSpreadSheet Instanz
ooSpSheet=OOSpSheet()

#Sheet Instanz
sheet1=ooSpSheet.Sheets.Add()

#Sheet Eigenschaften
sheet1.name="OOoTestSheet"

#Sheet Daten
sheet1.Range("A1:C1").Value="11","12","13"
sheet1.Range("A2:C2").Value="21","22","23"
sheet1.Range("A3:C3").Value="31","32","33"
sheet1.Range("C4:C4").Value="=SUMME(C1:C3)"

#Exportpfad
ooSpSheet.ExportPath="/tmp/ooSpSheet.sxc"

#Export
ooSpSheet.Export()

Gruss tabellar
joerg
User
Beiträge: 188
Registriert: Samstag 17. August 2002, 17:48
Wohnort: Berlin
Kontaktdaten:

tabellar hat geschrieben:

Code: Alles auswählen

[...]
sheet1.Range("A1:C1").Value="11","12","13"
[...]
Warum das Rad neu erfinden? Das Zuweisen/Holen von Werten über Indizes geht in Python prinzipiell über die eckigen Klammern, das kann man hier auch verwenden. Ich habe mal testweise eine SpreadSheet-Basisklasse gemacht, bei der man alternativ über Row/Column-Indizes oder symbolische Namen (Spaltenbuchstabe, Reihenzahl) gehen kann, auch mit Slices:
s = SpreadSheet()
s['B3'] = 15
print s[2,1] # ist das selbe
s['C7':'C19'] = range(13)
print s['A1':'F12']
das geht alles schon, und macht genau das, was man denkt. Intern funktioniert das Speichern über ein Dictionary. In den nächsten Tagen stelle ich die Klasse hier mal zur Diskussion als eine der Grundlagen für so ein Modul.

Was noch nicht klappt, ist eine zuverlässige Namen<->Index-Umrechnung für alles ab 'Z'. Wer hat eine einfache Idee, wie man die typische Reihe A...Z,AA...AZ, BA...BZ einfach auf einen linearen Index umrechnet, und zurück?
Jan

joerg hat geschrieben: Was noch nicht klappt, ist eine zuverlässige Namen<->Index-Umrechnung für alles ab 'Z'. Wer hat eine einfache Idee, wie man die typische Reihe A...Z,AA...AZ, BA...BZ einfach auf einen linearen Index umrechnet, und zurück?
Ich bin nicht so vertraut mit Eurem Projekt, aber vielleicht hilft das Folgende ein Bisschen weiter:

Code: Alles auswählen

def int2letters(zahl):        
    return ("%s%s"%(' ABCDEFGHIJKLMNOPQRSTUVWXYZ'[(zahl-1)/26],'ABCDEFGHIJKLMNOPQRSTUVWXYZ'[(zahl % 26)-1])).strip()

def letters2int(str):
    try:
        return ((ord(str[-2]) - ord('A') + 1) * 26) + ord(str[-1]) - ord('A') + 1
    except:
        return ord(str[-1]) - ord('A') + 1
 
for i in range(1,28):
        print i,int2letters(i),letter2int(int2letters(i))

for i in range(670,703):
        print i,int2letters(i),letter2int(int2letters(i))
Ich denke aber, wenn das ganze nur bis "ZZ" gehen soll, wären Übersetzungstabellen wesentlich performanter, in der einen Richtung als Liste und in die andere als Dictionary, auch wenn das gerade keine große Herausforderung ist :-)

Jan - ab sofort nur noch als Gast, hab die Faxen dicke ;-)
tabellar
User
Beiträge: 186
Registriert: Mittwoch 4. September 2002, 15:28

joerg hat geschrieben: Warum das Rad neu erfinden? Das Zuweisen/Holen von Werten über Indizes geht in Python prinzipiell über die eckigen Klammern, das kann man hier auch verwenden.
Der obige Code-Vorschlag ist an die Excel-COM Schnittstelle angelehnt...
Mit einem so aehnlichen Objektmodell koennen wir auch solche Dinge wie Formatieren und aehnliches realisieren:

Z.B.:

Code: Alles auswählen

...
s.Range['A1':'F12'].Font.Bold=1
...
joerg
User
Beiträge: 188
Registriert: Samstag 17. August 2002, 17:48
Wohnort: Berlin
Kontaktdaten:

Jan hat geschrieben: Ich denke aber, wenn das ganze nur bis "ZZ" gehen soll, wären Übersetzungstabellen wesentlich performanter, in der einen Richtung als Liste und in die andere als Dictionary, auch wenn das gerade keine große Herausforderung ist :-)

Jan - ab sofort nur noch als Gast, hab die Faxen dicke ;-)
Deine Lösung ist gut! Ich war an dem Problem irgendwie denkblockiert, wollte aber auch eine 'allgemeine Lösung' suchen. Aber Du hast recht, Übersetzungstabellen sind ca. um den Faktor 30..40 schneller...
Jörg
tabellar
User
Beiträge: 186
Registriert: Mittwoch 4. September 2002, 15:28

joerg hat geschrieben: ... Ich habe mal testweise eine SpreadSheet-Basisklasse gemacht, bei der man alternativ über Row/Column-Indizes oder symbolische Namen (Spaltenbuchstabe, Reihenzahl) gehen kann, auch mit Slices:
...
Ich hab mir nochmal Gedanken ueber die Objektstruktur des Moduls gemacht. In OOo oder Excel weisen wir ja Zellenobjekte Werte zu(Value,Font,...). Sollten wir also nicht auch gleich von einer Zellen-Basisklasse ausgehen? Im Prinzip brauchen wir doch ZellObjekte, die in einem Bereichsobjekt gespeichert sind und auf die ueber entsprechende Methoden zugegriffen werden kann.

Wenn wir also z.B. eine Basisklasse class Cell: mit den Eigenschaften Value,Font,etc. haben, koennten Instanzen davon in Deiner Dictionary-Basisklasse als Key-Value Paare abgelegt werden. Ein Schluessel waere hierbei entweder ein A1, ein (1,1) oder eine eindeutige ID (Umrechnungstabelle???) die das A1 oder (1,1) repraesentiert. Das Value ist dann das Objekt selbst.

Die Objektstruktur in dem Modul koennte also dann vielleicht so aussehen:

document
.Sheets -> Sheet-Containerobjklasse
..Sheet -> Sheet-Objekt
...Cells -> Zellen-Containerklasse oder Bereichsobjekt(Range)
....Cell -> Zellen-Objekt

Code: Alles auswählen

...
s.Cells('A1').Value='Hallo'
cell=s.Cells('1,2')
cell.Value='Joerg'
s.Cells('C7:C19').Value= range(13)
s.Cells('B1:B3').Value=['a','b','c']
s.Cells('A1:B2').Font='Arial'
s.Cells('A1:B2').Font.Bold=1
...
__________
Juergen
joerg
User
Beiträge: 188
Registriert: Samstag 17. August 2002, 17:48
Wohnort: Berlin
Kontaktdaten:

tabellar hat geschrieben: Die Objektstruktur in dem Modul koennte also dann vielleicht so aussehen:

document
.Sheets -> Sheet-Containerobjklasse
..Sheet -> Sheet-Objekt
...Cells -> Zellen-Containerklasse oder Bereichsobjekt(Range)
....Cell -> Zellen-Objekt

Code: Alles auswählen

...
s.Cells('A1').Value='Hallo'
cell=s.Cells('1,2')
cell.Value='Joerg'
s.Cells('C7:C19').Value= range(13)
s.Cells('B1:B3').Value=['a','b','c']
s.Cells('A1:B2').Font='Arial'
s.Cells('A1:B2').Font.Bold=1
...
__________
Juergen
Hallo Jürgen,

Da scheinen wir ja genau gleich zu denken. ;-) Die Klassen SpreadSheet, Cell und CellProxy (dein Cells) habe ich schon prototypisch implementiert. CellProxy dient dazu, Eigenschaftszuweisungen an die einzelnen Zellen weiterzuleiten.
Trotzdem finde ich es immer noch besser(weil Python-like), mit eckigen Klammern und Slices zu arbeiten, um an Tabellenbereiche ranzukommen.
Was bisher geht, ist z.B.:
s['A1':'B2'].Font='Arial'
Das .Value braucht man bei mir nicht, Werte können direkt zugewiesen werden, neue Zellenobjekte werden bei erstmaliger Zuweisung automatisch angelegt:
s['C7':'C19'] = range(13)
Was übrigens schwieriger ist, ist folgendes:
s['A1':'B2'].Font.Bold=1
Hier müßte als 'Font' zuerst ein AttributeProxy vom CellProxy zurückgegeben werden, der die Attribut-Zuweisung 'Bold=1' dann automatisch an alle beteiligten zellen des CellProxy weiterleitet... das habe ich noch nicht.

Ich spiele noch ein bißchen rum, dann gebe ich meinen Code raus, in den nächsten Tagen, ok?

Hätte denn jemand ein bißchen Webspace und FTP-Zugang für die ersten Fragmente des Projektes?

Tschö
Jörg
tabellar
User
Beiträge: 186
Registriert: Mittwoch 4. September 2002, 15:28

joerg hat geschrieben: ...Ich spiele noch ein bißchen rum, dann gebe ich meinen Code raus, in den nächsten Tagen, ok?
Hätte denn jemand ein bißchen Webspace und FTP-Zugang für die ersten Fragmente des Projektes?
Hallo Jörg,

es freut mich wirklich, dass wir bei dem OOo-Modul die gleiche Gedankenwelt haben :) und ich bin schon sehr auf deinen ersten Implementierungs-Entwurf gespannt!!!

Zwecks Webspace und FTP wuerde ich es am Anfang einfach lassen. Wir können doch einfach ein neues Thema mit dem Titel "Implementierung OOo-Modul" oder so ähnlich... anlegen und dann dort Deine und alle weiteren Implementierung-Codes reinlegen (ich denke piddon-Carsten hat nichts dagegen, oder?). Vielleicht in diesem Stil, dass pro neue Antwort die entsprechenden Klassen, Module, etc. in den jeweiligen Code-Fragmenten angelegt werden.

Themen-Antwort-Beispiel:

OOo-Modul v0.0.1

Code: Alles auswählen

class Cell:
  ...

Code: Alles auswählen

class CellProxy:
  ...
Das hätte zum einen den Vorteil, dass alle Foren-Leser einfach mitschauen können (Spannung, Lerneffekt, Python-Publikation, etc.???) und zum anderen Korrekturen, Wünsche und Ergänzungen über das Forum-Board einfach zu machen sind :wink: !!!

Bin schon gespannt...
_______
Jürgen
piddon
Gründer
Beiträge: 410
Registriert: Dienstag 30. Juli 2002, 18:03
Wohnort: Oestrich-Winkel
Kontaktdaten:

NAtürlich habe ich nichts dagegen. Dafür sind diese Foren ja eingerichtet worden!

Wenns brennt kann ich noch ein bissl Webspace und ein FTP-Zugang zur Verfügung stellen, daran sollte es nicht liegen.
irc: #python.de @ irc.freenode.net | [url=http://pythonwiki.pocoo.org]python-wiki[/url] | [url=http://www.pythonwiki.de/PythonDeForum/Faq]python-forum FAQ[/url]
Antworten