Juntando vários arquivos PDF usando AdvPL com GhostScript

No artigo de hoje, vamos mostrar como juntar arquivos PDF em um só usando AdvPL com GhostScript.

O GhostScript é um projeto conhecido no mundo da programação, que tem uma parte Open Source. Com ele nós conseguimos manipular arquivos PDF.

Um dos recursos interessantes, é o fato de conseguir juntar arquivos. Supondo então, que você tenha a necessidade de juntar 2 ou mais relatórios em AdvPL, nós conseguimos através de uma integração com o GhostScript.

Então antes de mais nada, baixe o GhostScript disponível nesse link – https://www.ghostscript.com/releases/gsdnld.html

Depois de fazer a instalação, baixe o código fonte abaixo, e se atente ao caminho na variável cPastaGS, que é ela que define a pasta onde tem os executáveis do GhostScript.

Dito isso, como é o funcionamento da rotina? Basicamente ela recebe um Array, com todos os arquivos em PDF na estação, e recebe a parametrização de onde que irá gravar o PDF que ficará tudo junto, então ficaria +- assim:

//Arquivos originais que ficarão juntos
aArqOrig := {}
aAdd(aArqOrig, "C:\spool\tst\arquivo1.pdf")
aAdd(aArqOrig, "C:\spool\tst\arquivo2.pdf")
aAdd(aArqOrig, "C:\spool\tst\arquivo3.pdf")

//Define a pasta onde vai gerar o pdf com tudo junto, o nome do pdf e se irá abrir o pdf logo após o processo
cPastaDest := "C:\spool\tst\"
cArquiDest := "tudo_junto.pdf"
lAbrDepois := .F.

//Aciona a função para juntar os PDFs
u_zJuntaPDF(aArqOrig, cPastaDest, cArquiDest, lAbrDepois)

E abaixo segue a função completa do zJuntaPDF que aciona o GhostScript:

//Bibliotecas
#Include "TOTVS.ch"

/*/{Protheus.doc} User Function zJuntaPDF
Função para juntar PDFs via Ghost Script
@type  Function
@author Atilio
@since 24/08/2023
@version version
@param aArqOrig, Array, Array com todos os arquivos pdfs a serem juntados (mandar com o caminho absoluto)
@param cPastaNovo, Caractere, Caminho da pasta onde vai ser gerado o arquivo novo
@param cArquiNovo, Caractere, Nome do arquivo novo com o conteúdo dos pdfs juntos
@param lAbrirPDF, Lógico, Define se após juntar irá abrir o arquivo novo
@return aRetorno, Array, Posição 1 é se deu tudo certo na geração do arquivo e Posição 2 é o caminho absoluto do arquivo
@obs É necessário instalar o Ghost Script na máquina
    Link para download: https://www.ghostscript.com/releases/gsdnld.html
@example
    //Arquivos originais que ficarão juntos
	aArqOrig := {}
	aAdd(aArqOrig, "C:\spool\tst\arquivo1.pdf")
	aAdd(aArqOrig, "C:\spool\tst\arquivo2.pdf")
	aAdd(aArqOrig, "C:\spool\tst\arquivo3.pdf")

	//Define a pasta onde vai gerar o pdf com tudo junto, o nome do pdf e se irá abrir o pdf logo após o processo
	cPastaDest := "C:\spool\tst\"
	cArquiDest := "tudo_junto.pdf"
	lAbrDepois := .F.

	//Aciona a função para juntar os PDFs
	u_zJuntaPDF(aArqOrig, cPastaDest, cArquiDest, lAbrDepois)
/*/

User Function zJuntaPDF(aArqOrig, cPastaNovo, cArquiNovo, lAbrirPDF)
    Local aArea        := FWGetArea()
    Local lDeuCerto    := .F.
    Local cComando     := ""
    Local aRetorno     := {}
    Local cPastaGS     := SuperGetMV("MV_X_GHOST", .F., "C:\Program Files\gs\gs9.55.0\bin\")
    Local nAtual       := 0
    Default aArqOrig   := {}
    Default cPastaNovo := "C:\spool\"
    Default cArquiNovo := "arquivo_junto.pdf"
    Default lAbrirPDF  := .F.

    //Retira os espaços vazios
    cPastaNovo  := Alltrim(cPastaNovo)
    cPastaGS   := Alltrim(cPastaGS)

    //Adiciona \ caso esteja faltando
    cPastaNovo := cPastaNovo + Iif(Right(cPastaNovo, 1) != "\", "\", "")
    cPastaGS  := cPastaGS  + Iif(Right(cPastaGS, 1)  != "\", "\", "")

    //Verifica se as pastas existem e se tem arquivos
    If ! Empty(cPastaGS) .And. ExistDir(cPastaGS) .And. ! Empty(cPastaNovo) .And. ExistDir(cPastaNovo) .And. Len(aArqOrig) > 0

        //Monta o comando para converter o PDF
        cComando := ' -dBATCH -dNOPAUSE -q '
        cComando += ' -sDEVICE=pdfwrite '
        cComando += ' -dPDFSETTINGS=/prepress '
        cComando += ' -sOutputFile="' + cPastaNovo + cArquiNovo + '" '

        //Percorre os arquivos originais
        For nAtual := 1 To Len(aArqOrig)

            //Se o arquivo existir
            If File(aArqOrig[nAtual])
                cComando += ' "' + aArqOrig[nAtual] + '"'
            EndIf
        Next

        //Executa o GhostScript
        cComando := '"' + cPastaGS + 'gswin64.exe"' + cComando
        WaitRun(cComando, 1)

        //Se o arquivo existe, deu certo a conversão
        If File(cPastaNovo + cArquiNovo)
            lDeuCerto := .T.

            //Se for para abrir o PDF
            If lAbrirPDF
                ShellExecute("OPEN", cArquiNovo, "", cPastaNovo, 1)
            EndIf
        EndIf
    EndIf

    //Define o retorno
    aRetorno := {lDeuCerto, cPastaNovo + cArquiNovo}

    FWRestArea(aArea)
Return aRetorno

Bom pessoal, por hoje é só.
Abraços e até a próxima.

Dan (Daniel Atilio)
Cristão de ramificação protestante. Especialista em Engenharia de Software pela FIB, graduado em Banco de Dados pela FATEC Bauru e técnico em informática pelo CTI da Unesp. Entusiasta de soluções Open Source e blogueiro nas horas vagas. Autor e mantenedor do portal Terminal de Informação.

Deixe uma resposta

Terminal de Informação