Text aus LibreOffice-Document (odt)

In dieser Linux-Ecke dürfen nur Themen rund um Linux geschrieben werden.
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Text aus LibreOffice-Document (odt)

Beitrag von ccode_new »

Hallo und noch einen schönen Reformationstag / bzw. Halloween.

Hat jemand unerwarteterweise zufällig Ahnung wie man einen einfachen Text (ohne Grafik/ohne Einhaltung von Formatierung/etc.) aus einem LibreOffice Writer - Dokument an einer festgelegten Stelle auslesen kann (mit PureBasic natürlich ;) ) ?

Dafür braucht man glaube ich das Libre-Office - SDK.

Hat jemand so etwas schon mal gemacht ?

Es geht mir hierbei wirklich um Libre-Office (odt) und nicht um Microsoft Office (.doc/.docx).
Außerdem muss/sollte es unter Linux funktionieren.

Ich habe bisher von diesen "Libre Office SDK" keine Ahnung.

Vielleicht hat hier ja jemand Tipps.

Naja!
Wenn hier keiner Ahnung hat und ich mir auch keine Ahnung anlesen/ probieren kann, dann ist das auch nicht weiter schlimm.
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Benutzeravatar
Kurzer
Beiträge: 1614
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Re: Text aus LibreOffice-Document (odt)

Beitrag von Kurzer »

Ich habe zwar kein Libre Office und folgendes ist auch nur eine seeeeeehr vage Vermutung...

... aber versuch mal dein Dokument von *.odt in *.zip umzubenennen und dann guck mal, ob du es mit einem ZIP Tool entpacken kannst.
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.02 x64, OS: Win 7 Pro x64 & Win 11 x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Useralter in 2023: 56 Jahre.
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: Text aus LibreOffice-Document (odt)

Beitrag von ccode_new »

Hi Kurzer!

Danke für den Tip!

Du hast recht!

Ok der Text ist jetzt tatsächlich in einer "content.xml" Datei gespeichert.

Aber jetzt einen "beliebigen" Text an einer beliebigen Stelle im Dokument auszulesen ist jetzt trotzdem noch recht kompliziert.

Ob ich das so einfach mit den XML-Features, etc. von PureBasic hinbekomme ?

Nagut somit habe ich jetzt zumindest einen Ansatz ohne dieses SDK.
:allright:

So obliegt es jetzt meiner Lust und Zeit und Können eine für mich vernünftige Lösung mit PureBasic zu programmieren.
:mrgreen:
Ok, danke!
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Benutzeravatar
Kurzer
Beiträge: 1614
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Re: Text aus LibreOffice-Document (odt)

Beitrag von Kurzer »

Wie sieht denn die XML Datei aus und was ist genau die "beliebige Stelle" im Text?
Wenn es eine reguläre XML Datei ist, kannst du den Text doch sicherlich komplett extrahieren, so dass du wirklich nur den Text vorliegen hast.

Wenn mit beliebiger Stelle z.B. ab dem 309 Zeichen gemeint ist, dann wäre es ja recht einfach.
Wenn Zeile und Zeichen gemeint sind, kommt es drauf an, ob du die Information in der XML Datei findest, welche Worte in welcher Zeile platziert sind. Wenn nicht wird es fast unmöglich, weil du ja sonst den Renderprozess von Libre mit genau dem verwendeten Font, Fontgrößen, Rändern, Margins, evtl. eingebetteten Grafiken usw. nachvollziehen müsstest.
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.02 x64, OS: Win 7 Pro x64 & Win 11 x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Useralter in 2023: 56 Jahre.
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: Text aus LibreOffice-Document (odt)

Beitrag von ccode_new »

Kurzer hat geschrieben:Wie sieht denn die XML Datei aus und was ist genau die "beliebige Stelle" im Text?
Wenn es eine reguläre XML Datei ist, kannst du den Text doch sicherlich komplett extrahieren, so dass du wirklich nur den Text vorliegen hast.

Wenn mit beliebiger Stelle z.B. ab dem 309 Zeichen gemeint ist, dann wäre es ja recht einfach.
Wenn Zeile und Zeichen gemeint sind, kommt es drauf an, ob du die Information in der XML Datei findest, welche Worte in welcher Zeile platziert sind. Wenn nicht wird es fast unmöglich, weil du ja sonst den Renderprozess von Libre mit genau dem verwendeten Font, Fontgrößen, Rändern, Margins, evtl. eingebetteten Grafiken usw. nachvollziehen müsstest.
Also:

Die Formatierung ist EGAL!

Mit "beliebige Stelle" ist eine per Procedure frei wählbare Stelle gemeint.
Diese Stelle muss/soll nicht Zeichengenau sein, sondern Zeilen- und Seitenumbruch genau sein.
Z.Bsp.:
TEXT = LeseText(SEITE, ZEILE)
TEXT$ = LeseText(12, 5)

Ein Seitenumbruch wird in der XML z.B so dargestellt:
<text:soft-page-break/>

Dabei wären erstmal auch Seiteneinstellungen wie: Randbreiten/Seitenformat (Standard: A4) egal.
Bzw. ich bräuchte sonst noch entsprechende Möglichkeiten diese Dinge bei "LeseText" mit einzubeziehen.
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: Text aus LibreOffice-Document (odt)

Beitrag von NicTheQuick »

Ich erstelle beruflich automatisiert LibreOffice Writer-Dateien mit Python. Von einfachen 10-Seiten-Dokumenten bis zu über 2000 Seiten.
Ich kann dir alles sagen, was du wissen willst. Und auch schon ein paar Antworten geben:
<text:soft-page-break/>
text:soft-page-break ist kein echter Seitenumbruch, sondern das ist ein Tag, den Writer selbst in das XML einbaut, damit externe Programme erkennen können, wo nach dem Layouten der Text umbricht.
Ein echter Seitenumbruch wird im Absatzformat des Absatzes festgelegt, über dem er stattfindet. Das Attribut ist fo:break-before.
Diese Stelle muss/soll nicht Zeichengenau sein, sondern Zeilen- und Seitenumbruch genau sein.
Das geht nicht, ohne direkt mit einer laufenden Writer-Instanz verbunden zu sein. Wie Kurzer schon sagte hast du im XML keine Information darüber wie der Text gelayoutet wurde, sprich du weißt nicht, wann er in eine nächste Zeile umbricht und auf welcher Seite er steht.
Man kann aber Absätze adressieren, da jeder Absatz von <text:p> umschlossen ist.

Erklär mal bitte genauer, was dein Ziel ist, vielleicht gibt es ja eine gute Herangehensweise.
Bild
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: Text aus LibreOffice-Document (odt)

Beitrag von ccode_new »

Hallo Nic,
dass ist ja toll.

Also wieso sollte ich jetzt genau <text:soft-page-break/> als Seitenindikator vermeiden ?

Ich finde deinen 1. Punkt interessant.

Wie erstellst du mit Python automatisiert Office-Dokumente ?

Nutzt du Python über Makro-Scripts ?
Oder nutzt du einen anderen Weg ?
Welche Python-Bibliothek nutzt du dafür ?

Bis jetzt bin ich zeitlich hier noch zu nichts gekommen.
Mal sehen ob ich mich in näherer Zeit überhaupt weiter mit diesem Thema beschäftige.
Aber warscheinlich vlt. doch.

Es muss insgesamt auch nicht unbedingt Zeilengenau sein,
aber eine Unterscheidung zwischen den einzelnen Seiten sollte schon möglich sein.

Naja, mit einer reinen PureBasic-Lösung wäre ich zufriedener.
Also ohne weitere Tools, wie Python mit zusätzlichen Bibliotheken.
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: Text aus LibreOffice-Document (odt)

Beitrag von NicTheQuick »

Ich nutze keine besondere Bibliothek in Python dafür. Grob gesagt brauche ich nur zipfile und dann eben ElementTree um das XML zu bearbeiten. Zusammen mit der Dokumentation und einem schlauen Klassenkonzept kann man dann wunderbar rekursiv auf dem XML-Baum arbeiten und alles mögliche tun.

Ich wollte nicht sagen, dass du den <text:soft-page-break/>-Tag vermeiden sollst, aber ich würde mich glaube ich auch nicht unbedingt darauf verlassen. Aber wenn du ein Dokument mit Writer speicherst und dann nichts mehr daran änderst und das XML ausliest, müsste es ja eigentlich richtig sein und man kann die Seitenumbrüche erkennen. Schwieriger wird es dann, wenn ein Absatzformat nochmal selbst einen Seitenumbruch macht. Ich glaube dann wird das <text:soft-page-break/>-Tag nicht mehr extra reingeschrieben. Das müsste ich jetzt ausprobieren. Das heißt wenn im Dokument echte Seitenumbrüche vorkommen, musst du dir auch noch zählen. Eventuell musst du dafür dann sogar die styles.xml auswerten, je nachdem in welchem Absatzformat der Seitenumbruch definiert wurde.

Falls du mit Python etwas machen willst, hilft dir vielleicht auch das Package odfpy, das speziell mit dem OpenDocument-Formaten zurecht kommt und alles noch etwas vereinfacht.

Man kann aber auch LibreOffice als Server starten und dann mittels PyUno-Bridge auf die laufenden Instanz zugreifen. Damit kannst du das gleiche machen wie den Macros, die man in LibreOffice selbst schreiben kann, allerdings mit Python und nicht etwa mit StarBasic. Leider ist hier die Dokumentation echt schlecht. Du findest erst mal nur Sachen über OpenOffice, die teilweise schon gut veraltet sind und anderen Stellen irgendwelche Codeschnipsel, die du erst mal umbauen musst für das, was du eigentlich haben willst, usw. Damit hab ich bisher auch nur echt wenig gemacht, nur ein bisschen herumgespielt, denn für manche Dinge braucht man ein laufendes LibreOffice, damit man das Layout in Echtzeit bearbeiten kann.
Bild
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: Text aus LibreOffice-Document (odt)

Beitrag von ccode_new »

Danke für die Antwort.

Das hier habe ich mir gerade eben mal schnell zusammengebastelt:

Code: Alles auswählen

UseZipPacker()

Define InputFile.s

Procedure.s Read_ODT_Text(File.s, Page.i, Line.i)
  Protected TextNode.i, NNode.i, NewChild.i
  Protected counter.i = 1
  Protected NPage.i = 1, NLine.i = 1
  
  If File <> "" And Page >= 1 And Line >= 1
    CreateDirectory(GetPathPart(File)+".hiddenDir")
    
    If OpenPack(0, File) 
      If ExaminePack(0)
        While NextPackEntry(0)
          UncompressPackFile(0, GetPathPart(File)+".hiddenDir/"+PackEntryName(0))
        Wend
      EndIf
      ClosePack(0)
    EndIf
    
    If LoadXML(0, GetPathPart(File)+".hiddenDir/content.xml")
      If XMLStatus(0) <> #PB_XML_Success
        Message$ = "Error in the XML file:" + Chr(13)
        Message$ + "Message: " + XMLError(0) + Chr(13)
        Message$ + "Line: " + Str(XMLErrorLine(0)) + " Character: " + Str(XMLErrorPosition(0))
        MessageRequester("Error", Message$)
      EndIf
      
      If GetXMLNodeName(MainXMLNode(0)) = "office:document-content"
        TextNode = XMLNodeFromPath(XMLNodeFromPath(MainXMLNode(0), "office:body"), "office:text")
        If GetXMLNodeName(TextNode)
          If GetXMLAttribute(TextNode, "text:use-soft-page-breaks") = "true" ;Abfrage nach Soft-Page-Breaks
            Repeat
              counter + 1
              NNode = ChildXMLNode(TextNode, counter)
              If NNode <> 0
                If NPage = Page And NLine = Line
                  ProcedureReturn GetXMLNodeText(NNode)
                  Break
                EndIf
                NewChild = ChildXMLNode(NNode)
                If NewChild <> 0
                  If GetXMLNodeName(NewChild) = "text:soft-page-break"
                    NLine = 1
                    NPage + 1                  
                    If Line = 1 And NPage = Page
                      NLine = 0
                      counter - 1
                    EndIf
                  EndIf
                EndIf
              EndIf
              NLine + 1
            Until NNode = 0
          EndIf
        EndIf
      EndIf
    EndIf
  EndIf
EndProcedure

InputFile = OpenFileRequester("Bitte eine .odt - Datei auswählen.", "*.odt", "ODT (*.odt)|*.odt;", 0)

Debug Read_ODT_Text(InputFile, 3, 1)
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Antworten