odfpy: Text finden und ersetzen

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
joh#
User
Beiträge: 139
Registriert: Freitag 6. November 2009, 13:16

Hallo,

ich habe ein OOo text Dokument bei dem ich eine Textstelle durch einen
anderen Text erstezen möchte. Ich finde in odfpy keine Funktion zum
finden . . . :shock:
joh
problembär

Kenne odfpy noch nicht. Steuere OpenOffice mit Python meist über pyuno.
joh#
User
Beiträge: 139
Registriert: Freitag 6. November 2009, 13:16

problembär hat geschrieben:Kenne odfpy noch nicht. Steuere OpenOffice mit Python meist über pyuno.
bei pyuno ist mir die Lernkurve zu steil, weil ich nur ein paar Rechnungen generieren
will, wo an 2, 3 Stellen Text einzufügen ist...
odfpy kann ein .odt ERZEUGEN, aber ich habe in der Doku nichts gefunden, um Text
zu FINDEN bzw. zu ERSETZEN.

Es gab hier im Forum auch schon den Vorschlag doch einfach mit zipfile das odt-Archiv
auseinander zu nehmen, die content.xml zu ändern, und dann alles wieder zusammen
zu packen. Aber da scheitere ich an der Tatsache, daß ich die Dateien in ihrer Baum-
struktur nicht eingepackt bekomme. OOo konnte die .odt dann nicht mehr öffnen...

'Natürlich' bekommt man das alles hin, wenn man bis auf xml-level runter geht,
aber muß das wirklich sein?

Gruß
joh
problembär

joh# hat geschrieben:
problembär hat geschrieben:Kenne odfpy noch nicht. Steuere OpenOffice mit Python meist über pyuno.
bei pyuno ist mir die Lernkurve zu steil, weil ich nur ein paar Rechnungen generieren
will, wo an 2, 3 Stellen Text einzufügen ist...
Ah, dann könnte das hier was für Dich sein:

http://www.oooforum.org/forum/viewtopic.phtml?t=37839

;)
lunar

@joh#: Wenn es in odfpy keine Funktion zum Suchen gibt, dann musst Du sie selbst schreiben, indem Du über alle Dokumentknoten iterierst, und den enthaltenen Text mit dem gesuchten vergleichst. An dieser Stelle würde ich normalerweise einfach auf die Dokumentation Dokumentation verweisen, aber die ist ein schlechter Scherz. Die pyodf API sieht zudem so aus, als hätten die Entwickler einfach überkommene APIs aus anderen Richtlinien übertragen, anstatt eine idiomatische und einfache Python-API zu entwerfen (was teilweise sicherlich auch der Komplexität von ODF geschuldet ist).

Vor diesem Hintergrund ist es wahrscheinlich wirklich am einfachsten, das Dokument auf XML-Ebene zu verarbeiten. Zeige uns doch Deinen Quelltext dazu und die Fehlermeldung, die Du erhältst, dann können wir Dir auch konkrete Hilfestellung leisten.

Von UNO rate ich nachdrücklich ab, denn die UNO-API ist komplex jenseits von Gut und Böse, und geeignet, Dich ins Irrenhaus zu bringen, bevor Du Dein Programm fertiggestellt hast ;)
problembär

lunar hat geschrieben:Von UNO rate ich nachdrücklich ab, denn die UNO-API ist komplex jenseits von Gut und Böse, und geeignet, Dich ins Irrenhaus zu bringen, bevor Du Dein Programm fertiggestellt hast ;)
Im Prinzip schon, aber nicht, wenn man schon eine fertige Rechnung hat und da nur zu zwei, drei Stellen springen will, um etwa eine Adresse oder die Rechnungsnummer einzufügen. Man setzt einfach ein paar Textmarken mit (Einfügen/Textmarke), springt die an wie in dem Link oben gezeigt und fügt seinen Text ein. Das kann man relativ schnell verstehen, in sagen wir einer halben Stunde.
joh#
User
Beiträge: 139
Registriert: Freitag 6. November 2009, 13:16

problembär hat geschrieben:
joh# hat geschrieben:
problembär hat geschrieben:Kenne odfpy noch nicht. Steuere OpenOffice mit Python meist über pyuno.
bei pyuno ist mir die Lernkurve zu steil, weil ich nur ein paar Rechnungen generieren
will, wo an 2, 3 Stellen Text einzufügen ist...
Ah, dann könnte das hier was für Dich sein:

http://www.oooforum.org/forum/viewtopic.phtml?t=37839

;)
probier ich....


wenn Zeit ist
danke.
joh#
User
Beiträge: 139
Registriert: Freitag 6. November 2009, 13:16

lunar hat geschrieben:@joh#: . . .
Vor diesem Hintergrund ist es wahrscheinlich wirklich am einfachsten, das Dokument auf XML-Ebene zu verarbeiten. Zeige uns doch Deinen Quelltext dazu und die Fehlermeldung, die Du erhältst, dann können wir Dir auch konkrete Hilfestellung leisten.
Was ich noch nicht geschafft habe ist, die Ordner-Struktur wieder ins .odt zu bekommen:

Code: Alles auswählen

'''
Ordner-Struktur innerhalb von .odt:

│  ├─ temp                      content.xml, manifest.rdf, meta.xml, mimetype, settings.xml, styles.xml
│ │  │  ├─ Configurations2
│ │  │  │  ├─ accelerator       current.xml
│ │  │  │  ├─ floater
│ │  │  │  ├─ images
              └─ Bitmaps
│ │  │  │  ├─ menubar
│ │  │  │  ├─ popupmenu
│ │  │  │  ├─ progressbar
│ │  │  │  ├─ statusbar
│ │  │  │  ├─ toolbar
│ │  │  │  └─ toolpanel
│ │  │  ├─ META-INF             manifest.xml
│ │  │  └─ Thumbnails           thumbnail.png
------------------------------------------------------------------
(u'', u'mimetype')
(u'Configurations2/statusbar', u'')
(u'Configurations2/accelerator', u'current.xml')
(u'Configurations2/floater', u'')
(u'Configurations2/popupmenu', u'')
(u'Configurations2/progressbar', u'')
(u'Configurations2/toolpanel', u'')
(u'Configurations2/menubar', u'')
(u'Configurations2/toolbar', u'')
(u'Configurations2/images/Bitmaps', u'')
(u'', u'content.xml')
(u'', u'manifest.rdf')
(u'', u'styles.xml')
(u'', u'meta.xml')
(u'Thumbnails', u'thumbnail.png')
(u'', u'settings.xml')
(u'META-INF', u'manifest.xml')

'''
import  os, shutil, zipfile, platform, glob

inputfilename = ur"Rechnungsvorlage2.odt"
outp_filename = ur"RE001.odt"

#die im odt-zipfile befindliche Verzeichnisstruktur anlegen:
inputfile = zipfile.ZipFile(inputfilename, 'r')
for name in inputfile.namelist():
    data = inputfile.read(name)             #DateiInhalt
    #print name.ljust(30), len(data), repr(data[:10])
    namet= os.path.split(name)
    print namet
    #wenn es noch EIN oder ZWEI Umterverz. mehr ist:
    if namet[0]:
        dummy1=namet[0]
        os.makedirs(dummy1)   #das anlegen
        #wenn darin noch eine Datei anzulegen ist:
        if namet[1]:
            dummy2=namet[0]+os.sep+namet[1]
            tfile = open(dummy2 ,'w')
            tfile.write(data)
            tfile.close()
    #wenn es nur ein Dateiname ist:
    else:
        dummy3= namet[1]
        tfile = open(dummy3,'w')
        tfile.write(data)
        tfile.close()

#bis hierher geht es
#jetzt wäre content.xml zu manipulieren

#ab hier muss jetzt die Ordnerstruktur wieder ins odt-zipfile:
outp_file = zipfile.ZipFile(outp_filename, "w")
outp_file.write(odt_text)
lunar

@joh#: Du musst die Ordnerstruktur natürlich auch wieder in derselben Form manuell erzeugen. Dazu kannst "os.walk()" nutzen, um über die Verzeichnisebenen zu iterieren, den Rest findest Du dann in der Dokumentation zu "zipfile". Hast Du gedacht, ".write()" errät auf irgendeine magische Weise die richtige Ordnerstruktur?

Wenn Du schon an der eigentlich nicht schwierigen Aufgabe scheiterst, Dateien in ein ZIP-Archiv zu verpacken, wirst Du an der Komplexität von odfpy und pyuno erst recht verzweifeln.
problembär

joh# hat geschrieben:probier ich....
wenn Zeit ist
Ja, mach' mal. Wenn das Beispielskript dort bei Dir direkt läuft (mußt halt noch "uno.py" in Deinen Python-Pfad kopieren, siehe unter Anmerkung 1. dort), solltest Du die "Zauberei" schon erkennen. Kostet sicher weniger Zeit als im xml rumzuwühlen.
joh# hat geschrieben:Was ich noch nicht geschafft habe ist, die Ordner-Struktur wieder ins .odt zu bekommen
Dazu

http://stackoverflow.com/questions/4584 ... ing-python

Erstaunlich umständlich. Ab Python 2.7 soll's auch

Code: Alles auswählen

shutil.make_archive("desired_zipfile_name_no", "zip", "name_of_the_folder_you_want_to_zip")
geben. Was ist denn Deine Python-Version und Dein OS?
Es ist zwar eigentlich ganz gut, alles mit Python-Modulen zu machen, aber unter Linux ginge auch einfach

Code: Alles auswählen

zip -r file.zip directory
Das in einem schnellen "os.system()", fertig.
lunar hat geschrieben:Wenn Du schon an der eigentlich nicht schwierigen Aufgabe scheiterst, Dateien in ein ZIP-Archiv zu verpacken, ...
Sehr aufbauend mal wieder. :roll:
lunar

@problembär: Es ist weder meine Aufgabe noch mein Anliegen, "aufbauend" zu sein. Für aufbauende Gespräche gibt es Freunde, Familie und Therapeuten (in wahlfreier Reihenfolge), hier gibt es nur ehrliche Meinungen, technische Hilfestellung und realistische Einschätzungen.
joh#
User
Beiträge: 139
Registriert: Freitag 6. November 2009, 13:16

lunar hat geschrieben:@joh#: Du musst die Ordnerstruktur natürlich auch wieder in derselben Form manuell erzeugen. Dazu kannst "os.walk()" nutzen, um über die Verzeichnisebenen zu iterieren, den Rest findest Du dann in der Dokumentation zu "zipfile". .
der Hinweis auf os.walk ist gut
lunar hat geschrieben: Hast Du gedacht, ".write()" errät auf irgendeine magische Weise die richtige Ordnerstruktur?
Nein, dazu reicht es gerade noch, die letzten Zeilen sollten nur andeuten: "an dieser Stelle muss jetzt alles wieder ins Körbchen :)
lunar

@joh#: Eins noch: In einem ZIP-Archiv gibt es keine Ordner als eigenständiges Objekt, so wie im Dateisystem. Ordner ergeben sich automatisch aus den Dateinamen, sprich, wenn Du eine Datei als "spam/with/eggs" ins Archiv packst, dann gibt es automatisch auch die Ordner "spam/" und "spam/with/". Das noch als Hinweis, denn ich weiß gerade nicht, ob dass aus der Dokumentation so auch hervorgeht.
problembär

lunar hat geschrieben:@problembär: Es ist weder meine Aufgabe noch mein Anliegen, "aufbauend" zu sein. Für aufbauende Gespräche gibt es Freunde, Familie und Therapeuten (in wahlfreier Reihenfolge), hier gibt es nur ehrliche Meinungen, technische Hilfestellung und realistische Einschätzungen.
:lol: Das erklärt einiges. So eine absichtlich "nicht-freundliche" Foren-"Community" wie hier ist mir noch nirgendwo untergekommen. Es ist einfach unglaublich! Unglaublich schlecht. So behandelt man keine Fragesteller und Mit-Antworter in einem Forum.
Das kann man höchstens machen, wenn man als Beamter Kriminelle verhört oder Verdächtige kontrolliert. Und selbst da gilt noch der sog. "Höflichkeitserlaß".
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

problembär hat geschrieben: :lol: Das erklärt einiges. So eine absichtlich "nicht-freundliche" Foren-"Community" wie hier ist mir noch nirgendwo untergekommen. Es ist einfach unglaublich! Unglaublich schlecht. So behandelt man keine Fragesteller und Mit-Antworter in einem Forum.
lunar schrieb doch es sei nicht seine Aufgabe - jedem steht es frei, seine Rolle hier anders zu interpretieren, so lange sie sich im Rahmen der Forenregeln bewegen. Es gibt auch User hier, die andere ermutigen und bewusst emotional aufbauende Passagen in ihre Postings einstreuen. Das hängt immer vom speziellen Fall ab. Im übrigen erscheint es mir so, als habe joh# mit lunars Postings keinerlei Probleme gehabt - worüber regst Du Dich also auf?

Mich stören an Deinen Metapostings vor allem Deine Ignoranz und Deine Verallgemeinerungen - dieses ist dafür ein gutes Beispiel. Vielleicht gehst Du doch noch mal in Dich und denkst mal drüber nach, ob Dich nicht doch persönliche Verbitterung zu solchen Postings veranlasst.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Also ich fand den Spruch von lunar super. :mrgreen:

Und jedem nicht allzu dünnhäutigen Menschen dürfte eine gewisse Spur von Sarkasmus darin nicht entgangen sein... :o

Im Übrigen ist diese ganze immer wieder aufflammende Diskussion dämlich. Das Forum / die Community ist im Großen und Ganzen freundlich und hilfsbereit. Solcherlei Gejammer ohne tatsächliche Grundlage, wie es allzu gern von problembär zelebriert wird, ist in meinen Augen eher das, was die Stimmung hier vergiften kann. Man kann hier eigentlich nur zu "just ignore him" raten, aber irgendwen gibt's ja leider immer, der trotzdem noch drauf eingeht (so wie ich jetzt zum Beispiel)...

Ich würde eigentlich gern ausführlicher schreiben, wie ich dazu stehe, aber der Anstand und die Forenregeln gebieten mir da (zum Glück) Einhalt.
Antworten