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.

2
  • There is a huge discussion for the mime type regarding to pdf you might be interessted in this question stackoverflow.com/questions/312230/… - Proper Mime Media Type for PDF. Q: Is this with all browsers or only specific ones? Commented Dec 8, 2015 at 12:51
  • Yeah seen that topic Commented Dec 8, 2015 at 12:56

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

4 Comments

Hi Uzair. Thanks for the response. I did try this but it doesn't prompt a download instead returns the pdf as a body element (lots of code). I presume maybe the header files are wrong?
Does it have anything to do with being on localhost?
@Allreadyhome I added another example. This shouldn't be a problem on localhost as well.
Looks like its an angualr issue after running a few checks. Thanks for the help.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.