0

I am trying to prompt a download of a PDF generated on the server using Node.js. Currently I can save it to the server but not force a download.

I am using npm html-pdf and currently it is saving to the server with this code.

  pdf.create(htmlbody).toStream(function(err, stream){
    console.log(stream);

    if (err) return next(err);

    stream.pipe(fs.createWriteStream('./foo.pdf'));

    res.status(200);
    res.send('Success');
  });

How can I make it force a download?

I tried setting headers like

res.setHeader('content-type', 'application/pdf');
res.setHeader("Content-Disposition", "attachment; filename="+pdfName+";");

I am testing on localhost but I don't presume this to be the issue.

Allreadyhome
  • 1,252
  • 2
  • 25
  • 46
  • There is a huge discussion for the mime type regarding to pdf you might be interessted in this question http://stackoverflow.com/questions/312230/proper-mime-media-type-for-pdf-files - Proper Mime Media Type for PDF. Q: **Is this with all browsers or only specific ones**? – silverfighter Dec 08 '15 at 12:51
  • Yeah seen that topic – Allreadyhome Dec 08 '15 at 12:56

1 Answers1

1

You don't have to save it to the server (unless that is a business logic requirement). What you can do is simply this:

pdf.create(htmlbody).toStream(function(err, stream){

  if (err) return next(err);

  res.setHeader('Content-Type', 'application/pdf');
  res.setHeader('Content-Disposition', 'attachment; filename='+pdfName+';');

  stream.pipe(res);
});

Basically, all you need to do is set the appropriate headers and then pipe the stream you get from html-pdf to your res stream.

If you however need to save the PDF on the server first, then you'll have to write it to the file system and once it's done, read it back and send it over the response stream again.


Edit: Here's the code snippet with a full working example (running on Node v4.0.0).

var http = require('http');
var pdf = require('html-pdf');

const PORT = 8765;

var server = http.createServer((req, res) => {

  var html = '<html><head><title>PDF Test</title></head><body><h1>Welcome</h1><p>This is a test to see if we can get <b>PDF generation</b> to work on the server side.</p><p>PDF files can be very tricky to do on the server so this will take a bit of <u>hit and trail</u> before we can be confident it works fine.</p></body></html>';

  pdf.create(html).toStream((err, stream) => {

    if (err) {

      console.error(err);
      res.status(500);
      res.end(JSON.stringify(err));

      return;
    }

    res.setHeader('Content-Type', 'application/pdf');
    res.setHeader('Content-Disposition', 'attachment; filename=test-file.pdf;');

    stream.pipe(res);
  });
});

server.listen(PORT, () => {
  console.log('Server listening on Port: %s', PORT);
});

Save the above as something like pdf.js and run in with node (node pdf.js) and open http://localhost:8765/. This should trigger a download in your browser.

Uzair Sajid
  • 2,135
  • 2
  • 21
  • 28