uglycode
uglycode

Reputation: 3082

express.js - create a new pdf and force the download, without saving it on server

I'm using express.js with pdfkit to generate a pdf and force a download to user. To this end I used the res.download function, that belongs to express.js. I could also pipe the pdf to res, but then the download wouldn't start.

Ok, so what's my question: is it possible to somehow create the pdf on server and store it "in memory" or something like that? Currently I have to define a specific location where the pdf is created and then read from that location and serve it to the user. Basically, I'd like to "skip" that save-to-disk and read-from-disk, yet still force the download for the user.

Perhaps I'm not understanding some concepts here, so any kind of explanation is greatly appreciated!

Here's the code:

router.get('/pdf/:id', function(req, res) {
    Order._getById(req.params.id).
    then(function(order) {
        if (order !== null) {
            var doc = new PDFDocument();
            var result = order.toJSON();

            var products = result.products;
            var user = result.user;
            var comments = result.comments;

            doc.registerFont('arial', path.join(__dirname, '../fonts', 'arial' , 'arial.ttf'));         

            for (var i in products) {
                var product = products[i];
                doc.font('arial').text(product.name);
                doc.image(path.join(__dirname,'../uploads','thumb', product.picture), {scale: 1.0});
                doc.font('arial').text(product.price + ' €');
            }

            var r = doc.pipe(fs.createWriteStream(path.join(__dirname, '../uploads', 'out.pdf')));
            doc.end();

            r.on('finish', function(){
                //the response is a "forced" download of a file I had to save on the disk
                res.download(path.join(__dirname, '../uploads', 'out.pdf'));
            });

        } else {
            res.json(false);
        }
    });
});

Again, if I don't save the file and just do this: doc.pipe(res); the pdf is opened in a new tab, and not forced to download.

Upvotes: 4

Views: 4606

Answers (1)

uglycode
uglycode

Reputation: 3082

I think this is the answer... I can just pipe the result to client, but headers need to be set, i.e.:

        res.writeHead(200, {
            'Content-Type': 'application/pdf',
            'Access-Control-Allow-Origin': '*',
            'Content-Disposition': 'attachment; filename=out.pdf'
        });

Upvotes: 5

Related Questions