By Sails.js Tech Brasil


Relatório em Portable Document Format (PDF)

Sails não possui um recurso nativo para geração de arquivos PDF, e nem precisa. Existem dezenas de biliotecas JavaScript que fazem isso!.

Escolhemos a biblioteca PDFKit pela sua flexibilidade, compatibilidade e segurança, mas você pode escolher qualquer outra que seja compatível com Node.js

Se esta é sua primeira vez aqui, recomendamos a leitura dos conteúdos abaixo antes de continuar:


Passo a passo para geração de PDF
  1. Instale a biblioteca PDFKit com o comando npm i pdfkit --save
  2. Na console do terminal e no diretório raíz de seu protótipo Sails.js, digite sails generate controller nome-do-controller
  3. Você deve ver na console algo do tipo
     info: Created a new controller ("nome-do-controle") at api/controllers/NomeDoControleController.js!
  4. Localiza e edite o arquivo config/routes.js e adicione a seguinte linha: 'GET /relatorio':'NomeDoControleController.gerar',
  5. Localize e abra para edição o arquivo que você criou (provavelmente no diretório api/controllers/NomeDoControleController.js). Ele provavelmente conterá algo do tipo:
    
                        /**
                        * NomeDoControleController
                        *
                        * @description :: Server-side actions for handling incoming requests.
                        * @help        :: See https://sailsjs.com/docs/concepts/actions
                        *             
                        */                   
                       
                       
                       module.exports = {
    
                       }
    
                    
  6. Copie o código abaixo e cole no seu arquivo ...Controller recém criado:
            
     /**
     * Exemplo de PDF Report Controller
     *
     * @description :: Server-side actions for handling incoming requests.
     * @help        :: See https://sailsjs.com/docs/concepts/actions
     *              :: See https://pdfkit.org/docs/getting_started.html
     */
    
    // carrega em memoria o PDFkit 
    const PDFDocument = require('pdfkit')
    
    module.exports = {    
    
        // Funcao evocada pela rota 'GET /relatorio':'NomeDoControleController.gerar',
        // definida no arquivo config/routes.js
        gerar: function (req, res) {
    
            // Cria um documento PDF mas mantem em memoria (bufferedPages = true)
            // A omissao do atributo `size` atribui o formato `letter` ao documento
            const doc = new PDFDocument({ size: 'A4', bufferPages: true })
    
            const formato =  {
                margins: {
                    top: 50,
                    bottom: 50,
                    left: 72,
                    right: 72                
                },
                size: 'A4',
                font: 'Courier'
            }
    
            // define as dimensoes especificas desta pagina inicial
            doc.switchToPage(0)
            doc
                .fontSize(30)
                .text('Titulo de seu documento', 100, 200)
                .fontSize(25)
                .text('Subtitulo do documento', 100, 230)
                .fontSize(12)
                .text('Resumo inicial do que se deve comunicar com este relatorio', 110, 260)
            
            // aplica as dimensoes gerais definidas no objeto 'formato'   
            // adiciona uma pagina seguinte com texto longo. Observe que o PDFKit separa as linhas
            doc.addPage(formato)
                .fontSize(10).text('conteudo textual e relevante que deve ser apresentado no relatorio em letras menores e com conteudo longo. Observe a mudança de linha', 100, 100)
    
            // Desenha um triangulo numa nova pagina
            doc.addPage(formato)
                .save()
                .moveTo(100, 150)
                .lineTo(100, 250)
                .lineTo(200, 250)
                .fill('#FF3300');        
    
            // Adiciona um texto de outra cor e um link, sem definicao de margem
            doc
                .addPage()
                .fillColor('blue')
                .text('Aqui nós temos um link!', 100, 100)
                .underline(100, 100, 160, 27, { color: '#0000FF' })
                .link(100, 100, 160, 27, 'http://google.com/');
    
            // captura um determinado conjunto de paginas. A omissao significa todos
            const range = doc.bufferedPageRange() // => { start: 0, count: 3 }
    
            // navega pagina a pagina para preencher no rodape o numero de paginas totais
            for (i = range.start, end = range.start + range.count, range.start <= end; i < end; i++) {
                doc.switchToPage(i)
                doc.text(`Pagina ${i + 1} de ${range.count}`, 100, 700)
            }
    
            // finaliza a montagem das paginas
            doc.flushPages()
            // transforma em streaming de saida e envia ao requisitante
            doc.pipe(res)
            // finaliza o processamento e limpa a memoria
            doc.end()
        }
    
    }
    
    
                
  7. Escolha uma de suas páginas EJS (ou até mesmo HTML) e adicione <a href='/relatorio'>Relatorio</a>
  8. Escolha uma de suas páginas EJS (ou até mesmo HTML) e adicione <iframe src="/relatorio" frameborder="1"></iframe>
  9. Execute seu protótipo com o comando sails lift, faça login e visualize seu pdf (ou clique no link [Relatorio])
  10. O comportamento esperado é que o navegador apresente um PDF com o conteúdo inserido acima.
A rota 'GET /relatorio', criada no nosso exemplo, responde a política de segurança definida no arquivo 'config/policies.js'. Para eliminar a necessidade de autenticação prévia (login e senha) é necessário explicitar uma política para o Controller!
                //Exemplo de politica "sem necessidade de autenticação"
                //que deve estar contida no arquivo config/policies.js

                NomeDoControleController: {
                    'gerar': true
                },

            

Este é um exemplo simplificado para demonstrar como gerar conteúdo PDF dentro de uma aplicação Sails. Visite o site PDFKit para conhecer outras opções de construção de conteúdo para seu arquivo PDF.


Para saber mais:
Início