Seite 1 von 3

Speichern einzelner Folien (impress) mit bestimmtem Namen

Verfasst: Mo 4. Dez 2023, 14:32
von LeFagnard
Hallo zusammen,

ich arbeite viel mit VBA in Office, benutze aber LibreOffice erst seit einer Woche!
Bei Impress finde ich zuerst einmal keine Möglichkeit, eigene Programme zu erstellen, außer "Makro ausführen, bearbeiten". Kann sein, dass ich letzeres benutzen kann.

Hier jetzt was ich benötige:
Ich habe eine Datei mit x Folien.
Jede Folie soll jetzt einzeln als png mit 600 dpi und 12 cm Kantenlänge im selben Ordner gespeichert werden.
Der Name einer jeden png-Datei soll teilweise aus einem Textfeld auf der Folie ausgelesen werden. Andere Infos bestehen aus Text sowie Datum und Uhrzeit.

Ist das möglich und wenn ja, wie? Ich kenne momentan nichts, was VB bei LibrOffice betrifft.

Ich lege einmal eine Beispieldatei bei, damit ihr sehen könnt, worum es sich handelt. Der Text für den Dateinamen kommt jeweils aus dem Textfeld mit RB-Lg-... als Inhalt., der außerhalb der zu speichernden Folie liegt.
Vielen Dank für Eure Hilfe
Marc
Belgien

Re: Speichern einzelner Folien (impress) mit bestimmtem Namen

Verfasst: Mo 4. Dez 2023, 16:44
von miesepeter
Hallo,
ich kenne nur zwei Möglichkeiten für den Bildexport aus Impress: Für Weiteres sollte sich einer der Spezialisten melden.

VisualBasic: Ist für LibreOffice nicht angesagt, hier gibt's StarBasic, Python und andere Programmierumgebungen. Ich selbst habe hierzu kein Wissen, vielleicht meldet sich einer der Spezialisten... - Ciao

Re: Speichern einzelner Folien (impress) mit bestimmtem Namen

Verfasst: Di 5. Dez 2023, 20:49
von mikele
Hallo,
so könnte es klappen:

Code: Alles auswählen

Sub Main

	'Zugriff auf das Dokument
	oDoc=ThisComponent
	'Exportfilter festlegen
	Dim args(2) As New com.sun.star.beans.PropertyValue
	oFilter = CreateUnoService("com.sun.star.drawing.GraphicExportFilter")
	args(1).Name = "MediaType"
	args(1).Value = "image/png"
	args(2).Name = "FilterData"
	Dim FilterData (1) As New com.sun.star.beans.PropertyValue
	myPixelWidth = 2835 : myPixelHeight = 2835 '  = 12cm:(2,54:96 cm pro Pixel)*600:96 
	FilterData(0).Name = "PixelWidth"  : FilterData(0).Value = myPixelWidth
	FilterData(1).Name = "PixelHeight" : FilterData(1).Value = myPixelHeight
	args(2).Value = FilterData

	'Durchlauf durch alle Folien
	For i = 0 To oDoc.getDrawPages().getCount() - 1
		oPage = oDoc.getDrawPages().getByIndex(i)
		'Textform finden und auslesen
		for k=0 to oPage.Count-1
			oForm=oPage.getByIndex(k)
			if oForm.supportsservice("com.sun.star.drawing.TextShape") then
				if left(oForm.String,6)="RB-Lg-" then
					sName=i & "_" & oForm.String
				end if
			end if
		next
		
		'Zieldatei festlegen
		args(0).Name = "URL"
		args(0).Value = convertToUrl("/home/michael/test/" & sName & ".png")
		
		'Exportieren
		oFilter.setSourceDocument(oPage)
		oFilter.filter(args())
	Next
	
End Sub

Re: Speichern einzelner Folien (impress) mit bestimmtem Namen

Verfasst: Mo 11. Dez 2023, 10:51
von LeFagnard
mikele hat geschrieben:
Di 5. Dez 2023, 20:49
Hallo,
so könnte es klappen:

Code: Alles auswählen

Sub Main

		'Zieldatei festlegen
		args(0).Name = "URL"
		args(0).Value = convertToUrl("/home/michael/test/" & sName & ".png")
	
End Sub
Hallo mikele,

Entschuldige die späte Rückmeldung. Ich war zu beschäftigt, obwohl in Rente ...
Vielen Dank für die tolle sub.
Ich bin von dem Code überrascht. Der ähnelt fast nirgendwo VBA. Das liegt wohl auch an den Benennungen bei Impress, die ich nicht kenne (aber ich lerne).

Ich hätte noch zwei Fragen dazu:
  • Wie muss ich den Zielordner anpassen?
  • Ist es möglich, dort einen relativen Pfad zu benutzen, sprich, das Resultat soll im selben Ordner wie die ODP liegen?
Und noch eine allgemeine Frage: Kann man verhindern, dass LibreOffice für diese Datei oder einem präzisen Ordner eine Ausnahme anlegt, damit nicht nach dem Ausführen des Makros gefragt wird?

Sorry, ich bin sowas von Anfänger mit LibreOffice Programmation.

Herzlichen Dank für Deine kompetente Hilfe.

Beste Grüße aus Belgien
Marc

Re: Speichern einzelner Folien (impress) mit bestimmtem Namen

Verfasst: Mo 11. Dez 2023, 13:20
von mikele
Hallo Marc,
ja der Syntax unterscheidet sich doch erheblich von VBA (insbesonder der Zugriff auf die Objekte).
Auf die Schnelle:
Die Anpassung des Pfades erfolgt in der Zeile

Code: Alles auswählen

args(0).Value = convertToUrl("/home/michael/test/" & sName & ".png")
Die Funktion convertToUrl() wandelt die Pfadangabe auf das notwendige Format (insbesondere Sonderzeichen etc.).
Für Windows könnte es so lauten:

Code: Alles auswählen

args(0).Value = convertToUrl("c:\Dokumente\lg\" & sName & ".png")
Die Variable sName entählt den gewünschten Dateinamen (ohne Pfad und Endung).
Das ganze geht auch relativ. Dazu muss der Pfad der aktuellen Datei ausgelesen werden.

Code: Alles auswählen

sDatei=oDoc.Url
Dieser String enthält nun Pfad und Dateinamen mit / als Trennzeichen.
Mit

Code: Alles auswählen

aDatei=split(oDoc.Url,"/")
würde ich die Url in ein Array ablegen(zerlegen nach jedem /)
Das letzte Element ist dann der Dateiname, den wir nun durch den neuen ersetzen:

Code: Alles auswählen

aDatei(ubound(aDatei))=sName & ".png"
und dann wieder zu einem String zusammensetzen und (zur Sicherheit) einem convertToUrl unterziehen:

Code: Alles auswählen

sNeu=join(aDatei,"/")
Zusammen also:

Code: Alles auswählen

'Zieldatei festlegen
		args(0).Name = "URL"
		aDatei=split(oDoc.Url,"/")
		aDatei(ubound(aDatei))=sName & ".png"
		args(0).Value = convertToUrl(join(aDatei,"/"))

Re: Speichern einzelner Folien (impress) mit bestimmtem Namen

Verfasst: Sa 16. Dez 2023, 12:01
von LeFagnard
Hallo Mikele,

da habe ich ja einen guten Lehrmeister gefunden, der mir genau erklärt, wie es funktioniert. Vielen Dank dafür.
So weit so gut. Was ich nicht verstehe ist, woher die Foliennummer vor dem Namen herkommt. Im Code kann ich das nicht erkennen.
Die wird nicht benötigt. Vielleicht einfach mit right(...)? Würde ich auch alleine hinbekommen, ich denke aber, da gibt es sicherlich etwas subtileres...
Da müsstest du mir nochmal unter die Arme greifen.

Also, das Format des Dateinamens sieht so aus:
Text Folienname(ohne Foliennummer) Datum Uhrzeit.

Zu Datum habe ich ein wenig recherchiert und, "Format" (wie bei vba) sowie "FormaDateTime" gefunden.
Bei letzterem finde ich allerdings nicht die Vorgabe, die ich benötige.
Das soll genau so aussehen: 2023-09-03 10-55-05

Du brauchst mir jetzt nicht alles im Detail zu erklären, nur eben auf die Sprünge helfen, z.B. wenn das wie bei vba etwa so aussehen würde: Format(Now(), "yyyy-MM-dd hh-mm-ss"), brauche ich nur die Schreibweise bei den Makros von LibreOffice.

Ach ja, noch etwas: bei dem png soll der Hintergund transparent sein. Sorry, hatte ich nicht angegeben.

Vielen Dank und Grüße aus Belgien. Mach's gut,
Marc

Re: Speichern einzelner Folien (impress) mit bestimmtem Namen

Verfasst: Sa 16. Dez 2023, 16:44
von mikele
Hallo,
woher die Foliennummer vor dem Namen herkommt
hier:

Code: Alles auswählen

sName=i & "_" & oForm.String
Das hatte ich eingebaut, um sicher zu erkennen, dass jede Folie exportiert wird.
Gekürzt:

Code: Alles auswählen

sName=oForm.String
brauche ich nur die Schreibweise bei den Makros von LibreOffice
Du hast sie schon selbst gefunden:

Code: Alles auswählen

format(now(),"yyyy-MM-dd hh-mm-ss")
Für die Transparenz habe ich hier https://ask.libreoffice.org/t/specifica ... tput/61981 eine Info gefunden.
Im Makro müsste es dann so als weitere FilterData-Eigenschaft eingebaut werden.

Code: Alles auswählen

	Dim FilterData (2) As New com.sun.star.beans.PropertyValue
	myPixelWidth = 2835 : myPixelHeight = 2835 '  = 12cm:(2,54:96 cm pro Pixel)*600:96 
	FilterData(0).Name = "PixelWidth"  : FilterData(0).Value = myPixelWidth
	FilterData(1).Name = "PixelHeight" : FilterData(1).Value = myPixelHeight
	FilterData(2).Name = "Translucent" : FilterData(2).Value = 1
	args(2).Value = FilterData

Re: Speichern einzelner Folien (impress) mit bestimmtem Namen

Verfasst: So 17. Dez 2023, 01:55
von LeFagnard
Hallo Mikele,

vielen Dank für die kompetente Hilfe.
Ich habe den Code jetzt angepasst und auch selber meinen Senf eingegeben.
Allerdings vorerst ohne die Transparenz und auch ohne Datum und Uhrzeit.
Der Code in der Schleife sieht jetzt so aus:

Code: Alles auswählen

	'Durchlauf durch alle Folien
	For i = 0 To oDoc.getDrawPages().getCount() - 1
		oPage = oDoc.getDrawPages().getByIndex(i)
		'Textform finden und auslesen
		for k=0 to oPage.Count-1
			oForm=oPage.getByIndex(k)
			if oForm.supportsservice("com.sun.star.drawing.TextShape") then
				if left(oForm.String,3)="RB-" then
						sName="21 - " & oForm.String & " - Schéma (" & ")"	'  & format(now(),"yyyy-MM-dd hh-mm-ss") --> erst mal ausgelassen
					else
						sName="Feuille " & i+1 & " -- manque nom de la RB"
				end if
			end if
		next

		'Zieldatei festlegen
		args(0).Name = "URL"
		aDatei=split(oDoc.Url,"/")
		aDatei(ubound(aDatei))=sName & ".png"
		args(0).Value = convertToUrl(join(aDatei,"/"))

		'Exportieren
		oFilter.setSourceDocument(oPage)
		oFilter.filter(args())
	Next
Syntax-Fehler werden nicht gemeldet, jedoch auch kein Resultat... oder es speichert an einer ganz anderen Stelle als im selben Odner.

Kannst du Dir bitte den Code mal anschauen? Kann es daran liegen, dass im Namen das Sonderzeichen "é" vorkommt? Das wäre allerdings ungünstg, denn solche Sonderzeichen werden auch im "RB-"-Feld vorkommen.

Vielen Dank,
Marc

Re: Speichern einzelner Folien (impress) mit bestimmtem Namen

Verfasst: So 17. Dez 2023, 13:28
von mikele
Hallo,
bei mir läuft das Makro durch und speichert 17 png im Verzeichnis der odp-Datei.
Du kannst ja mal nach der Zeile

Code: Alles auswählen

		args(0).Value = convertToUrl(join(aDatei,"/"))
folgende Zeile einfügen

Code: Alles auswählen

		msgbox args(0).Value
Dann siehst du in welchem Verzeichnis (im url-Syntax) die Datei gespeichert wird. Mit der Methode ConvertFromURL(args(0).Value) könntest du es wieder im Format deines Systems sehen.
Die Sonderzteichen sind daher unproblematisch, da sie durch die Methode convertToUrl() korrekt maskiert werden.
Eine Stelle ist mir jedoch nicht ganz klar:

Code: Alles auswählen

if oForm.supportsservice("com.sun.star.drawing.TextShape") then
				if left(oForm.String,3)="RB-" then
						sName="21 - " & oForm.String & " - Schéma (" & ")"	'  & format(now(),"yyyy-MM-dd hh-mm-ss") --> erst mal ausgelassen
					else
						sName="Feuille " & i+1 & " -- manque nom de la RB"
				end if
			end if
Auf jeder Folie werden alle Textformen durchsucht. Bei jeder einzelnen wird durch die obige Verzeigung die Variable sName belegt (entweder durch "21 - " ... oder "Feuille " ...) Damit legt die letzte gefundene Textform den Dateinamen fest. Soll das so sein?

Re: Speichern einzelner Folien (impress) mit bestimmtem Namen

Verfasst: Mo 18. Dez 2023, 19:32
von LeFagnard
Hallo Mikele,
ja, jetzt funktioniert es auch bei mir. Keine Ahnung, was da gesten schiefgelaufen ist.
Zu dem "Else": Ich habe das deshalb eingefügt, damit die Anwender sofort sehen, wo sie einen Fehler haben, also dort, wo der Dateiname falsch geschrieben ist.
Aber, wenn du dir den Output anschaust, findest du jetzt, oder dewegen, Fehler.
Die Folien, auf denen nur das Feld mit dem Blattnamen steht, erhalten den richtigen Namen,
alle diejenigen, auf denen es Zeichnungen gibt, erkennt das Programm den Namen nicht (mehr).

Ich verstehe noch nicht, wie das bei Basic in LibreOffce verarbeitet wird. Möglicherweise ist eben dieses "else" der Grund. Es wäre aber eine schöne Sache, wenn es möglich wäre, diese Fehlerabfrage richtig verarbeiten zu können.

Vielen Dank für die viele Geduld,
Marc