wkhtmltopdf: download a PDF to the user's HD - php

how to download automaticaly (to the user's HD) a pdf generated using wkhtmltopdf or snappy? You know.. a user click a link ("Download this page as PDF") and download the pdf to his/her HD.
Regards
Javi

PHP: there are better ways of getting wkhtmltopdf working with PHP, however, I like to be able to print out what my command line is so that I can debug the resulting page that bit more easily. It is not just about code, but about having margins and other page details correct. Here the wkhtmltopdf is a binary in the web root, margins are set to zero, the background is turned off:
$do_it=$_SERVER["DOCUMENT_ROOT"]."/wkhtmltopdf --dpi 600 -B 0 -L 0 -R 0 -T 0 --no-background http://".$_SERVER['SERVER_NAME']."/".$filename." ".$_SERVER["DOCUMENT_ROOT"]."/".$pdf_url;
//var_dump($do_it); // uncomment to see your wkhtmltopdf parameters...
$whatever=passthru($do_it);
header('Content-disposition: attachment; filename='.$pdf_url);
header('Content-type: application/pdf');
readfile($pdf_url);
I don't think much comes back when running passthru when it comes to error messages, however, it does run whatever you send it.
As for header, it is important to set the content type to PDF or else the browser will not know what to do with it.
The Snappy website actually also has a ready made example just for this.
$snappy = new Pdf('/usr/local/bin/wkhtmltopdf');
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="file.pdf"');
echo $snappy->getOutput('http://www.github.com');

Here's how I do it in RoR
filename = "MyNew.pdf"
fullpath = "#{RAILS_ROOT}/tmp/charts/#{filename}"
# system issues a shell command
system "/usr/local/bin/wkhtmltopdf \"http://localhost/page/to/pdf?download=t\" #{fullpath}"
send_data(File.read(fullpath), :type => 'application/pdf', :filename => filename, :disposition => "attachment;filename=\"#{filename}\"")

Related

Download the YouTube video file directly to user's computer through browser

<?php
$youtubeUrl = "https://www.youtube.com/watch?v=Ko2JcxecV2E";
$content = json_encode ($file = shell_exec("youtube-dl.exe $youtubeUrl "));
$input_string =$content;
$regex_pattern = "/Destination:(.*.mp4)/";
$boolean = preg_match($regex_pattern, $input_string, $matches_out);
$extracted_string=$matches_out[0];
$file =explode(': ',$extracted_string,2)[1];
// Quick check to verify that the file exists
if( !file_exists($file) ) die("File not found");
// Force the download
header("Content-Disposition: attachment; filename=\"$file\"" );
header("Content-Length: " . filesize($file));
header("Content-Type: application/octet-stream;");
readfile($file);
?>
When I run this file the respective YouTube video is first downloaded to the localhost server folder where this PHP file is, using youtube-dl.exe and then it is pushed from that folder to browser download (forced download).
How to directly start the download to user's browser?
Also the file is running fine on localhost but not on remote server.
First, you need to use a version of youtube-dl for a platform of your webserver. The youtube-dl.exe is a build for Windows, while most webhostings use Linux.
Then use the passthru PHP function to run the youtube-dl with the -o - command-line parameter. The parameters makes youtube-dl output the downloaded video to its standard output, while the passthru passes the standard output to a browser.
You also need to output the headers before the the passthru. Note that you cannot know the download size in this case.
header("Content-Disposition: attachment; filename=\"...\"" );
header("Content-Type: application/octet-stream");
passthru("youtube-dl -o - $youtubeUrl");
If you need a video metadata (like a filename), you can run the youtube-dl first with the -j command-line parameter to get the JSON data without downloading the video.
Also you need 1) Python interpreter on the web server 2) to be able to use the passthru function 3) connectivity to YouTube from the PHP scripts. All these are commonly restricted on webhostings.
The trouble is probably within: shell_exec("youtube-dl.exe $youtubeUrl ")
Firstly, some hosts disable shell_exec for security reasons.
Secondly, youtube-dl.exe looks like it is probably a windows script, where as your remote server is probably Linux based.

PHP: wkhtmltopdf snappy (wrapper) fails

i have a problem using wkhtmltopdf with snappy.
I has installed wkhtmltopdf with homebrew on mac osx.
I use this code to display PDF in Browser:
<?php
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="file.pdf"');
require_once('snappy/autoload.php');
use Knp\Snappy\Pdf;
$snappy = new Pdf('/usr/local/bin/wkhtmltopdf');
echo $snappy->getOutput('http://www.github.com');
?>
Instead of displaying the PDF in the browser, the script opens the terminal. After i click on the terminal it starts downloading the file.pdf. The file.pdf shows the correct github page.
What i am doing wrong?
And whats the best solution to manage wkhtmltopdf's binary path that the script is working on several systems (debian, windows, ..).
EDIT:
Oh sorry.. i changed attachment to inline and the browser displays the PDF.
But i must click on the terminal first..

PDFTK outputs a corrupt pdf to the browser

I am using PHP to fill a PDF form, which I would like to output to the browser. I am using the function found here: http://koivi.com/fill-pdf-form-fields to create an xfdf file. I then use the following code to fill the form and output the resulting file to the browser:
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="filename.pdf"');
passthru("/usr/local/bin/pdftk forms/pdf_form.pdf fill_form filename.xfdf output - ");
When I open the PDF created from the browser, I get an error from adobe pdf reader that says "Adobe Reader could not open 'filename.pdf' because it is either not a supported file type or because the file has been damaged (for example, it was sent as an email attachment and wasn't correctly decoded)." Opening the same PDF in another reader does not give the error, but my users will be using acrobat.
By way of contrast, if I change my code to the following:
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="filename.pdf"');
passthru("/usr/local/bin/pdftk forms/pdf_form.pdf fill_form filename.xfdf output filename.pdf ");
I can open, read and edit the resulting PDF from the tmp folder. It seems that the 'output - ' option is somehow corrupting the PDF.
My question is this: Am I doing something wrong? Is there some piece of code that I am missing or a better way to accomplish this?
PHP version: 5.3.19; Server OS: Mac OS 10.7.5; Client OS: Mac OS
10.7.5; Browsers tested: Chrome, FireFox; Readers tested: Adobe PDF Reader, Preview; PDFTK version: 1.4.5
Use <?php ... for instance without final ?> so you are sure no final whitespace, especially newline is written after the PDF output.

Why downloaded file is not downloaded instead it is shown in browser?

I redirect the visitors in my website from page A to page B. In page B I expect users to get the downloaded PDF file (to be downloaded when page B is loading).
I have taken the code from another article (see a previous question answered here) and my code of page B is the following:
<?php
header('Content-Disposition: attachment; filename=nature.pdf');
header('Content-type: application/pdf');
$fn=fopen("/wp-content/nature.pdf","r");
fpassthru($fn);
?>
The output is not by opening a download dialog box, instead some unreadable characters are displayed in browser such as the following (I have just picked up a small sample below):
%PDF-1.4 %���� 3 0 obj <>stream x���MK1�o�+�$zIg&�� V=T�=Xo����K��i+#V�yx3��඀(BX�pW`
Server: OS Linux; PHP version: 5.2.17
The visitor -> Browser: Firefox; OS: Windows 2000
Is it possible to fail due to the old OS on client side? If not, does anybody know a solution how to force the download? Any help would be highly appreciated.
Thanks.
Try it with the Content-Length header:
ob_clean(); ob_start();
header('Content-Disposition: attachment; filename=nature.pdf');
header('Content-type: application/pdf');
header ("Content-Length: ".filesize("/wp-content/nature.pdf"));
readfile("/wp-content/nature.pdf");
exit;
There was a quirk in the really old browsers when Content-disposition was first being introduced, some of the really old browsers wouldn't show the "Save As" dialogue unless it couldn't recognize the type of file you were trying to open. Try setting the Content-type to nothing (or something unrecognizable), and see if that'll force the older browser to pop the save-as dialogue.
header('Content-type: ');
If that works, then I'd suggest adding in a line of PHP to detect whether or not they're on an old browser before running that line, as modern browsers will use that header to determine what program the file should be opened with.

pdf generator from html in php using Wkhtmltopdf

On my windows with xamp local server I follow pdf generator from html
step 1 & 2 (wkhtmltopdf http://www.test.com test.pdf) goes fine but step 3
3. In php you should execute the tool using shell_exec:
shell_exec("/usr/local/bin/wkhtmltopdf-i386 http://test.com test.pdf");
//for Linux 32 bits operating system
//for Linux 64 bits operating system use wkhtmltopdf-amd64
//for windows just put the path of the exe file.
$allfile = file_get_contents("test.pdf");
header('Content-Type: application/pdf');
header('Content-Length: '.strlen($allfile));
header('Content-Disposition: inline; filename="test.pdf"');
header('Cache-Control: private, max-age=0, must-revalidate');
header('Pragma: public');
ini_set('zlib.output_compression','0');
does not do any thing... :(
I installed at e drive and used:
exec("e:\wkhtmltopdf\wkhtmltopdf.exe http://www.google.com/ test.pdf");
Actually I creates PDF correctly but does not send output to browser..
any idea what I had missed ...?
I'm guessing but the issue might be file locations. Does file_get_contents actually find the file?
I'm not very sure where the pdf file gets generated during the exec, try to use full paths for both the output pdf location and the file_get_contents location, they might not be correct by default. Maby even check somehow that the files exist and what folder are they both using (I cant remember how to do this in PHP :))

Categories