Word/Libre-Office Writer-Export

Rund um die LCL und andere Komponenten
Antworten
Joh
Lazarusforum e. V.
Beiträge: 360
Registriert: Sa 26. Mai 2012, 17:31
OS, Lazarus, FPC: Win 10 (L 2.2.6 x64 FPC 3.2.2)
CPU-Target: 64Bit

Word/Libre-Office Writer-Export

Beitrag von Joh »

Hi,
gibt es irgendeine Komponente für Word/Writer etc,, in der ich per Lazarus Formulare erstellen kann wie
- Pos(0,0) WritePicture (Datei)
- Pos(x,y) WriteLabel (Arial, 10, N)
- Pos(x+20,y) Textbox (Arial, 10, N) // hier soll der Benutzer was eingeben

Also so etwas wie fpspreadsheet für Dokumente.
Zur Not auch Office-Automation; aber eher ungern; das war grottenlahm und nicht mein Ding.

Also in etwa: Formular mit 30 Feldern erstellen.
Daten vorbelegen.
Speichern als docx/odt möglich...
Änderbar durch den Anwender.

Ich weiß: blöde Idee...

thx
just my two Beer

Benutzeravatar
Jorg3000
Lazarusforum e. V.
Beiträge: 445
Registriert: So 10. Okt 2021, 10:24
OS, Lazarus, FPC: Win64
Wohnort: NRW

Re: Word/Libre-Office Writer-Export

Beitrag von Jorg3000 »

Moin Joh!
Bei der Office-Automation per OLE oder UNO ist bezüglich Geschwindigkeit das Problem, dass zunächst Word bzw. LibreOffice im Hintergrund gestartet werden muss. Für den ersten Zugriff kann das mehrere Sekunden dauern und der Anwender hat den Eindruck, es würde nichts passieren.

Wenn du das Dokument ganz neu erzeugen möchtest, kannst du es als XML-Datei selbst erstellen und dann mittels TZipper zu einer Datei zusammenschnüren, als .ODT oder .DOCX.
Darin wird die content.xml bzw. document.xml zusammen mit weiteren Dateien z.B. Styles gezippt.

Du findest allerdings bei der Textverarbeitung keinen Pos(x+20,y) Befehl o.ä. wie bei PDF, denn bei Textverarbeitung werden die Elemente im Fluss des Inhalts angeordnet, so wie man es auch von klassischem HTML kennt.

Die XML-Knoten für .ODT und .DOCX sind selbstverständlich nicht kompatibel, außerdem hat alles sehr viel Overhead. Zudem ist der Aufbau der .ODT und .DOCX Dateien im Zip anders.
Letztlich wird dir die Erstellung eines komplexen XML viel Geduld abverlangen, selbst wenn du dir von einem Sprachmodell ein paar XML-Beispiele ausspucken lässt.
Grüße, Jörg

Benutzeravatar
theo
Beiträge: 11273
Registriert: Mo 11. Sep 2006, 19:01

Re: Word/Libre-Office Writer-Export

Beitrag von theo »

Oder soffice (Libreoffice) aufrufen und ein HTML konvertieren.

soffice --headless --convert-to odt test.html
oder
soffice --headless --convert-to "docx:MS Word 2007 XML" test.html

Keine Ahnung, wie gut man das hinbekommt, aber viel einfacher wird''s nicht werden.

wp_xyz
Beiträge: 5420
Registriert: Fr 8. Apr 2011, 09:01

Re: Word/Libre-Office Writer-Export

Beitrag von wp_xyz »

Das Gegenstück zu FPSpreadsheet für Text- und Vektorgraphik-Dokumente ist FPVectorial (kommt mit Lazarus). Es wird per Code eine Document-Struktur mit diversen Text-/Graphikelementen aufgebaut und dann von speziellen Writerklassen als Datei im gewünschten Format auf Platte geschrieben; umgekehrt gibt es entsprechende Reader zum Einlesen dieser Dateien.

Leider ist das Projekt zur Zeit verwaist, die Reader/Writer-Klassen sind in der Regel unvollständig und teilweise kaputt. docx und odt werden allerdings recht gut für das Schreiben unterstützt. Hier ist ein Beispiel, das irgendwann mal in einem Forum oder einem Bugreport vorgestellt wurde; es wird eine (einfache) Tabelle erzeugt und im docx und odt-Forum gespeichert (das Package "fpvectorialpkg" muss in die Projekt-Anforderungen aufgenommen werden):

Code: Alles auswählen

program SimpleTable;

{$mode objfpc}{$H+}

uses
  fpvectorial,
  fpvutils,   // For RGBToFPColor()
  docxvectorialwriter, odtvectorialwriter,
  SysUtils;

var
  Document: TvVectorialDocument;
  Page: TvTextPageSequence;
  Paragraph: TvParagraph;
  BoldTextStyle: TvStyle;
  CenterStyle: TvStyle;
  Table: TvTable;
  Row: TvTableRow;
  Cell: TvTableCell;
  iRow: Integer;
  iCol: Integer;

const
  // Most dimensions in FPVectorial are in mm.  If you want to specify
  // anything in other units, be ready to do the conversion...
  ONE_POINT_IN_MM = 0.35278;

begin
  Document := TvVectorialDocument.Create;
  try
    //  Adds the defaut Paragraph Styles
    //    StyleTextBody, StyleHeading1,
    //    StyleHeading2 & StyleHeading3
    Document.AddStandardTextDocumentStyles(vfUnknown);

    // Add our own Style for bolded text elements
    BoldTextStyle := Document.AddStyle();
    BoldTextStyle.Kind := vskTextSpan; // This style will only be applied to selected Text Spans
    BoldTextStyle.Name := 'Bold';
    BoldTextStyle.Font.Bold := True;
    BoldTextStyle.SetElements := BoldTextStyle.SetElements + [spbfFontBold];

    // Add our own style for centered paragraphs
    CenterStyle := Document.AddStyle();
    CenterStyle.Kind := vskTextBody; // This style will be applied to the whole Paragraph
    CenterStyle.Name := 'Table Body Centered';
    CenterStyle.Font.Name := 'Verdana';
    CenterStyle.Font.Size := 8;
    CenterStyle.Alignment := vsaCenter;
    CenterStyle.MarginTop := 2 * ONE_POINT_IN_MM;
    CenterStyle.MarginBottom := 2 * ONE_POINT_IN_MM;
    CenterStyle.SetElements :=
      [spbfFontSize, spbfFontName, spbfAlignment, sseMarginTop, sseMarginBottom];

    // Create the Document, and add a simple Heading
    Page := Document.AddTextPageSequence;
    Paragraph := Page.AddParagraph;
    Paragraph.Style := Document.StyleHeading1;
    Paragraph.AddText('Simple Table');

    // Add our Table, which will have 5 columns
    Table := Page.AddTable;
    Table.PreferredWidth := Dimension(100, dimPercent);

    // As we will be merging cells, we have to define all the column widths
    // so that ODT knows how many columns there will be.
    // Getting the width exactly correct is not essential as LibreOffice Writer
    // and Microsoft Word each treat this as a PreferredWidth value.
    Table.ColWidthsUnits:=dimMillimeter;
    SetLength(Table.ColWidths, 5);
    Table.ColWidths[0] := 50;
    Table.ColWidths[1] := 50;
    Table.ColWidths[2] := 50;
    Table.ColWidths[3] := 50;
    Table.ColWidths[4] := 50;

    // Add a single row at the start which will contain merged cells
    Row := Table.AddRow;
    Row.BackgroundColor := RGBToFPColor(192, 192, 192); // Grey Shading
    Row.Header := True; // Tell the table this is a Header Row
                        // Header Rows repeat at the top of each page

    Cell := Row.AddCell;
    Paragraph := Cell.AddParagraph;
    Paragraph.Style := CenterStyle;
    Paragraph.AddText('Category 1').Style := BoldTextStyle;

    Cell := Row.AddCell;
    Cell.SpannedCols:=2;  // Make this cell cover two columns
    Paragraph := Cell.AddParagraph;
    Paragraph.Style := CenterStyle;
    Paragraph.AddText('Category 2').Style := BoldTextStyle;

    Cell := Row.AddCell;
    Cell.SpannedCols:=2;  // Make this cell cover two columns
    Paragraph := Cell.AddParagraph;
    Paragraph.Style := CenterStyle;
    Paragraph.AddText('Category 3').Style := BoldTextStyle;

    // Add 21 rows to the Table, with the first being the header row
    for iRow := 0 to 20 do
    begin
      Row := Table.AddRow;

      // Header Row
      if iRow = 0 then
      begin
        Row.BackgroundColor := RGBToFPColor(192, 192, 192); // Grey Shading
        Row.Header := True; // Tell the table this is a Header Row
                            // Header Rows repeat at the top of each page
      end;

      // Add 5 cells to each Row
      for iCol := 0 to 4 do
      begin
        Cell := Row.AddCell;

        // Each Cell is a TvRichText, we cad add anything we can add to the main
        // body of a Document (for now Paragraphs, Tables or Lists)
        Paragraph := Cell.AddParagraph;
        Paragraph.Style := CenterStyle;

        if iRow = 0 then
          Paragraph.AddText(Format('Header Col %d', [iCol])).Style := BoldTextStyle
        else
          Paragraph.AddText(Format('Cell %d x %d', [iRow, iCol]));
      end;
    end;


    Document.WriteToFile('Simple_Table.docx', vfDOCX);
    Document.WriteToFile('Simple_Table.odt', vfODT);
  finally
    Document.Free;
  end;
end.
Im docxWriter ist der Teil für das Schreiben eines Bildes ("ProcessImage") allerdings auskommentiert (*), der odtWriter dagegen scheint das zu unterstützen ("WriteRasterImage"), ob es funktioniert habe ich nicht getestet.

------------
(*) Ich weiß von FPSpreadsheet, dass das Schreiben von Bildern in MSOffice eine Tortur ist...

Joh
Lazarusforum e. V.
Beiträge: 360
Registriert: Sa 26. Mai 2012, 17:31
OS, Lazarus, FPC: Win 10 (L 2.2.6 x64 FPC 3.2.2)
CPU-Target: 64Bit

Re: Word/Libre-Office Writer-Export

Beitrag von Joh »

Hmm, ja Bilder (Logo, Piktogramme) muß das ganze beinhalten.
Es geht um Betriebsanweisungen gem. §14 GefStoffV.

Ich werd mir FPVectorial mal angucken.
Vielleicht passts ja doch.

Aber Jorg hat mich schon auf eine passende Idee gebracht:
ich erstelle mir eine odt-Datei, positioniere dort meine zig Textboxen. Und Grafiken. Und Linien.
Diese Datei speichere ich als Vorlage ab.
Dann öffne ich die Datei als zip, extrahiere die content.xml, ersetze die %Labelxxx% und %Textxxx" und speichere die Datei ab.

Ggf wird die Datei dann via
soffice --headless --convert-to "docx:MS Word 2007 XML" test.odt
nach Word konvertiert ;-)

Hier ein Ausschnitt einer content.xml aus einer LibreOffice-Testdatei.

Code: Alles auswählen

<text:p text:style-name="Standard">
	<draw:frame text:anchor-type="paragraph" draw:z-index="0" draw:name="tbLabel1" draw:style-name="gr1" draw:text-style-name="P1" svg:width="4.234cm" svg:height="1.218cm" svg:x="0.457cm" svg:y="0.383cm">
		<draw:text-box>
			<text:p>%Label1%</text:p>
		</draw:text-box>
	</draw:frame>
	<draw:frame text:anchor-type="paragraph" draw:z-index="1" draw:name="tbText1" draw:style-name="gr2" draw:text-style-name="P1" svg:width="3.467cm" svg:height="1.377cm" svg:x="5.801cm" svg:y="0.277cm">
		<draw:text-box>
			<text:p>%Text1%</text:p>
		</draw:text-box>
	</draw:frame>
</text:p>
PS: @Jorg: in der content.xml stehen die Positionen schon drin.
Für mich war eigentlich von vornherein klar, das ich mit Textboxen arbeite.

Und nein, das Sprachmodell darf draußen vor der Tür stehen bleiben.
Ich habe es noch nie genutzt und will es auch nicht.
=> Thema: digitale Demenz.
just my two Beer

Soner
Beiträge: 788
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: Word/Libre-Office Writer-Export

Beitrag von Soner »

Joh hat geschrieben: Do 16. Apr 2026, 13:08 ...
Es geht um Betriebsanweisungen gem. §14 GefStoffV.
...
Es ist kein Antwort auf deine Frage, aber falls die Zielpersonen es nicht bearbeiten sollen, warum erzeugst du keine PDF-Datei, z.B. mit LazReport. Inzwischen kann jeder mit PDF-Dateien umgehen.
Falls man die PDF-Datei bearbeiten möchte, dann kann man es mit Libre Office (Draw) machen.

Joh
Lazarusforum e. V.
Beiträge: 360
Registriert: Sa 26. Mai 2012, 17:31
OS, Lazarus, FPC: Win 10 (L 2.2.6 x64 FPC 3.2.2)
CPU-Target: 64Bit

Re: Word/Libre-Office Writer-Export

Beitrag von Joh »

Soner hat geschrieben: Do 16. Apr 2026, 22:39
Joh hat geschrieben: Do 16. Apr 2026, 13:08 ...
Es geht um Betriebsanweisungen gem. §14 GefStoffV.
...
Es ist kein Antwort auf deine Frage, aber falls die Zielpersonen es nicht bearbeiten sollen, warum erzeugst du keine PDF-Datei, z.B. mit LazReport. Inzwischen kann jeder mit PDF-Dateien umgehen.
Falls man die PDF-Datei bearbeiten möchte, dann kann man es mit Libre Office (Draw) machen.
Ich erzeuge (seit Jahren) diese Dokumente als pdf-Datei.
allerdings nicht mit Lazreport, sondern händisch mit libjpfpdf.
Jetzt kam die Anforderung, das ganze als Word-Dokument dem Endbenutzer zur Verfügung zu stellen, damit der es ändern kann.
=> ich halte das für Schwachfug, muß aber trotzdem dafür den Aufwand abschätzen.

Die ganzen Infos stehen in einer Datenbank, werden in das/die Dokument(e) eingetragen und sollen hinterher händisch geändert werden können... (was für ein Quark)
just my two Beer

Soner
Beiträge: 788
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: Word/Libre-Office Writer-Export

Beitrag von Soner »

Dann würde ich den von Jörg vorgeschlagenen Weg gehen, allerdings würde ich jetzt nicht ODT-Format lernen. Ich würde ein ODT-Dokument mit allen möglichen vorkommenden Möglichkeiten, Checkboxen, Bilder, Texte usw., erstellen, dann hast du alle Styles in "styles.xml"-Datei und diese Datei als Grundlage verwenden. In content.xml kannst du anschauen, was du machen musst, um das zu machen, was du möchtest. Ob das funktioniert, weiß ich nicht, nicht getestet, aber scheint mir einfachste zu sein.
ODT-Dateien sind ZIP-Dateien.
Vielleicht XLSX-Dateien sind auch so.

Benutzeravatar
Zvoni
Beiträge: 651
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz/FPC fixes)
CPU-Target: 64Bit
Wohnort: BW

Re: Word/Libre-Office Writer-Export

Beitrag von Zvoni »

Soner hat geschrieben: Fr 17. Apr 2026, 11:30 Vielleicht XLSX-Dateien sind auch so.
XLSX sind definitiv ZIP-Dateien.
Hab damit schon genug Unfug getrieben
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

Joh
Lazarusforum e. V.
Beiträge: 360
Registriert: Sa 26. Mai 2012, 17:31
OS, Lazarus, FPC: Win 10 (L 2.2.6 x64 FPC 3.2.2)
CPU-Target: 64Bit

Re: Word/Libre-Office Writer-Export

Beitrag von Joh »

Soner hat geschrieben: Fr 17. Apr 2026, 11:30 ODT-Dateien sind ZIP-Dateien.
Vielleicht XLSX-Dateien sind auch so.
Aber docx/xlsx sind chaotischer...
Die Texte sind in der document.xml mindestens 2-fach vorhanden:
- unter <mc:AlternateContent>
- und <mc:Fallback>

Aber AlternateContent und Fallback klingt mir beides nicht nach Original-Inhalt.
Deshalb würde ich eher den Weg .odt gehen und dann nach .xlsx konvertieren.
Das klingt für mich sicherer.

Vor allem, wenn ich über den c't-Artikel (aus dem letzten Jahr?) über das Chaos im docx-Format nachdenke. Da kann besser jemand aus dem LibreOffice-Team über eine saubere Konvertierung nachdenken, als das ich als Alleinkämpfer mich um Microsofts Gewurschtel kümmere.
just my two Beer

wp_xyz
Beiträge: 5420
Registriert: Fr 8. Apr 2011, 09:01

Re: Word/Libre-Office Writer-Export

Beitrag von wp_xyz »

Joh hat geschrieben: Fr 17. Apr 2026, 14:06 Aber docx/xlsx sind chaotischer...
Die Texte sind in der document.xml mindestens 2-fach vorhanden:
- unter <mc:AlternateContent>
- und <mc:Fallback>

Aber AlternateContent und Fallback klingt mir beides nicht nach Original-Inhalt.
Ähnliches hat man in FPSpreadsheet (xlsx) wo in den Charts die Zelldaten wiederholt werden. Ich habe das einfach weggelassen, und siehe da - läuft trotzdem. Also im Zweifelsfall: weglassen, was man nicht versteht, und wo man meint, das wäre für 90% aller Fälle unnötig. Ob etwas nicht funktioniert, sieht man sofort, wenn man die erzeugte Datei in Office lädt.

Hast du schon mal versucht, ein odt-Dokument nach deinen Vorgaben mit FPVectorial zu erstellen? FPVectorial nimmt dir 90% der Arbeit ab, weil die Grundarbeiten schon gemacht sind. Man muss "nur" herausfinden, welche der benötigten Features nicht funktionieren und wo man diese in der Writer-Unit einbauen muss.

Es gibt übrigens im OPM auch noch ein Package fpOdf, mit dem man LibreOffice-Dateien schreiben kann. Letzte Änderung im github-Archiv vor 4 Monaten (https://github.com/dgaspary/fpOdf/tree/master) - d.h. das Projekt ist aktiv, und man kann vielleicht auch Wünsche äußern. Ich selbst habe keine eigene Erfahrung mit diesem Projekt.

Soner
Beiträge: 788
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: Word/Libre-Office Writer-Export

Beitrag von Soner »

fpvectorial sieht gut aus, schau mal lazarus\components\fpvectorial\examples\fpvtextwritetest2 an, man muss bei fpvtextwritetest2.pas oben {$define pdf_test} deaktivieren, dann sieht man weitere Möglichkeiten, man kann auch Tabellen erstellen. Die fehlenden Sachen kann man hinzufügen, in dem man ein mal leere ODT-Datei speichert und dann eine Datei mit nur eine fehlende Sache, dann die beiden vergleicht. Notepad++ hat ein gutes Plugin, es heißt ComparePlus, ich verwende es immer.

Antworten