ActiveDelphi - Índice do Fórum ActiveDelphi
.: O site do programador Delphi! :.
 
 FAQFAQ   PesquisarPesquisar   MembrosMembros   GruposGrupos   RegistrarRegistrar 
 PerfilPerfil   Entrar e ver Mensagens ParticularesEntrar e ver Mensagens Particulares   EntrarEntrar 

Unir vários PDF's em apenas um documento [Resolvido]
Ir à página 1, 2  Próximo
 
Novo Tópico   Responder Mensagem    ActiveDelphi - Índice do Fórum -> Delphi
Exibir mensagem anterior :: Exibir próxima mensagem  
Autor Mensagem
natanbh1
Colaborador
Colaborador


Registrado: Terça-Feira, 15 de Março de 2011
Mensagens: 3093
Localização: Belo Horizonte - MG

MensagemEnviada: Sex Out 23, 2015 11:08 am    Assunto: Unir vários PDF's em apenas um documento [Resolvido] Responder com Citação

Alguém conhece alguma maneira (via componente delphi ou procedimento) de unir vários pequenos arquivos pdf's (mais de 1000) em um só?

Encontrei alguns programas freeware prontos mas precisaria incorporar esta utilidade em um programa que criei no Delphi.
_________________
''A persistência é o caminho para o êxito.''
Charlie Chaplin


Editado pela última vez por natanbh1 em Seg Dez 07, 2015 2:30 pm, num total de 7 vezes
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Enviar E-mail
marcieldeg
Colaborador
Colaborador


Registrado: Terça-Feira, 5 de Abril de 2011
Mensagens: 1054
Localização: Vitória - ES

MensagemEnviada: Sex Out 23, 2015 11:59 am    Assunto: Responder com Citação

Você pode incorporar a dll do ghostscript ao seu projeto.

Nesse link tem um exemplo de como usar via linha de comando; a chamada da dll é semelhante:

http://stackoverflow.com/questions/8158584/ghostscript-to-merge-pdfs-compresses-the-result
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
natanbh1
Colaborador
Colaborador


Registrado: Terça-Feira, 15 de Março de 2011
Mensagens: 3093
Localização: Belo Horizonte - MG

MensagemEnviada: Sex Out 23, 2015 2:02 pm    Assunto: Responder com Citação

Não conhecia o Ghostscript. Baixei e instalei para conhecer.

Copiei a dll gsdll32.dll para pasta do aplicativo.

Mas sei muito pouco sobre a utilização de dll.

Código:
gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=out.pdf in1.pdf in2.pdf


Poderia me ajudar a implementar o comando acima através da dll?
_________________
''A persistência é o caminho para o êxito.''
Charlie Chaplin


Editado pela última vez por natanbh1 em Sex Out 23, 2015 4:57 pm, num total de 1 vez
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Enviar E-mail
natanbh1
Colaborador
Colaborador


Registrado: Terça-Feira, 15 de Março de 2011
Mensagens: 3093
Localização: Belo Horizonte - MG

MensagemEnviada: Sex Out 23, 2015 4:16 pm    Assunto: Responder com Citação

Tentei utilizar a dll do GhostScript mas sem sucesso.

Consegui resolver com o ActiveX:
PDF Split Merge ActiveX Component 2.0.2007.718

Link para download:
http://ziggi.uol.com.br/downloads/active-tss

Obrigado pela ajuda
_________________
''A persistência é o caminho para o êxito.''
Charlie Chaplin
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Enviar E-mail
natanbh1
Colaborador
Colaborador


Registrado: Terça-Feira, 15 de Março de 2011
Mensagens: 3093
Localização: Belo Horizonte - MG

MensagemEnviada: Seg Out 26, 2015 8:46 am    Assunto: Responder com Citação

Bom dia pessoal,

Estou reabrindo o tópico porque a licença do activex PDF Split Merge é Shareware (gratuito para teste 30 dias).

Alguém conhece algum componente para Delphi que unifique pdf's gratuitamente?

Ou que pode me ajudar na implementação da dll do Ghostscript?

Obrigado.
_________________
''A persistência é o caminho para o êxito.''
Charlie Chaplin
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Enviar E-mail
strak2012
Colaborador
Colaborador


Registrado: Segunda-Feira, 13 de Janeiro de 2014
Mensagens: 1518
Localização: Maceió - AL

MensagemEnviada: Seg Out 26, 2015 12:22 pm    Assunto: Responder com Citação

Segue a forma de unir varios pdfs em uma só com o uso do Ghostscript
Código:
const
  GS_ARG_ENCODING_LOCAL = 0;
  GS_ARG_ENCODING_UTF8 = 1;
  e_Quit = -990;

type

  TGSAPIrevision = packed record
    product: PChar;
    copyright: PChar;
    revision: longint;
    revisiondat: longint;
  end;

  PGSAPIrevision = ^TGSAPIrevision;
  Pgs_main_instance = Pointer;
  PPChar = array of PChar;

  { funções e procedure da dll gsdll32.dll }
function gsapi_new_instance(pinstance: Pgs_main_instance;
  caller_handle: Pointer): Integer; stdcall; external 'gsdll32.dll';
function gsapi_init_with_args(pinstance: Pgs_main_instance; argc: Integer;
  argv: PPChar): Integer; stdcall; external 'gsdll32.dll';
function gsapi_exit(pinstance: Pgs_main_instance): Integer; stdcall;
  external 'gsdll32.dll';
procedure gsapi_delete_instance(pinstance: Pgs_main_instance); stdcall;
  external 'gsdll32.dll';
function gsapi_set_arg_encoding(pinstance: Pgs_main_instance; ENCODING: Integer)
  : Integer; stdcall; external 'gsdll32.dll';

function JuntaPdfs(outPdf: ansistring; files: array of ansistring): Integer;
const
  GS_ARG_ENCODING_UTF8 = 1;

var
  code, code1, gsargc, i: Integer;
  gsargv: array of pansichar;
  minst: PGSAPIrevision;
begin
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := 'gs';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-dBATCH';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-dNOPAUSE';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-q';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-sDEVICE=pdfwrite';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := pansichar('-sOutputFile=' + outPdf);
  for i := Low(files) to High(files) do
  begin
    setlength(gsargv, length(gsargv) + 1);
    gsargv[high(gsargv)] := pansichar(files[i]);
  end;
  gsargc := length(gsargv);
  code := gsapi_new_instance(@minst, nil);
  if (code < 0) then
  begin
    result := 1;
    exit;
  end;
  code := gsapi_set_arg_encoding(minst, GS_ARG_ENCODING_UTF8);
  if (code = 0) then
    code := gsapi_init_with_args(minst, gsargc, @gsargv[0]);
  code1 := gsapi_exit(minst);
  if ((code = 0) or (code = e_Quit)) then
    code := code1;
  gsapi_delete_instance(minst);
  if ((code = 0) or (code = e_Quit)) then
  begin
    result := 0;
    exit;
  end;
  result := 1;
end;


Da forma de uso:
Código:
procedure TForm1.Button1Click(Sender: TObject);
begin
  JuntaPdfs('C:\system\OutPdfs\test.pdf', ['C:\system\InPdfs\file1.pdf',  'C:\system\InPdfs\file2.pdf']   );
end;

Lembre de ter a dll 'gsdll32.dll' no diretorio da aplicação ou em system32.
com alguns ajuste dá para fazer com que a lista de arquivo in seja um tstrings em vez de um array de string.
_________________
Tudo podemos quando tudo sabemos!
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Enviar E-mail MSN Messenger
natanbh1
Colaborador
Colaborador


Registrado: Terça-Feira, 15 de Março de 2011
Mensagens: 3093
Localização: Belo Horizonte - MG

MensagemEnviada: Seg Out 26, 2015 2:38 pm    Assunto: Responder com Citação

Funcionou perfeitamente strak2012.

Muito obrigado.
_________________
''A persistência é o caminho para o êxito.''
Charlie Chaplin
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Enviar E-mail
strak2012
Colaborador
Colaborador


Registrado: Segunda-Feira, 13 de Janeiro de 2014
Mensagens: 1518
Localização: Maceió - AL

MensagemEnviada: Seg Out 26, 2015 2:50 pm    Assunto: Responder com Citação

Ghostscript é uma ótima ferramenta com a mesma dá para extrair texto do pdf assim como converter-lo em outros formato como jpeg, png ou ps.

Segue um link com um exemplo básico em delphi 7 e algumas units muito uteis:
http://htmlbasic.esy.es/filehost/gsapi.rar

Dente algumas units que explora o potencial do Ghostscript estão:
gsapi, GhostScript, gsimage, View e GhostTools (esta sendo bem interessante)

Das funções da unit GhostTools temos:
PDF2PNG, PDF2JPEG, PDF2PS, PS2PDF, PDF2TXT, PDS2TXT

Fica ai a dica.

Abraços
_________________
Tudo podemos quando tudo sabemos!
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Enviar E-mail MSN Messenger
natanbh1
Colaborador
Colaborador


Registrado: Terça-Feira, 15 de Março de 2011
Mensagens: 3093
Localização: Belo Horizonte - MG

MensagemEnviada: Seg Out 26, 2015 3:09 pm    Assunto: Responder com Citação

Não conhecia esta ferramenta Ghostscript. Me surpreendeu bastante. Muito interessante.

Pesquisei bastante sobre ela antes e descobri que vários programas pagos e gratuitos do mercado utilizam ela para várias
funcionalidades com PDF, tais como conversão para diversos formatos, cortar, mesclar, etc.

Agradeço muito pela dica e pela ajuda no post.
_________________
''A persistência é o caminho para o êxito.''
Charlie Chaplin
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Enviar E-mail
natanbh1
Colaborador
Colaborador


Registrado: Terça-Feira, 15 de Março de 2011
Mensagens: 3093
Localização: Belo Horizonte - MG

MensagemEnviada: Sex Dez 04, 2015 9:12 am    Assunto: Responder com Citação

Implementei a função JuntaPDFs na minha aplicação e ficou muito bom, da maneira que eu precisava.

O meu problema acontece quando utilizo arquivos PDF's grandes ou um grande número de arquivos.

A aplicação "trava" enquanto está sendo utilizada a função (que utiliza a DLL GhostScript).

Tentei utilizar:

- Application.ProcessMessages
- Refresh
- Update
- ProgressBar

Mas nada adiantou, quando se está utilizando as funções da DLL tudo "trava".

Alguém sabe alguma maneira de resolver isso?
_________________
''A persistência é o caminho para o êxito.''
Charlie Chaplin
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Enviar E-mail
strak2012
Colaborador
Colaborador


Registrado: Segunda-Feira, 13 de Janeiro de 2014
Mensagens: 1518
Localização: Maceió - AL

MensagemEnviada: Sex Dez 04, 2015 10:12 am    Assunto: Responder com Citação

natanbh1 escreveu:
Implementei a função JuntaPDFs na minha aplicação e ficou muito bom, da maneira que eu precisava.

O meu problema acontece quando utilizo arquivos PDF's grandes ou um grande número de arquivos.

A aplicação "trava" enquanto está sendo utilizada a função (que utiliza a DLL GhostScript).

Tentei utilizar:

- Application.ProcessMessages
- Refresh
- Update
- ProgressBar

Mas nada adiantou, quando se está utilizando as funções da DLL tudo "trava".

Alguém sabe alguma maneira de resolver isso?


use uma thread e isso se resolve.
_________________
Tudo podemos quando tudo sabemos!
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Enviar E-mail MSN Messenger
natanbh1
Colaborador
Colaborador


Registrado: Terça-Feira, 15 de Março de 2011
Mensagens: 3093
Localização: Belo Horizonte - MG

MensagemEnviada: Sex Dez 04, 2015 10:32 am    Assunto: Responder com Citação

Obrigado por responder strak2012. Imaginei que esta seria a melhor maneira mesmo.

O problema é que não tenho nenhuma experiência com Threads.

Estou pesquisando bastante para tentar entender o funcionamento.

Creio que um progressbar com estilo Marquee funcionando em Thread já seria o suficiente para atender o que preciso.

Encontrei este exemplo de uso de Threads e Progressbar, mas não estou conseguindo implementar no meu projeto:

https://ricardogavira.wordpress.com/2011/07/27/usando-thread-no-delphi/

Poderia me ajudar a implementar ou me passar algum exemplo?

Desde já agradeço.
_________________
''A persistência é o caminho para o êxito.''
Charlie Chaplin
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Enviar E-mail
natanbh1
Colaborador
Colaborador


Registrado: Terça-Feira, 15 de Março de 2011
Mensagens: 3093
Localização: Belo Horizonte - MG

MensagemEnviada: Sex Dez 04, 2015 2:22 pm    Assunto: Responder com Citação

Consegui resolver através da criação de Threads.

Segue parte do código:

Código:
procedure TThreadProgresso.ChamarJuntaPDF;
begin
  Application.ProcessMessages();
  JuntaPdfs(frmPrincipal.SaveDialog1.FileName, Arquivos);
  ShellExecute(0, 'open', PChar(frmPrincipal.SaveDialog1.FileName), '', '', SW_SHOWMAXIMIZED);
  Application.ProcessMessages();
end;

procedure TThreadProgresso.Execute;
begin
  inherited;
  Priority := tpHigher;
  ChamarJuntaPDF;
  Self.Terminate;
end;


Para chamar:

Código:
var
  ThreadProgresso1: TThreadProgresso;
begin
  ThreadProgresso1 := TThreadProgresso.Create(true);
  ThreadProgresso1.Progresso := ProgressBar1;
  ThreadProgresso1.FreeOnTerminate := true;
  ThreadProgresso1.OnTerminate := frmPrincipal.OnTerminate;
  ThreadProgresso1.Resume;
  FormAtualiza.Close;
end;

_________________
''A persistência é o caminho para o êxito.''
Charlie Chaplin
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Enviar E-mail
strak2012
Colaborador
Colaborador


Registrado: Segunda-Feira, 13 de Janeiro de 2014
Mensagens: 1518
Localização: Maceió - AL

MensagemEnviada: Sex Dez 04, 2015 2:37 pm    Assunto: Responder com Citação

não pode testar pq não estou aqui com a dll mais seria algo assim


Código:
unit UThreadPDFs;

interface

uses
  Vcl.ComCtrls,
  System.Classes;

type

  TGSAPIrevision = packed record
    product: PChar;
    copyright: PChar;
    revision: longint;
    revisiondat: longint;
  end;

  PGSAPIrevision = ^TGSAPIrevision;
  Pgs_main_instance = Pointer;
  PPChar = array of PChar;

  TPDF = class(TThread)
  private
    { Private declarations }
    FoutPdf: ansistring;
    Ffiles: array of ansistring;
    FProgresso: TProgressBar;
  protected
    procedure Execute; override;
  public
    procedure setFileOut(outPdf: string);
    procedure setFilesIn(files: array of ansistring);
    procedure setProgresso(Progresso: TProgressBar);
  end;

const
  GS_ARG_ENCODING_LOCAL = 0;
  GS_ARG_ENCODING_UTF8 = 1;
  e_Quit = -990;

procedure JuntaPdfs(FProgresso: TProgressBar; FoutPdf: ansistring;
  Ffiles: array of ansistring);

implementation

{ funções e procedure da dll gsdll32.dll }
function gsapi_new_instance(pinstance: Pgs_main_instance;
  caller_handle: Pointer): Integer; stdcall; external 'gsdll32.dll';
function gsapi_init_with_args(pinstance: Pgs_main_instance; argc: Integer;
  argv: PPChar): Integer; stdcall; external 'gsdll32.dll';
function gsapi_exit(pinstance: Pgs_main_instance): Integer; stdcall;
  external 'gsdll32.dll';
procedure gsapi_delete_instance(pinstance: Pgs_main_instance); stdcall;
  external 'gsdll32.dll';
function gsapi_set_arg_encoding(pinstance: Pgs_main_instance; ENCODING: Integer)
  : Integer; stdcall; external 'gsdll32.dll';

{ TPDF }

procedure TPDF.setFileOut(outPdf: string);
begin
  FoutPdf := outPdf;
end;

procedure TPDF.setFilesIn(files: array of ansistring);
var
  i: Integer;
begin
  setlength(Ffiles, length(files));
  for i := Low(Ffiles) to High(Ffiles) do
    Ffiles[i] := files[i];
end;

procedure TPDF.setProgresso(Progresso: TProgressBar);
begin
  FProgresso := Progresso;
end;

procedure TPDF.Execute;
var
  code, code1, gsargc, i: Integer;
  gsargv: array of pansichar;
  minst: PGSAPIrevision;
begin
  if (FoutPdf<>'') and (length(Ffiles) > 0) then
  begin
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := 'gs';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-dBATCH';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-dNOPAUSE';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-q';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-sDEVICE=pdfwrite';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := pansichar('-sOutputFile=' + FoutPdf);

    for i := Low(Ffiles) to High(Ffiles) do
    begin
      setlength(gsargv, length(gsargv) + 1);
      gsargv[high(gsargv)] := pansichar(Ffiles[i]);
    end;
    gsargc := length(gsargv);
    code := gsapi_new_instance(@minst, nil);
    if (code < 0) then
    begin
      // result := 1;
      Terminate;
      exit;
    end;
    code := gsapi_set_arg_encoding(minst, GS_ARG_ENCODING_UTF8);
    // if (code = 0) then
    // code := gsapi_init_with_args(minst, gsargc, @gsargv[0]);

    if (code = 0) then
    begin
      if FProgresso <> nil then
        FProgresso.Max := gsargc;
      for i := 1 to gsargc do
      begin
        code := gsapi_init_with_args(minst, 1, @gsargv[i - 1]);
        if FProgresso <> nil then
          FProgresso.Position := i;
      end;
    end;

    code1 := gsapi_exit(minst);
    if ((code = 0) or (code = e_Quit)) then
      code := code1;
    gsapi_delete_instance(minst);
    if ((code = 0) or (code = e_Quit)) then
    begin
      // result := 0;
      Terminate;
      exit;
    end;
  end;
  // result := 1;
end;

procedure JuntaPdfs(FProgresso: TProgressBar; FoutPdf: ansistring;
  Ffiles: array of ansistring);
var
  myTread: TPDF;
begin
    myTread := TPDF.Create(true);
    myTread.FreeOnTerminate := true;
    myTread.Priority := tpNormal;
    myTread.setFileOut(FoutPdf);
    myTread.setFilesIn(Ffiles);
    myTread.setProgresso(FProgresso);
    myTread.Resume;
end;

end.


Da forma de uso
Código:
implementation

uses UThreadPDFs;
{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  s: array of ansistring;
  i: integer;
begin
  setlength(s, Memo1.Lines.Count);
  for i := 0 to Memo1.Lines.Count - 1 do
    s[i] := Memo1.Lines.Strings[i];

  JuntaPdfs(ProgressBar1, Edit1.Text, s);
end;



Depois testo com mais tempo a ideá deste é que ele vai mostrando no progressbar a incrementação do pdf OUT os IN
_________________
Tudo podemos quando tudo sabemos!
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Enviar E-mail MSN Messenger
natanbh1
Colaborador
Colaborador


Registrado: Terça-Feira, 15 de Março de 2011
Mensagens: 3093
Localização: Belo Horizonte - MG

MensagemEnviada: Sex Dez 04, 2015 3:16 pm    Assunto: Responder com Citação

Funcionou em partes strak2012.

O Progressbar funcionou perfeitamente, incrementando corretamente de acordo com o loop de arquivos.
Mas no final não está sendo criado o arquivo unificado.

Se precisar da DLL para testes, hospedei neste link:
http://www.4shared.com/file/jRP2Qzacce/gsdll32.html

Obrigado.
_________________
''A persistência é o caminho para o êxito.''
Charlie Chaplin
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Enviar E-mail
Mostrar os tópicos anteriores:   
Novo Tópico   Responder Mensagem    ActiveDelphi - Índice do Fórum -> Delphi Todos os horários são GMT - 3 Horas
Ir à página 1, 2  Próximo
Página 1 de 2

 
Ir para:  
Enviar Mensagens Novas: Proibido.
Responder Tópicos Proibido
Editar Mensagens: Proibido.
Excluir Mensagens: Proibido.
Votar em Enquetes: Proibido.


Powered by phpBB © 2001, 2005 phpBB Group
Traduzido por: Suporte phpBB