Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   PDF Merge (https://www.delphipraxis.net/206905-pdf-merge.html)

gaisser 8. Feb 2021 13:21

PDF Merge
 
Hallo Zusammen,

habe Ihr denn Erfahrungen mit PDF Merge?
Was könnt Ihr da am besten empfehlen, damit ich aus der IDE 2 PDF´s in 1 zusammenbringen kann?

Bernhard Geyer 8. Feb 2021 13:32

AW: PDF Merge
 
Wir nutzten PDFBox (https://pdfbox.apache.org).
Sehr gute Ergebnisse bei Textextraction und Splitten von PDF.
Ich vermute der Merge ist auch mit wenig Problemen verbunden.

haentschman 8. Feb 2021 14:03

AW: PDF Merge
 
Hallöle...:P

Ghostscript DLL:
Zitat:

gs -dNOPAUSE -sDEVICE=pdfwrite -sOUTPUTFILE=combine.pdf -dBATCH 1.pdf 2.pdf
https://gist.github.com/brenopolansk...95ed7e865b60f5

generic 8. Feb 2021 15:08

AW: PDF Merge
 
Ein Kunde hat mal was mit ITextSharp in C# programmiert.

gaisser 8. Feb 2021 15:16

AW: PDF Merge
 
Zitat:

Zitat von haentschman (Beitrag 1482497)
Hallöle...:P

Ghostscript DLL:
Zitat:

gs -dNOPAUSE -sDEVICE=pdfwrite -sOUTPUTFILE=combine.pdf -dBATCH 1.pdf 2.pdf
https://gist.github.com/brenopolansk...95ed7e865b60f5

Danke Dir!
Aber es scheint ich bin zu doof das aus Delphi aufzurufen:roll:

Code:
procedure TForm1.Button1Click(Sender: TObject);
var xProg:String;
begin
xProg := 'gs -dNOPAUSE -sDEVICE=pdfwrite -sOUTPUTFILE='+ JvFilenameEdit3.Text +'-dBATCH '+JvFilenameEdit1.Text+' '+JvFilenameEdit2.Text;

    JvCreateProcess1.CommandLine := ExtractFilePath(Application.ExeName) + xProg;
    JvCreateProcess1.Run;

end;
Was mache ich falsch???
gs ist installiert!

Bernhard Geyer 8. Feb 2021 15:16

AW: PDF Merge
 
ITextSharp hat Dual-Lizenz (AGPL bzw. Commercial License).
Als aufpassen das dies nicht eine teure Integration wird.

Bernhard Geyer 8. Feb 2021 15:17

AW: PDF Merge
 
Was ist der Fehlercode/Text

Ich Tipp aber auf fehlende Backslash bei der Pfadangabe

himitsu 8. Feb 2021 15:22

AW: PDF Merge
 
Ich auf eventuelle Leerzeichen in Pfaden (fehlende ")
und vorallem auf ein fehlendes Leerzeichen vor -dBATCH :angle:

gaisser 8. Feb 2021 15:23

AW: PDF Merge
 
Meldung: Das System kann die angegebe Datei nicht finden!
Backshlash habe ich drinne, mir scheint das er einfach "gs" nicht finden kann, wenn ich es im CMD mache, dann habe ich das gleiche!

gaisser 8. Feb 2021 15:24

AW: PDF Merge
 
gs -dNOPAUSE -sDEVICE=pdfwrite -sOUTPUTFILE=C:\Austausch\Test.pdf -dBATCH C:\Austausch\DV\jg121035219.PDF C:\Austausch\DV\jg1209120740.PDF


das wird versucht aufzurufen!

Habe ich vielleicht das gs falsch installiert?

habs von hier:
https://www.ghostscript.com/download.html

gaisser 8. Feb 2021 15:51

AW: PDF Merge
 
Ich habe den Fehler gefunden!
Ich muss den kompletten Pfad angeben, dann funktioniert es!
Coole Sache :)

Delphi-Quellcode:
var
  xProg: String;
begin
  xProg := '"C:\Program Files (x86)\gs\gs9.53.3\bin\gswin32.exe" -dNOPAUSE -sDEVICE=pdfwrite -sOUTPUTFILE=' + JvFilenameEdit3.Text
    + ' -dBATCH ' + JvFilenameEdit1.Text + ' ' + JvFilenameEdit2.Text;
  showmessage(xprog);
  JvCreateProcess1.CommandLine := xProg;
  JvCreateProcess1.Run;

end;

himitsu 8. Feb 2021 16:03

AW: PDF Merge
 
Zitat:

Delphi-Quellcode:
CommandLine := ExtractFilePath(Application.ExeName) + 'gs ...';

Liegt denn GS im selben Verzeichnis, wie deine Application?



Und dennoch solltest du sicherheitshalber "eventuelle" Leerzeichen beachten (Parameter in " einschließen), nicht nur bei der EXE, sondern auch bei den PDFs.
und das eine fehlende Leerzeichen einfügen. siehe #8

Außerdem ist denn das aktuelle Arbeitsverzeichnis auch das Verzeichnis wo die PDFs liegen?
Sicherheitshalber immer nur mit absoluten Pfaden arbeiten.

HolgerX 9. Feb 2021 17:26

AW: PDF Merge
 
Hmm..

Alternativ kannst du auch von GS die DLL direkt in deinem Programm verwenden, dann braucht gar kein GS mehr installiert werden und es muss auch kein (externes) Programm mehr aufgerufen werden.

Als Parameter werden die gleichen an einen Funktionsaufruf übergeben, wie beim Aufruf der Exe.

Die API-Pas files waren von Alessandro Briosi und müssen nur auf UniCode angepasst werden.

gaisser 10. Feb 2021 10:05

AW: PDF Merge
 
Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
var
  argv: Array of PAnsiChar;
  instance: Pointer;
  x: Integer;
begin
  // new(instance); //how many bytes, this really doesn't make sense with a untyped pointer!
  // setlength(argv, 4);
  // argv[0] := PANsiChar('ps2pdf');
  // argv[1] := PAnsiChar('-dNOPAUSE');
  // argv[2] := PAnsiChar('-dBATCH');
  // argv[3] := PAnsiChar('-dSAFER');
  // gsapi_init_with_args(instance, Length(argv), PPAnsiChar(argv));
  // gsapi_exit(instance);
  gsapi_new_instance(instance, instance);
  // ShowMessage(inttostr(x));
  // new(instance); //how many bytes, this really doesn't make sense with a untyped pointer!
  setlength(argv, 5);
  argv[0] := PAnsiChar('');
  argv[1] := PAnsiChar('-dNOPAUSE');
  argv[2] := PAnsiChar('-sDEVICE=pdfwrite');
  argv[3] := PAnsiChar('-sOUTPUTFILE= ' + JvFilenameEdit3.Text);
  argv[4] := PAnsiChar(' -dBATCH ' + JvFilenameEdit1.Text + ' ' +
    JvFilenameEdit2.Text);
  gsapi_init_with_args(instance, Length(argv), PPAnsiChar(argv));
  gsapi_exit(instance);
  showmessage('fertig!');

end;
Danke HolgerX!
Das funktioniert aber nicht, kommt nicht mal ne Fehlermeldung!

jziersch 10. Feb 2021 10:16

AW: PDF Merge
 
Falls es ohne Abhängigkeit zu GhostScript laufen soll:

WPViewPDF PLUS kann mehrere PDFs in eine neue zusammen führen. Es kann auch Seiten aus einer PDF herausnehmen und als Wasserzeichen (z.b. als Briefkopf) unter existierende Seiten aus einer anderen PDF legen. Seiten können auch gelöscht werden, dabei werden dann die Resourcen, die nur von diesen Seiten verwenden werden, nicht in der neuen PDF eingebunden.

Viele Grüsse,
Julian

Blup 10. Feb 2021 11:33

AW: PDF Merge
 
argv[0] // ein Pointer auf nil, sicher das die API damit etwas anfangen kann?
argv[3] // warum ein Leerzeichen nach dem = ?
argv[4] // warum ein Leerzeichen am Anfang ?

gaisser 10. Feb 2021 14:41

AW: PDF Merge
 
Ich blick es nicht:oops:
Was mache ich falsch, es kommt hier nun immer der Errocode 100
Kann vielleicht mal jemand Source testen?

Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
var
  ArgV: Array of PAnsiChar;
  instance: Pointer;
  x, code: Integer;
  xArgV: PPAnsiChar;
begin

  code := gsapi_new_instance(instance, nil);
  if code < 0 then
    raise Exception.Create
      ('Impossible to open an instance of ghostscript. Error code: ' +
      IntToStr(code));

  setlength(ArgV, 4);

  ArgV[0] := PAnsiChar('-dNOPAUSE' + #0);
  ArgV[1] := PAnsiChar('-sDEVICE=pdfwrite' + #0);
  ArgV[2] := PAnsiChar('-sOUTPUTFILE="' + JvFilenameEdit3.Text + '"' + #0);
  ArgV[3] := PAnsiChar('-dBATCH ' + '"' + JvFilenameEdit1.Text + '"' + ' ' + '"'
    + JvFilenameEdit2.Text + '"' + #0);

  code := gsapi_init_with_args(instance, Length(ArgV), @ArgV);
  if code < 0 then
    raise Exception.Create('ERROR: init_args: ' + IntToStr(code));

  gsapi_exit(instance);
  showmessage('fertig!');

end;
Ich verzweifle:roll:

HolgerX 10. Feb 2021 16:48

AW: PDF Merge
 
Hmm..

JvFilenameEdit1.Text dürfte wohl Unicode sein...

Ghostscipt DLL kann nur ANSI oder UTF8

Für UTF8 muss das Encodiung vor gsapi_init_with_args gesetzt werden (gsapi_set_arg_encoding(instance, GS_ARG_ENCODING_UTF8))

Somit die UnicodeStrings nach UTF8, dann dass Encoding setzen, dann gsapi_init_with_args.

haentschman 11. Feb 2021 05:09

AW: PDF Merge
 
Moin...:P

ein funktionierendes Beispiel:
Delphi-Quellcode:
function TGhostscript.PDFShrink(FileName: string): Boolean;
var
  TargetFileName: string;
  InitError: Integer;
begin
  if FDLLHandle = 0 then
  begin
    if not LoadDLL(FDLLPath) then
    begin
      Result := False;
      Exit;
    end;
  end;
  try
    TargetFileName := IncludeTrailingPathDelimiter(ExtractFilePath(FileName)) + conFileNameTempPDF;
    SetLength(FParameters, 7);
    FParameters[0] := '';
    FParameters[1] := '-dNOPAUSE';
    FParameters[2] := '-dBATCH';
    FParameters[3] := '-dPDFSETTINGS=/ebook';
    FParameters[4] := '-sDEVICE=pdfwrite';
    FParameters[5] := PAnsiChar(AnsiString('-sOutputFile=' + TargetFileName));
    FParameters[6] := PAnsiChar(AnsiString(FileName));

    InitError := FGsApiInitWithArgs(FGsInstance, Length(FParameters), FParameters);
    Result := (InitError = 0);
    if InitError <> 0 then
    begin
      if Assigned(FOnError) then
      begin
        FOnError(Self, Format('Fehlercode: %d', [InitError]));
      end;
    end;
  finally
    FGsApiExit(FGsInstance);
  end;

  if Result then
  begin
    if not TToolsIO.IsFileInUse(FileName) then
    begin
      try
        TFile.Delete(FileName);
        if not TToolsIO.IsFileInUse(FileName) then
        begin
          if not RenameFile(TargetFileName, FileName) then
          begin
            if Assigned(FOnError) then
            begin
              FOnError(Self, Format('Fehler beim Umbenennen von TempPDF.pdf: %s', ['Rename']));
            end;
          end;
        end
        else
        begin
          if Assigned(FOnError) then
          begin
            FOnError(Self, Format('Fehler beim Umbenennen von TempPDF.pdf: %s', ['InUse']));
          end;
        end;
      except
        if Assigned(FOnError) then
        begin
          FOnError(Self, Format('Fehler beim Umbenennen von TempPDF.pdf: %s', ['Delete']));
        end;
      end;
    end
    else
    begin
      if Assigned(FOnError) then
      begin
        FOnError(Self, Format('Fehler beim Umbenennen von TempPDF.pdf (in Benutzung): %s', [FileName]));
      end;
    end;
  end;
end;
PS:
So eine Funktion gehört nicht auf die Form sondern in eine seperate Unit / Klasse. Dieser Klasse übergiebst du dann die Dateien...:zwinker:

gaisser 12. Feb 2021 09:42

AW: PDF Merge
 
Hi Danke für den Test, aber ich will ja Merge machen, aber das funktioniert nicht.
Habe es auch in einer eigenen Klasse deklariert!
Delphi-Quellcode:
function TGhostscript.PDFMerge(InFile1, InFile2, InFile3,
  OutFile: Ansistring): Boolean;
var
  xDLLFile: String;
begin
  if not FileExists(InFile1) then
  begin
    ShowMessage('PDF Nr1 wurde nicht gefunden!!!');
    Exit;
  end;
  if not FileExists(InFile2) then
  begin
    ShowMessage('PDF Nr2 wurde nicht gefunden!!!');
    Exit;
  end;
  if FDLLHandle = 0 then
  begin
    xDLLFile := IncludeTrailingBackslash(FDLLPath) + conDLLName;
    if FileExists(xDLLFile) then
      LoadDLL(xDLLFile);
  end;
  try
    SetLength(FParameters, 4);
    FParameters[0] := ('-dNOPAUSE');
    FParameters[1] := PAnsiChar('-dBATCH ' + '"'+InFile1+ '"' +' ' +
      '"'+InFile2+ '"') ;
    FParameters[2] := ('-sDEVICE=pdfwrite');
    FParameters[3] := PAnsiChar('-sOUTPUTFILE=' + '"'+OutFile+ '"' );

    Result := (FGsApiInitWithArgs(FGsInstance, Length(FParameters),
      FParameters) = 0);

    ShowMessage(booltostr(Result));
  finally
    FGsApiExit(FGsInstance);
  end;
end;

haentschman 12. Feb 2021 10:11

AW: PDF Merge
 
...griegst du gleich. 8-) Ich hatte gestern Probleme mit "dynamischen" Parametern.
https://www.delphipraxis.net/206950-...usfuellen.html
Delphi-Quellcode:
FParameters[1] := PAnsiChar('-dBATCH ' + '"'+InFile1+ '"' +' ' + '"'+InFile2+ '"') ;
Das ist der Knackpunkt. Die Files gehören ans Ende als separate Parameter!

himitsu 12. Feb 2021 10:15

AW: PDF Merge
 
@gaisser: Bei dieser ART von DLLs, wo man die "selben" Parameter reingibt, wie für die EXE,
dort muß man oftmals/meistens auch den Param0 mit reingeben (gefüllt oder leer ist oft egal), also den "Programmaufruf" und erst ab Param1 die Parameter, da in der DPP praktisch der "selbe" Code steckt, wie in der EXE.
Delphi-Quellcode:
FParameters[0] := '';
FParameters[1] := ...;

gaisser 15. Feb 2021 08:06

AW: PDF Merge
 
Super, vielen Dank!
Also ich hab mal die Unit wo funktioniert angehängt!
Delphi-Quellcode:
unit uGhostscript;

interface

uses
  Winapi.Windows, Vcl.dialogs, Generics.Collections,
  System.Classes, System.SysUtils, System.IOUtils;

const
  conDLLName = 'gsdll32.dll';
  conFileNameTempPDF = 'TempPDF.pdf';

type
  TStdIoFunction = function(CallerHandle: Pointer; Buffer: PAnsiChar;
    Length: Integer): Integer stdcall;
  TGsInit = function(I: Pointer; P: Pointer): Integer; stdcall;
  TGsApiInitWithArgs = function(I: Pointer; L: Integer; A: array of PAnsiChar)
    : Integer; stdcall;
  TGsApiExit = function(I: Pointer): Integer; stdcall;
  TGsApiDeleteInstance = function(I: Pointer): Integer; stdcall;

  TOnErrorEvent = procedure(Sender: TObject; MessageText: string) of object;

  TGhostscript = class
  private
    FDLLPath: string;
    FDLLHandle: THandle;
    FGsInit: TGsInit;
    FGsApiInitWithArgs: TGsApiInitWithArgs;
    FGsApiExit: TGsApiExit;
    FGsApiDeleteInstance: TGsApiDeleteInstance;
    FGsInstance: Pointer;
    FParameters: array of PAnsiChar;
    FOnError: TOnErrorEvent;
    function LoadDLL(PathDLL: string): Boolean;
    function IsFileInUse(FileName: string): Boolean;
  public
    constructor Create(PathDLL: string = '');
    destructor Destroy; override;
    property OnError: TOnErrorEvent read FOnError write FOnError;
    function PDFShrink(FileName: string): Boolean;
    function PDFMerge(OutputFile: string; FileList: TStrings): Boolean;
  end;

implementation

{ TGhostscript }

// Initialisation
constructor TGhostscript.Create(PathDLL: string);
begin
  FDLLPath := PathDLL;
  FDLLHandle := 0;
end;

destructor TGhostscript.Destroy;
begin
  if FDLLHandle > 0 then
  begin
    FreeLibrary(FDLLHandle);
  end;
  inherited;
end;

// Work
function TGhostscript.LoadDLL(PathDLL: string): Boolean;
var
  CurrentDLLPath: string;
begin
  if PathDLL = '' then
  begin
    CurrentDLLPath := IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0)))
      + conDLLName;
  end
  else
  begin
    CurrentDLLPath := PathDLL;
  end;
  FDLLHandle := LoadLibrary(PChar(CurrentDLLPath));
  if FDLLHandle > 0 then
  begin
    FGsInit := GetProcAddress(FDLLHandle, 'gsapi_new_instance');
    Result := (FGsInit(@FGsInstance, nil) = 0);
    if Result then
    begin
      FGsApiInitWithArgs := GetProcAddress(FDLLHandle, 'gsapi_init_with_args');
      FGsApiExit := GetProcAddress(FDLLHandle, 'gsapi_exit');
      FGsApiDeleteInstance := GetProcAddress(FDLLHandle,
        'gsapi_delete_instance');
    end
    else
    begin
      FOnError(Self, 'Die Ghostscript Instanz konnte nicht erzeugt werden.');
      Result := False;
    end;
  end
  else
  begin
    FOnError(Self, Format('Die Ghostscript DLL %s wurde nicht geladen.',
      [QuotedStr(CurrentDLLPath)]));
    Result := False;
  end;

end;

function TGhostscript.IsFileInUse(FileName: string): Boolean;
var
  Stream: TFileStream;
begin
  Result := False;
  Stream := nil;
  if not FileExists(FileName) then
    Exit;
  try
    Stream := TFileStream.Create(FileName, fmOpenRead);
    // Alternative: 'or fmShareExclusive'
  except
    Result := True;
  end;
  Stream.Free;
end;

function TGhostscript.PDFMerge(OutputFile: string; FileList: TStrings): Boolean;
var
  ParametersTemp: TList<AnsiString>;
  InitError: Integer;
  procedure CreateMergeFiles;
  var
    I: Integer;
  begin
    ParametersTemp := TList<AnsiString>.Create;
    for I := 0 to FileList.Count - 1 do
    begin
      ParametersTemp.Add(AnsiString(FileList[I])); // <--
      FParameters[I + 8] := PAnsiChar(ParametersTemp[I]); // <--
    end;
  end;

var
  xDLLFile: String;
begin
  xDLLFile := IncludeTrailingBackslash(FDLLPath) + conDLLName;
  if FileExists(xDLLFile) then
    LoadDLL(xDLLFile);
  if FDLLHandle = 0 then
  begin
    if not LoadDLL(xDLLFile) then
    begin
      Result := False;
      Exit;
    end;
  end;
  try
    ParametersTemp := TList<AnsiString>.Create; // <--
    try
      SetLength(FParameters, FileList.Count + 8);

      FParameters[0] := '';
      FParameters[1] := '-dNOPAUSE';
      FParameters[2] := '-dBATCH';
      FParameters[3] := '-Author=ProTRxxx Software GmbH';
      FParameters[4] := '-Creator=ProTRxxx Software GmbH';
      FParameters[5] := '-dPDFSETTINGS=/printer';
      FParameters[6] := '-sDEVICE=pdfwrite';
      FParameters[7] := PAnsiChar(AnsiString('-sOutputFile=' + OutputFile));
      CreateMergeFiles;

      InitError := FGsApiInitWithArgs(FGsInstance, Length(FParameters),
        FParameters);
      Result := (InitError = 0);
      if InitError <> 0 then
      begin
        if Assigned(FOnError) then
        begin
          FOnError(Self, Format('Fehlercode: %d', [InitError]));
        end;
      end;
    finally
      ParametersTemp.Free;
    end;
  finally
    FGsApiExit(FGsInstance);
  end;

  if not Result then
  begin
    if Assigned(FOnError) then
    begin
      FOnError(Self, Format('Fehler beim Erstellen: %s', [OutputFile]));
    end;
  end;
end;

function TGhostscript.PDFShrink(FileName: string): Boolean;
var
  TargetFileName: string;
begin
  if FDLLHandle = 0 then
  begin
    LoadDLL(FDLLPath);
  end;
  try
    TargetFileName := IncludeTrailingPathDelimiter(ExtractFilePath(FileName)) +
      conFileNameTempPDF;
    SetLength(FParameters, 7);
    FParameters[0] := '';
    FParameters[1] := '-dNOPAUSE';
    FParameters[2] := '-dBATCH';
    FParameters[3] := '-dPDFSETTINGS=/ebook';
    FParameters[4] := '-sDEVICE=pdfwrite';
    FParameters[5] := PAnsiChar(AnsiString('-sOutputFile=' + TargetFileName));
    FParameters[6] := PAnsiChar(AnsiString(FileName));

    Result := (FGsApiInitWithArgs(FGsInstance, Length(FParameters),
      FParameters) = 0);

  finally
    FGsApiExit(FGsInstance);
  end;

  if Result then
  begin
    if not IsFileInUse(FileName) then
    begin
      TFile.Delete(FileName);
      RenameFile(TargetFileName, FileName);
    end;
  end
end;

end.
Der Aufruf ist dann :
Delphi-Quellcode:
procedure TForm1.Button3Click(Sender: TObject);
var
  xPDF: TGhostscript;
  xFiles:TStringList;
begin
if not Assigned(xPDF) then
  xPDF := TGhostscript.Create(ExtractFilePath(Application.ExeName));
  xFiles:=TStringList.Create;
  xFiles.Add(JvFilenameEdit1.Text);
  xFiles.Add(JvFilenameEdit2.Text);
  xPDF.PDFMerge(JvFilenameEdit3.Text,xFiles );
  xFiles.Free;
  xPDF.Free;
end;
Danke Euch allen:-D

haentschman 15. Feb 2021 09:01

AW: PDF Merge
 
:P...soviel "Diebstahl" ist ein :cheers: auf den nächsten Delphi Tagen wert... :thumb:

gaisser 15. Feb 2021 09:05

AW: PDF Merge
 
Mit Sicherheit :):):):bouncing4::bouncing4::bouncing4:
Aber ein Phänomen hab ich noch...
Unter Debug Comp geht es, aber unter Release nicht, an was kann dies liegen? Er bekommt den FDDLPath nicht zugewiesen???

elmar.faber 30. Sep 2021 14:49

AW: PDF Merge
 
Hallo,

habe gerade versucht, zwei FastReport PDF's mit Ghostscript zu mergen aber
trotz Aufrufs von gsapi_set_arg_encoding(FGsInstance, GS_ARG_ENCODING_UTF8),
wie von HolgerX vorgeschlagen, werden die Umlaute in Hieroglyphen umgewandelt.

Hat jemand eine Idee, wie man das korrigieren kann?

Viele Grüße

HolgerX 1. Okt 2021 07:02

AW: PDF Merge
 
Hmm..

Zitat:

Zitat von elmar.faber (Beitrag 1495599)
Hallo,

habe gerade versucht, zwei FastReport PDF's mit Ghostscript zu mergen aber
trotz Aufrufs von gsapi_set_arg_encoding(FGsInstance, GS_ARG_ENCODING_UTF8),
wie von HolgerX vorgeschlagen, werden die Umlaute in Hieroglyphen umgewandelt.

Hasst Du die FileNamen auch vorher in ein UTF8 String konvertiert (bei Verwendung von GS_ARG_ENCODING_UTF8)?

In den Quelltexten von gaisser wird nur nach AnsiString konvertiert und nicht nach UTF8, und dann gehen schon so einige Zeichen verloren...

elmar.faber 1. Okt 2021 12:35

AW: PDF Merge
 
Ja ich habe überall wo "Ansi" steht UTF8 eingesetzt. Fehler kamen keine...
Aufgeruft habe ich die Funktion an dieser Stelle
Delphi-Quellcode:
...
    FGsInit := GetProcAddress(FDLLHandle, 'gsapi_new_instance');
    Result := (FGsInit(@FGsInstance, nil) = 0);
    if Result then
    begin
      Fgsapi_set_arg_encoding := GetProcAddress(FDLLHandle, 'gsapi_set_arg_encoding');
      Fgsapi_set_arg_encoding(FGsInstance, GS_ARG_ENCODING_UTF8);
...

HolgerX 5. Okt 2021 09:18

AW: PDF Merge
 
Hmm...

Zitat:

Zitat von elmar.faber (Beitrag 1495636)
Ja ich habe überall wo "Ansi" steht UTF8 eingesetzt. Fehler kamen keine...
Aufgeruft habe ich die Funktion an dieser Stelle
Delphi-Quellcode:
...
    FGsInit := GetProcAddress(FDLLHandle, 'gsapi_new_instance');
    Result := (FGsInit(@FGsInstance, nil) = 0);
    if Result then
    begin
      Fgsapi_set_arg_encoding := GetProcAddress(FDLLHandle, 'gsapi_set_arg_encoding');
      Fgsapi_set_arg_encoding(FGsInstance, GS_ARG_ENCODING_UTF8);
...

Die Reihenfolge ist bei mir:

gsapi_new_instance
gsapi_set_arg_encoding
gsapi_init_with_args
gsapi_exit

Bei den Argumenten (gsapi_init_with_args) muss der erste Eintrag ein '' sein, da dieser von der GS-APi ignoriert wird (https://www.ghostscript.com/doc/current/API.htm#init).

Bei den anderen Argumenten, welche Strings als Wert enhalten musst du deinen Delphistring mit UTF8Encode nach UTF umcodieren!

Einfach nur aus 'AnsiString' ein 'UTF8String' zu machen, wird wohl nichts bringen...

Sprich z.B. (Src von gaisser):

Delphi-Quellcode:
      SetLength(FParameters, 8);

      FParameters[0] := '';
      FParameters[1] := '-dNOPAUSE';
      FParameters[2] := '-dBATCH';
      FParameters[3] := '-Author=ProTRxxx Software GmbH';
      FParameters[4] := '-Creator=ProTRxxx Software GmbH';
      FParameters[5] := '-dPDFSETTINGS=/printer';
      FParameters[6] := '-sDEVICE=pdfwrite';
      FParameters[7] := PAnsiChar(AnsiString('-sOutputFile=' + UTF8Encode(OutputFile)));

elmar.faber 11. Okt 2021 06:46

AW: PDF Merge
 
Hallo,

vielen Dank für dein Hilfe aber ich kriege es nicht hin, habe jetzt viel herumexperimentiert
und versucht mit UTF8Encode die Strings um zu kodieren aber ich bekomme immer das gleiche
Resultat. Keine Ahnung was ich jetzt noch versuchen kann...

Frickler 11. Okt 2021 09:46

AW: PDF Merge
 
Ich nehme für sowas immer das Befehlszeilenprogramm PDFTK.

pdftk dateiname1.pdf dateiname2.pdf ... dateinameN.pdf cat output ausgabedatei.pdf

hängt die alle aneinander an. Man kann sogar Seiten drehen dabei, einzelne Seiten ausschneiden und vieles mehr.

Man braucht die EXE Datei und eine DLL, und das wars. Keine Installation.

elmar.faber 25. Okt 2021 08:08

AW: PDF Merge
 
Ja so habe ich es jetzt auch gelöst.
Hätte es nur gerne hinbekommen...


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:03 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz