I have a PDF export that takes a while to create the PDF. I want the user to be able to click the export link and be presented with a download dialog right away. This way they can start the download and just wait for it to complete. Instead of clicking the link, wait for the generation and then wait for the download again.
Here's a very simple example in PHP:
<?php
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename=test.pdf');
flush();
// time consuming PDF creation happens here
sleep(15);
echo 'pdf contents would be here';
The idea is to send the appropriate headers, flush() them to the browser, slowly create the PDF and finally send it to the browser.
This works perfectly in chrome. The Download Dialog pops up immeadiately and the sleep is part of the download waiting time.
In Firefox and InternetExplorer this does not work. Those browsers wait the full 15 seconds before showing the download dialog.
Any idea how to make the download dialog pop up immeadiately would be greatly appreciated.
Some browsers wait for the actual content before showing the download dialog. So, the solution is simple: send some PDF content before creating the PDF content.
Wait a minute. How do you send something before you have it? That sounds like it would require a time machine, right? Don't worry, there is a way to get around it.
PDF content starts with %PDF
, thus you simply have to send %PDF
before calling flush().
After the PDF creation completes, remove the first 4 bytes of the newly created PDF content before echoing it.
<?php
// disable output buffering
while (@ob_end_clean());
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename=test.pdf');
// send some content to trigger the download dialog
echo '%PDF';
flush();
// time consuming PDF creation happens here
sleep(15);
$pdfContent = '%PDF-pdf contents would be here';
echo substr($pdfContent, 4);
This solution works in any language because it doesn't rely on any PHP-only feature.
If you want to do the absolute minimum, you can also send 1 byte %
and then remove just the first byte before echoing.
Same result.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With