Exibir mensagem anterior :: Exibir próxima mensagem |
Autor |
Mensagem |
natanbh1 Colaborador

Registrado: Terça-Feira, 15 de Março de 2011 Mensagens: 3093 Localização: Belo Horizonte - MG
|
Enviada: Sex Out 23, 2015 11:08 am Assunto: Unir vários PDF's em apenas um documento [Resolvido] |
|
|
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 |
|
 |
marcieldeg Colaborador


Registrado: Terça-Feira, 5 de Abril de 2011 Mensagens: 1054 Localização: Vitória - ES
|
|
Voltar ao Topo |
|
 |
natanbh1 Colaborador

Registrado: Terça-Feira, 15 de Março de 2011 Mensagens: 3093 Localização: Belo Horizonte - MG
|
Enviada: Sex Out 23, 2015 2:02 pm Assunto: |
|
|
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 |
|
 |
natanbh1 Colaborador

Registrado: Terça-Feira, 15 de Março de 2011 Mensagens: 3093 Localização: Belo Horizonte - MG
|
Enviada: Sex Out 23, 2015 4:16 pm Assunto: |
|
|
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 |
|
 |
natanbh1 Colaborador

Registrado: Terça-Feira, 15 de Março de 2011 Mensagens: 3093 Localização: Belo Horizonte - MG
|
Enviada: Seg Out 26, 2015 8:46 am Assunto: |
|
|
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 |
|
 |
strak2012 Colaborador


Registrado: Segunda-Feira, 13 de Janeiro de 2014 Mensagens: 1518 Localização: Maceió - AL
|
Enviada: Seg Out 26, 2015 12:22 pm Assunto: |
|
|
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 |
|
 |
natanbh1 Colaborador

Registrado: Terça-Feira, 15 de Março de 2011 Mensagens: 3093 Localização: Belo Horizonte - MG
|
Enviada: Seg Out 26, 2015 2:38 pm Assunto: |
|
|
Funcionou perfeitamente strak2012.
Muito obrigado. _________________ ''A persistência é o caminho para o êxito.''
Charlie Chaplin |
|
Voltar ao Topo |
|
 |
strak2012 Colaborador


Registrado: Segunda-Feira, 13 de Janeiro de 2014 Mensagens: 1518 Localização: Maceió - AL
|
Enviada: Seg Out 26, 2015 2:50 pm Assunto: |
|
|
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 |
|
 |
natanbh1 Colaborador

Registrado: Terça-Feira, 15 de Março de 2011 Mensagens: 3093 Localização: Belo Horizonte - MG
|
Enviada: Seg Out 26, 2015 3:09 pm Assunto: |
|
|
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 |
|
 |
natanbh1 Colaborador

Registrado: Terça-Feira, 15 de Março de 2011 Mensagens: 3093 Localização: Belo Horizonte - MG
|
Enviada: Sex Dez 04, 2015 9:12 am Assunto: |
|
|
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 |
|
 |
strak2012 Colaborador


Registrado: Segunda-Feira, 13 de Janeiro de 2014 Mensagens: 1518 Localização: Maceió - AL
|
Enviada: Sex Dez 04, 2015 10:12 am Assunto: |
|
|
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 |
|
 |
natanbh1 Colaborador

Registrado: Terça-Feira, 15 de Março de 2011 Mensagens: 3093 Localização: Belo Horizonte - MG
|
Enviada: Sex Dez 04, 2015 10:32 am Assunto: |
|
|
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 |
|
 |
natanbh1 Colaborador

Registrado: Terça-Feira, 15 de Março de 2011 Mensagens: 3093 Localização: Belo Horizonte - MG
|
Enviada: Sex Dez 04, 2015 2:22 pm Assunto: |
|
|
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 |
|
 |
strak2012 Colaborador


Registrado: Segunda-Feira, 13 de Janeiro de 2014 Mensagens: 1518 Localização: Maceió - AL
|
Enviada: Sex Dez 04, 2015 2:37 pm Assunto: |
|
|
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 |
|
 |
natanbh1 Colaborador

Registrado: Terça-Feira, 15 de Março de 2011 Mensagens: 3093 Localização: Belo Horizonte - MG
|
Enviada: Sex Dez 04, 2015 3:16 pm Assunto: |
|
|
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 |
|
 |
|