Linking to a forced download script in a pdf - php

I am generating dynamic PDF reports in PHP and having some issues with links to the web.
My links are to a PHP script that forces the download of a file attachment. This script works perfectly in all browser when accessed via the browser. It also works from the PDF in all browser except Internet Explorer.
Instead of IE seeing the file as a PDF, PNG, or whatever the file is, the download prompt says the document type is: "HTML Plugin Document"
If the user clicks "Open" or "Save" IE says it cannot download the file and gives the filename as "index2.php". That is the beginning of the URI of address.
The correct filesize is given so I know it is getting the file. Maybe it is a header issue?
Here is the header I'm creating on the download script:
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT;");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT;");
header("Pragma: no-cache;"); // HTTP/1.0
header('Content-Type: '.$file->file_mime_type.';');
header("Content-Description: File Transfer");
header("Cache-Control: public");
header('Content-Disposition: attachment; filename="'.$file->file_name.'";');
header('Content-Length: '.$file->file_size.';');
header('Content-transfer-encoding: binary');
Any input would be greatly appreciated.

Here's what I use and that is proven to work:
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="'.$file->file_name.'"');
readfile($filename);

have you tried something like this?
header('Content-Disposition: attachment; filename="'.$file->filename.'"');

It might be worth mentioning that there is also a known issue on several versions of IE when transferring files over SSL which requires the following work around:
header("Cache-Control: maxage=1");
header("Pragma: public");
There is more information regarding this bug here: http://support.microsoft.com/kb/812935

Related

PHP Download Files from another Server using File URL

Right now, if I paste the same URL in Chrome's URL Bar, it downloads the file accurately.
But when I add the same URL inside ANCHOR TAG it just reloads the same page. I have tried both _self and _blank values for TARGET Attribute.
Here are the Anchor tags I used:
Download File
Download File
Download File
NOTE: These anchors are working fine in Microsoft Edge
Also, I tried the different PHP scripts for this and one of them downloads the file but the file is empty. Changing URLs for different types of files including pdf, jpg, png and all of them has filesize of zero.
$file_name = basename($vpf_url);
$fn = file_put_contents($file_name,file_get_contents($vpf_url));
header("Expires: 0");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Content-type: application/octet-stream");
header('Content-length: '.filesize($file_name));
header('Content-disposition: attachment; filename="'.basename($file_name).'"');
readfile($file_name);
I don't know if its a cross-domain issue or just some error that's downloading an empty file.

Download File Types Confusion - application/octet-stream

I'm using this code:
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // some day in the past
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=".$original);
header("Content-Transfer-Encoding: binary");
readfile('/tmp/'.$original);
to output files from my server (EC2) which have been grabbed off S3. This works fine for images and .txt files but PDF and .doc seem to be damaged in some way. They won't open, or if they do the content is garbled.
I'm thinking it must be to do with the content type application/octet-stream? However my knowledge is limited in this area - I've done some reading and trial and error, but I'm no further forward with it.
In S3 the content types are set for all files as application/octet-stream. I'm not sure if this is right either (it's not something I've set when uploading the files)
Any ideas appreciated.
Thanks
for .doc files you should set application/msword, for .pdf files you should set application/pdf
<?php
header('Content-type: application/pdf'); // set content type
header('Content-Disposition: attachment; filename="downloaded.pdf"'); // force download
readfile('original.pdf'); // read the content to server
?>
Source: http://php.net/manual/en/function.header.php

php force download on mobile browsers

I'm trying to force download a image file (jpg for example) using php. So I have a script here force.php and here would be the code:
header("Pragma: public"); // required
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false); // required for certain browsers
header('Content-Description: File Transfer');
header("Content-Type: image/jpeg");
header('Content-Length: ' . filesize($file));
header('Content-Disposition: attachment; filename=test.jpg');
readfile($file);
Now the problem is for some browsers (mobile phone browsers especially), it'll work properly and prompt test.jpg for the user to save. However on some browser, it'll prompt force.php as download. Any solution?
Thank you!
Content disposition header highly depends on how a particular browser implements it. Sometimes there are encoding issues (I do not see in your case).
The document at Test Cases for HTTP Content-Disposition shows behavior for various browsers.
To be safe with mobile browsers you should consider having the http request's last part be equal to the actual filename of the attachment, for example http://some.url/download/test.jpg .
Use apache mod_rewrite or similar to route such requests to your download script.

Cannot render Excel download using SSRS SDK for PHP

I cannot render an excel file for download correctly using SSRS SDK for PHP. I can for a CSV, and I can render one for PDF inline. The contents of produced file is garbage when viewed in EXCEL. Here is my code:
$renderAs = new RenderAsEXCEL();
$result = $ssrs_report->Render2($renderAs,
PageCountModeEnum::$Estimate,
$Extension,
$MimeType,
$Encoding,
$Warnings,
$StreamIds);
header("Content-Type: application/vnd.ms-excel");
header("Content-Disposition: attachment; filename=\"".$reportName.".xls\";");
I've tried many different MIME Content-Type values.
A bit late but I had the same problem and it took me a while to figure it out:
There are more files that contain spaces before or after the php-tags than just the RenderAsEXCEL.php file.
Since the main php file of the SSRS library includes almost all files you need to remove all spaces before and after the php-tags from all files.
After you've done that use this code to download the Excel file.
$renderAsExcel = new RenderAsEXCEL();
$result = $ssrsServer->Render2($renderAsExcel,
PageCountModeEnum::$Estimate,
$Extension,
$MimeType,
$Encoding,
$Warnings,
$StreamIds
);
header("Content-Type: application/force-download");
header("Content-Disposition: attachment; filename=\"report.xls\"");
header("Content-length: ".(string)(strlen($result)));
header("Expires: ".gmdate("D, d M Y H:i:s", mktime(date("H")+2, date("i"),date("s"),date("m"), date("d"),date("Y")))." GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Cache-Control: no-cache, must-revalidate");
header("Pragma: no-cache");
echo $result;
i'm probably way to late but for anyone else that stumbles on this problem:
the problem is actually that there is a space in front of the first
<?php
in RenderAsEXCEL.php and there are a few lines after the last
?>
in RenderAsPDF.php
remove these white spaces and you will not have to use an ugly ob_clean() workaround
I've not used that library, but i have had great results from this one: http://www.bettina-attack.de/jonny/view.php/projects/php_writeexcel/
Built it into many apps without having to think very much about it.

How do I get csv file to download on IE? Works on firefox

I'm struggling with an odd error. I have a simple web app that grabs stuff from a DB then outputs it as a downloadable csv file. It works on firefox and chrome, but IE fails to recognize it as a csv file (thinking it is a html fle) and when I click save I get the error, "Unable to download {name of file} from {name of site}. Unable to open this internet site. ..."
Code:
session_start();
//some logic goes here...
//generate csv header
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=exportevent.csv");
header("Pragma: no-cache");
header("Expires: 0");
echo "Event: " . $event_title . "\n";
//print the column names
echo "Last Name, First Name, Company \n";
while($row = mysql_fetch_assoc($result))
{
echo $row['atlname'] . ',' . $row['atfname'] . ',' . $row['atcompany'] . "\n";
}
I've played around with the content-type a whole bunch, but that had no effect.
Update: I've tried text/csv, application/vnd.ms-excel (and variations of this), text/plain, and some others that I now forget with no luck.
This is IE8 btw.
Update 2: The connection is over SSL.
Don't we love IE? :)
Try using those headers:
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false);
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"exportevent.csv\";" );
header("Content-Transfer-Encoding: binary");
I think that the octet-stream content type forces IE to download the file.
We recently ran into this problem ourselves. See this MSKB article
These are the headers we ended up having to use to get it to work over SSL.
header("Expires: Sat, 01 Jan 2000 00:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public");
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"$file_name\";");
header("Content-length: " . strlen($csv_string));
I've had success with the following:
header("Content-type: application/vnd.ms-excel");
header("Content-disposition: attachment; filename=File.csv");
Setting the type to application/vnd.ms-excel seemed to do the trick in my case. This is all in a file that is opened by submitting a form using
target="_blank"
The only extra code I had to add for IE to work with SSL was: header("Pragma: public");
So my headers look like this now:
header("Pragma: public");
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=some_filename.csv");
We have just had the same issue and after adding many headers and getting a working link I then removed them one by one and found the key one for us was
"Cache-Control: public"
so in the end we just had
header("Cache-Control: public");
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=some_filename.csv");
which worked fine.
Try setting your content type to text/csv instead of application/octet-stream.
Since application/octet-stream is a generic binary mime type (and doesn't match the '.csv' extension), Internet explorer might be ignoring it and computing the mime type based on the file extension.
After using Javascript it will solve your problem.
Use this for IE,
var IEwindow = window.open();
IEwindow.document.write('sep=,\r\n' + CSV);
IEwindow.document.close();
IEwindow.document.execCommand('SaveAs', true, fileName + ".csv");
IEwindow.close();
For more information i have written tutorial on that,
see - Download JSON data in CSV format Cross Browser Support
Hope this will be helpful for you.
The solution for me was:
header_remove();
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename=brokerlist.csv');
echo $content;
Did you try the Content-type: text/csv ?
Some time ago I've got a problem with IE6 opening pdf files, and crashing when AdobeReader 6.0 was installed and tried to open file in browser window. Than I found somewhere this header:
header('Content-Type: application/force-download');
And it solved the problem, every pdf file was downloaded and opened in Adobe instead of IE.
This simply doesn't make sense. I tried the accepted answer, all the other answers in here, and it didn't work for me. I tried their permutations, and somehow I managed to make it work in IE like so:
header("Pragma: public");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public");
header("Content-Type: application/vnd.ms-exce");
header("Content-Disposition: attachment; filename=coupons.csv" );
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . strlen($csv));
echo $csv;
die();
One thing I did is to empty the cache every freaking time I test the code. And it still doesn't make sense. Just in case someone might need this desperately ;)
If you are trying to accomplish this task (getting a CSV file to download in IE8) using Salesforce.com (in which case your front-end is Visualforce and you can't set all of the headers, only some of them), here's what you need:
<apex:page cache="true"
contentType="application/octet-stream#myAwesomeFileName.csv"
showHeader="false" sidebar="false" standardStylesheets="false">
<apex:outputText value="{!csvContent}" escape="false"/>
</apex:page>
The key pieces here are cache=true, which, in conjunction with the default expires=0 attribute, achieves the following headers:
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public");
And then the contentType of application/octet-stream --- doing text/csv fails for IE8.

Categories