Zugferd XML in Pdf einfügen Error: Can't take the address of constant expressions

Zur Vorstellung von Komponenten und Units für Lazarus
Antworten
Benutzeravatar
KoBraSoft
Beiträge: 125
Registriert: So 6. Jun 2021, 09:57
OS, Lazarus, FPC: die zu Zeit aktuellen Versionen, überwiegend Linux
CPU-Target: 64Bit 32 Bit
Kontaktdaten:

Zugferd XML in Pdf einfügen Error: Can't take the address of constant expressions

Beitrag von KoBraSoft »

Hallo,
ich habe mir zum Einfügen einer Zugferd XML in ein vorhandenes Pdf folgende Vorgehensweise überlegt:
  • xml Stream komprimieren
    geht problemlos mit CompressStream aus fpPdf in fcl-pdf
  • komprimieten xml Stream in pdf Stream einfügen
    Hierzu habe ich mich für AddInDirectObject aus fppdfobjects.pp in fcl-pdf entschieden
    Achtung: fppdfobjects ist erst ab Lazarus 4.x enthalten, ich verwende die trunk version
    Hat jemand eine bessere Idee die xml in ein pdf einzufügen? Bitte in die Kommentare schreiben.

Code: Alles auswählen

    T := TMemoryStream.Create;
    CompressStream(S,T);
    if OpenDialog1.Execute then begin
      F:=TFileStream.Create(OpenDialog1.FileName,fmOpenRead or fmShareDenyWrite);
      PdfDoc:=TPDFDocument.Create();
      P:=TPDFParser.Create(F);
      P.ParseDocument(PdfDoc);
      PdfDoc.AddInDirectObject(PdfInd);
      T.Read(TPdfIndirect(PdfInd).Stream,T.size);
    end;
Leider komme ich beim Einlesen des komprimierten xml Streams in Pdfind nicht weiter. Ich erhalte die Fehlermeldung "Can't take the address of constant expressions"
Ich verstehe, dass TPdfIndirect(PdfInd).Stream eine Konstante ist.
Wie kriege ich den Steam da rein?
zugferdGenerator.zip
(346.56 KiB) 78-mal heruntergeladen
Konrad

www.KoBraSoft.de

Joh
Lazarusforum e. V.
Beiträge: 288
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: Zugferd XML in Pdf einfügen Error: Can't take the address of constant expressions

Beitrag von Joh »

wie wärs mit ghostscript:

Unter Windows:

Code: Alles auswählen

SET pfad=.\
"c:\Program Files\GS\gs10.03.1\bin\gswin64c.exe" --permit-file-read=%pfad% -sDEVICE=pdfwrite -dPDFA=3 -sColorConversionStrategy=RGB -sZUGFeRDXMLFile=%pfad%factur-x.xml -sZUGFeRDProfile=%pfad%srgb.icc -sZUGFeRDVersion=2p1 -sZUGFeRDConformanceLevel="EN 16931" -o %pfad%invoice.GS.pdf %pfad%zugferd.ps %pfad%Invoice.pdf
Die Dateien heißen bei mir:
- factur-x.xml
- invoice.pdf

erzeugt wird
- invoice.GS.pdf

Aber wenn du einen sauberen internen Weg findest: gerne.

die
- srgb.icc
- zugferd.ps
stehen bei mir im aktuellen Vrz.
just my two Beer

Benutzeravatar
KoBraSoft
Beiträge: 125
Registriert: So 6. Jun 2021, 09:57
OS, Lazarus, FPC: die zu Zeit aktuellen Versionen, überwiegend Linux
CPU-Target: 64Bit 32 Bit
Kontaktdaten:

Re: Zugferd XML in Pdf einfügen Error: Can't take the address of constant expressions

Beitrag von KoBraSoft »

Joh hat geschrieben: Mo 30. Dez 2024, 11:32 wie wärs mit ghostscript:
Danke für den Hinweis.
Das ist Plan B. Ob ich Plan A tatsächlich umsetzen kann, wird sich zeigen.
Unter Windows:
Ich arbeite mit Linux. Ich weis, dass es ghostscript auch unter Linux läuft. Aber mir wäre eine Lösung nur mit Lazarus lieber. Ich bräuchte dann die pdf und die xml nicht als Datei zwischen speichern und könnte beides bequem aus der DB erzeugen.
Konrad

www.KoBraSoft.de

Stevie
Beiträge: 172
Registriert: Di 27. Feb 2024, 22:40

Re: Zugferd XML in Pdf einfügen Error: Can't take the address of constant expressions

Beitrag von Stevie »

... das Problem liegt darin, dass die Variablen, die Du übergeben willst, Properties und keine 'echten' Variablen sind. Das lässt sich aber ziemlich einfach umgehen, wenn Du die Properties kurzfristig zwischenspeicherst:

Code: Alles auswählen

var
 // ...
  StreamSize : Int64;
  Stream : TPDFStream;
  // ...
... und weiter:

Code: Alles auswählen

      // ...
      StreamSize := T.Size;
      Stream := TPdfIndirect(PdfInd).Stream;
      T.Read(Stream, StreamSize);
      // ...
Ich habe mir nicht die Mühe gemacht, das Programm im Detail zu testen, aber zumindest kompiliert es. :-)

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

Re: Zugferd XML in Pdf einfügen Error: Can't take the address of constant expressions

Beitrag von wp_xyz »

Kann mir nicht vorstellen, dass das funktioniert. In "T.ReadStream(Stream, StreamSize)" mit "StreamSize = T.Size" liest der Stream T StreamSize Bytes und schreibt sie in die Variable "Stream" - das ist zwar als TMemorystream deklariert, aber die Stream-Lesemethode sieht nur eine allgemeine Variable. Die ist als Pointer zwar 8 Bytes groß, aber für den lesenden Stream zählt nur die StreamSize-Angabe. Du überschreibst also diese 8 Bytes und alle im Stack folgenden StreamSize-8 Bytes mit dem Inhalt des Streams T. Das gibt einen hässlichen Crash...

Richtig wäre es, einen temporären Speicherblock in der gewünschten Größe zu reservieren, den einen Stream dorthin einzulesen und den Speicherblock dann in den anderen Stream zu schreiben.

Ohne jetzt im Detail auf deine Anforderung einzugehen, würde ich im allgemeinen folgendermaßen vorgehen, um den Inhalt des einen Streams (srcStream) in den anderen Stream (destStream) zu kopieren:

Code: Alles auswählen

var
  buf: array of byte;
begin
  ...
  SetLength(buf, srcStream.Size);
  srcStream.Read(buf[0], Length(buf));
  destStream.Write(buf[0], Length(buf));
  ...

Stevie
Beiträge: 172
Registriert: Di 27. Feb 2024, 22:40

Re: Zugferd XML in Pdf einfügen Error: Can't take the address of constant expressions

Beitrag von Stevie »

Okay, guter Punkt. Wie gesagt: ich hatte mir das Thema nicht inhaltlich angeschaut, sondern lediglich den Syntaxfehler behoben. Dass es da auch einen semantischen Fehler gibt, habe ich nicht betrachtet...

Antworten