Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Como fazer download com nodeJs

Boa noite, gostaria de saber como faço para entregar um PDF gerado pelo node para quem fez a requisição em forma de download

const Consulta = require("../infra/consulta");
const xml = require("../infra/consultaXML");
const webdanfe = require("webdanfe");
const fs = require("fs");

module.exports = (app) => {

    app.get("/", (req, res) => res.marko(require("../views/index.marko")));

    app.post("/consulta", (req, res) => {

        if (req.body == "") {

            res.send("Este patrimonio não existe");
            return;
        }

        let patrimonio = req.body;

        Consulta.consulta(patrimonio.patrimonio).then(resposta => {

            if (resposta == "Este Patrimonio não existe") {

                res.send(`<td colspan="8">Este Patrimonio não existe</td>`);
                return;
            }

            let consulta = [];
            resposta.forEach(prop => {

                let objeto = {
                    loja: prop[0],
                    patrimonio: prop[1],
                    descricao: prop[2],
                    fornecedor: prop[3],
                    numeroNf: prop[4],
                    serieNf: prop[5],
                    data: prop[6],
                    cgo: prop[7],
                    chave: prop[8]
                }

                consulta.push(objeto)    
            });

            res.marko(require("../views/rotas/tabelas.marko"), {consulta: consulta});
        });
    });

    app.post("/consultaXML", (req, res) => {

        console.log(req);
        xml.consultaXML().then(result => {

            webdanfe.gerarDanfe(result, function(err, pdf) {
                if(err) {
                    throw err;
                }

                fs.writeFileSync(res, pdf, {
                    encoding: 'binary'
                });
            });   
        })
    })
}

Aqui estou usando o express, e esta funcionando porem gostaria de mandar o PDF para quem requisitou no caso a requisição vem daqui

$(document).on("click", ".buscar-nf", function() {

    $.post("/consultaXML", function(resultado) {

        window.print(resultado);
    })
})

e aqui gostaria de abrir o PDF direto para a impressão ou fazer o download dele no browser alguém consegue me ajudar?

2 respostas
solução!

Olá Felix, tudo bem com você?

Eu criei um exemplo da maneira como podemos fazer isso para que você possa ter uma ideia de como aplicar em seu projeto, a lógica será a mesma apenas adaptar para o jquery

Parte 1: Servidor

Irei criar um servidor com express bem simples para servir apenas o arquivo pdf, ok?

const path = require('path');
const express = require('express');
const app = express();
const cors = require('cors');

app.use(cors());

app.use(express.static(path.resolve(__dirname, "public")));

app.get("/", (req, res) => {
    res.sendFile( path.resolve(__dirname, "CalcP1.pdf"))
});

app.listen(3000, () => console.log(`[ONLINE] Servidor rodando na porta 3000`));
`

Bem, a lógica é simples, ao dar um get em "/" irei devolver o arquivo chamado calcp1.pdf que está na mesma pasta do servidor :)

Estou utilizando o express.static apenas porque criei uma página html para fazer a requisição, dentro de public, dessa maneira consigo acesssar: localhost:3000/page.html

Pate 2: HTML

Bem, aqui acredito que está o seu grande problema, para conseguir o que queremos é necessário criar um Blobque normalmente utilizamos para obter arquivos:

<body>
    <button id="pdf"> Gerar PDF >/button>

    <script>
        function mostrarPDF( blob) {
            const arquivo = new Blob([
                    [ blob ],
                    { type: "application/pdf"}
            )
            const link = window.URL.createObjectURL(arquivo);
            window.open(link) 
        }

        const button = document.getElementById("pdf");
        button.addEventListener("click", () => {
            fetch("http://localhost:3000")
                .then( res => res.blob() )
                .then(mostrarPDF)
        }
    </script>    

</body>

Aqui é bem simples, estou utilizando o fetch para fazer uma requisição para o servidor, estou obtendo a resposta e dizendo que quero ela no formato blob e passando para a função mostrarPDF, ela cria esse objeto com os dados passados e diz que é do tipo pdf e eu crio um link para ser aberto com o conteúdo do pdf :)

Ali depois de window.open(link) poderiamos adicionar o window.print(), mas na tela de arquivo que irá abrir acredito que não é necessário pois tem todas as informações e opções para o usuário :)

Abraços e Bons Estudos!

Boa tarde.

No meu caso fiz assim no lado do servidor:

app.get("/consultaXML/:id", (req, res) => {

        const chave = req.params.id;

        xml.consultaXML(chave).then(result => {

            webdanfe.gerarDanfe(result, function(err, pdf) {
                if(err) {
                    throw err;
                }

                res.type("aplication/pdf");
                res.end(pdf, "binary");
            });   
        })
    })

No lado do cliente tirei o script java script e fiz o seguinte:

<for|dado| of=data.consulta>
    <tr class="linhas">
        <td class="status"><div id="status"></div></td>
        <td>${dado.loja}</td>
        <td>${dado.patrimonio}</td>
        <td>${dado.descricao}</td>
        <td>${dado.fornecedor}</td>
        <td>${dado.numeroNf}</td>
        <td class="data">${dado.data}</td>
        <td>${dado.chave}</td>
        <td><button class="buscar-nf"><a href=`/consultaXML/NFe${dado.chave}` download=`${dado.fornecedor} - NF ${dado.numeroNf}.pdf`>Download</a></button></td>
    </tr>
</for>

Não cheguei a testar seu código Geovani e não havia compartilhada minha resolução pois não tive tempo, mas fica ai as duas ideias então para mais alguém que tenha o mesmo problema

Obrigado!!!